/*
 * Copyright (c) 2011, 2012, 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.java2d;

import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
import java.nio.*;

import sun.awt.image.*;
import sun.java2d.loops.*;

public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements RasterListener
{
    private static native void initIDs();

    static {
        initIDs();
    }

    // the image associated with this surface
    BufferedImage bim;
    // the image associated with this custom surface
    BufferedImage bimBackup;
    // <rdar://problem/4177639> nio based images use ARGB_PRE
    static DirectColorModel dcmBackup = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, true, DataBuffer.TYPE_INT);

    Object lock;

    // cached rasters for easy access
    WritableRaster bufImgRaster;
    SunWritableRaster bufImgSunRaster;

    // these are extra image types we can handle
    private static final int TYPE_3BYTE_RGB = BufferedImage.TYPE_BYTE_INDEXED + 1;

    // these are for callbacks when pixes have been touched
    protected ByteBuffer fImageInfo;
    IntBuffer fImageInfoInt;
    private static final int kNeedToSyncFromJavaPixelsIndex = 0;
    private static final int kNativePixelsChangedIndex = 1;
    private static final int kImageStolenIndex = 2;
    private static final int kSizeOfParameters = kImageStolenIndex + 1;

    public static native SurfaceData getSurfaceData(BufferedImage bufImg);

    protected static native void setSurfaceData(BufferedImage bufImg, SurfaceData sData);

    public static SurfaceData createData(BufferedImage bufImg) {
        /*
         * if ((bufImg.getWidth() == 32) && (bufImg.getHeight() == 32)) { Thread.dumpStack(); }
         */
        // This could be called from multiple threads. We need to synchronized on the image so that
        // we can ensure that only one surface data is created per image. (<rdar://4564873>)
        // Note: Eventually, we should switch to using the same mechanism (CachingSurfaceManager) that Sun uses
        // <rdar://4563741>
        synchronized (bufImg) {
            SurfaceData sData = getSurfaceData(bufImg);
            if (sData != null) { return sData; }

            OSXOffScreenSurfaceData osData = OSXOffScreenSurfaceData.createNewSurface(bufImg);

            OSXOffScreenSurfaceData.setSurfaceData(bufImg, osData);
            osData.cacheRasters(bufImg);
//            osData.setRasterListener();

            return osData;
        }
    }

    public static SurfaceData createData(Raster ras, ColorModel cm) {
        throw new InternalError("SurfaceData not implemented for Raster/CM");
    }

    static OSXOffScreenSurfaceData createNewSurface(BufferedImage bufImg) {
        SurfaceData sData = null;

        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:
            case BufferedImage.TYPE_CUSTOM:
            default: {
                Raster raster = bufImg.getRaster();

                // we try to fit a custom image into one of the predefined BufferedImages (BufferedImage does that
                // first, we further refine it here)
                // we can do that because a pointer in C is a pointer (pixel pointer not dependent on DataBuffer type)
                SampleModel sm = bufImg.getSampleModel();
                SurfaceType sType = SurfaceType.Custom;
                int transferType = cm.getTransferType();
                int pixelSize = cm.getPixelSize();
                int numOfComponents = cm.getNumColorComponents();
                if ((numOfComponents == 3) && (cm instanceof ComponentColorModel) && (sm instanceof PixelInterleavedSampleModel)) {
                    int sizes[] = cm.getComponentSize();
                    boolean validsizes = (sizes[0] == 8) && (sizes[1] == 8) && (sizes[2] == 8);
                    int[] offs = ((ComponentSampleModel) sm).getBandOffsets();
                    int numBands = raster.getNumBands();
                    boolean bigendian = (offs[0] == numBands - 3) && (offs[1] == numBands - 2) && (offs[2] == numBands - 1);
                    boolean littleendian = (offs[0] == numBands - 1) && (offs[1] == numBands - 2) && (offs[2] == numBands - 3);

                    if ((pixelSize == 32) && (transferType == DataBuffer.TYPE_INT)) {
                        if (validsizes && bigendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_ARGB_PRE);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && bigendian && cm.hasAlpha() && sizes[3] == 8) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_ARGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_4BYTE_ABGR_PRE);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian && cm.hasAlpha() && sizes[3] == 8) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_4BYTE_ABGR);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && bigendian) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 32) && (transferType == DataBuffer.TYPE_BYTE)) {
                        if (validsizes && bigendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_ARGB_PRE);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                        if (validsizes && bigendian && cm.hasAlpha() && sizes[3] == 8) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_ARGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_4BYTE_ABGR_PRE);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian && cm.hasAlpha() && sizes[3] == 8) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_4BYTE_ABGR);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_BGR);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && bigendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 24) && (transferType == DataBuffer.TYPE_INT)) {
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian) {
                            try {
                                sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_BGR);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 24) && (transferType == DataBuffer.TYPE_BYTE)) {
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 0, TYPE_3BYTE_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        } else if (validsizes && littleendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 0, BufferedImage.TYPE_3BYTE_BGR);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 16) && (transferType == DataBuffer.TYPE_USHORT)) {
                        validsizes = (sizes[0] == 5) && (sizes[1] == 6) && (sizes[2] == 5);
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataSC(bufImg, sType, null, BufferedImage.TYPE_USHORT_565_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 16) && (transferType == DataBuffer.TYPE_BYTE)) {
                        validsizes = (sizes[0] == 5) && (sizes[1] == 6) && (sizes[2] == 5);
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 1, BufferedImage.TYPE_USHORT_565_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 15) && (transferType == DataBuffer.TYPE_USHORT)) {
                        validsizes = (sizes[0] == 5) && (sizes[1] == 5) && (sizes[2] == 5);
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataSC(bufImg, sType, null, BufferedImage.TYPE_USHORT_555_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    } else if ((pixelSize == 15) && (transferType == DataBuffer.TYPE_BYTE)) {
                        validsizes = (sizes[0] == 5) && (sizes[1] == 5) && (sizes[2] == 5);
                        if (validsizes && bigendian) {
                            try {
                                sData = createDataBC(bufImg, sType, 1, BufferedImage.TYPE_USHORT_555_RGB);
                            } catch (ClassCastException e) {
                                sData = null;
                            }
                        }
                    }
                }
            }
                break;
        }

        // we failed to match
        if (sData == null) {
            sData = new OSXOffScreenSurfaceData(bufImg, SurfaceType.Custom);
            OSXOffScreenSurfaceData offsd = (OSXOffScreenSurfaceData) sData;

            // 2004_03_26 cmc: We used to use createCompatibleImage here. Now that createCompatibleImage returns
            // an INT_ARGB_PRE instead of an NIO-based image, we need to explicitly create an NIO-based image.
            IntegerNIORaster backupRaster = (IntegerNIORaster) IntegerNIORaster.createNIORaster(bufImg.getWidth(), bufImg.getHeight(), dcmBackup.getMasks(), null);
            offsd.bimBackup = new BufferedImage(dcmBackup, backupRaster, dcmBackup.isAlphaPremultiplied(), null);

            // the trick that makes it work - assign the raster from backup to the surface data of the original image
            offsd.initCustomRaster(backupRaster.getBuffer(),
                                    backupRaster.getWidth(),
                                    backupRaster.getHeight(),
                                    offsd.fGraphicsStates,
                                    offsd.fGraphicsStatesObject,
                                    offsd.fImageInfo);

            //offsd.checkIfLazyPixelConversionDisabled();
            offsd.fImageInfoInt.put(kImageStolenIndex, 1);
        }

        return (OSXOffScreenSurfaceData) sData;
    }

    private static SurfaceData createDataIC(BufferedImage bImg, SurfaceType sType, int iType) {
        OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);

        IntegerComponentRaster icRaster = (IntegerComponentRaster) bImg.getRaster();
        offsd.initRaster(icRaster.getDataStorage(),
                            icRaster.getDataOffset(0) * 4,
                            icRaster.getWidth(),
                            icRaster.getHeight(),
                            icRaster.getPixelStride() * 4,
                            icRaster.getScanlineStride() * 4,
                            null,
                            iType,
                            offsd.fGraphicsStates,
                            offsd.fGraphicsStatesObject,
                            offsd.fImageInfo);

       // offsd.checkIfLazyPixelConversionDisabled();
        offsd.fImageInfoInt.put(kImageStolenIndex, 1);
        return offsd;
    }

    public static SurfaceData createDataIC(BufferedImage bImg, SurfaceType sType) {
        return createDataIC(bImg, sType, bImg.getType());
    }

    private static SurfaceData createDataSC(BufferedImage bImg, SurfaceType sType, IndexColorModel icm, int iType) {
        OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);

        ShortComponentRaster scRaster = (ShortComponentRaster) bImg.getRaster();
        offsd.initRaster(scRaster.getDataStorage(),
                            scRaster.getDataOffset(0) * 2,
                            scRaster.getWidth(),
                            scRaster.getHeight(),
                            scRaster.getPixelStride() * 2,
                            scRaster.getScanlineStride() * 2,
                            icm,
                            iType,
                            offsd.fGraphicsStates,
                            offsd.fGraphicsStatesObject,
                            offsd.fImageInfo);

        //offsd.checkIfLazyPixelConversionDisabled();
        offsd.fImageInfoInt.put(kImageStolenIndex, 1);
        return offsd;
    }

    public static SurfaceData createDataSC(BufferedImage bImg, SurfaceType sType, IndexColorModel icm) {
        return createDataSC(bImg, sType, icm, bImg.getType());
    }

    private static SurfaceData createDataBC(BufferedImage bImg, SurfaceType sType, int primaryBank, int iType) {
        OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);

        ByteComponentRaster bcRaster = (ByteComponentRaster) bImg.getRaster();
        ColorModel cm = bImg.getColorModel();
        IndexColorModel icm = ((cm instanceof IndexColorModel) ? (IndexColorModel) cm : null);
        offsd.initRaster(bcRaster.getDataStorage(),
                            bcRaster.getDataOffset(primaryBank),
                            bcRaster.getWidth(),
                            bcRaster.getHeight(),
                            bcRaster.getPixelStride(),
                            bcRaster.getScanlineStride(),
                            icm,
                            iType,
                            offsd.fGraphicsStates,
                            offsd.fGraphicsStatesObject,
                            offsd.fImageInfo);

        offsd.fImageInfoInt.put(kImageStolenIndex, 1);

        return offsd;
    }

    public static SurfaceData createDataBC(BufferedImage bImg, SurfaceType sType, int primaryBank) {
        return createDataBC(bImg, sType, primaryBank, bImg.getType());
    }

    private static SurfaceData createDataBP(BufferedImage bImg, SurfaceType sType, int iType) {
        OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);

        BytePackedRaster bpRaster = (BytePackedRaster) bImg.getRaster();
        ColorModel cm = bImg.getColorModel();
        IndexColorModel icm = ((cm instanceof IndexColorModel) ? (IndexColorModel) cm : null);
        offsd.initRaster(bpRaster.getDataStorage(),
                            bpRaster.getDataBitOffset(), // in bits, NOT bytes! (needs special attention in native
                                                         // code!)
                bpRaster.getWidth(),
                            bpRaster.getHeight(),
                            bpRaster.getPixelBitStride(),
                            bpRaster.getScanlineStride() * 8,
                            icm,
                            iType,
                            offsd.fGraphicsStates,
                            offsd.fGraphicsStatesObject,
                            offsd.fImageInfo);

        //offsd.checkIfLazyPixelConversionDisabled();
        offsd.fImageInfoInt.put(kImageStolenIndex, 1);
        return offsd;
    }

    protected native void initRaster(Object theArray, int offset, int width, int height, int pixStr, int scanStr, IndexColorModel icm, int type, ByteBuffer graphicsStates, Object graphicsStatesObjects, ByteBuffer imageInfo);

    protected native void initCustomRaster(IntBuffer buffer, int width, int height, ByteBuffer graphicsStates, Object graphicsStatesObjects, ByteBuffer imageInfo);

    public Object getLockObject() {
        return this.lock;
    }

    // Makes the constructor package private instead of public.
    OSXOffScreenSurfaceData(BufferedImage bufImg, SurfaceType sType) {
        super(sType, bufImg.getColorModel());
        setBounds(0, 0, bufImg.getWidth(), bufImg.getHeight());

        this.bim = bufImg;

        this.fImageInfo = ByteBuffer.allocateDirect(4 * kSizeOfParameters);
        this.fImageInfo.order(ByteOrder.nativeOrder());
        this.fImageInfoInt = this.fImageInfo.asIntBuffer();

        this.fImageInfoInt.put(kNeedToSyncFromJavaPixelsIndex, 1); // need to sync from Java the very first time
        this.fImageInfoInt.put(kNativePixelsChangedIndex, 0);
        this.fImageInfoInt.put(kImageStolenIndex, 0);

        this.lock = new Object();
    }

    /**
     * Performs a copyArea within this surface.
     */
    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
        // <rdar://problem/4488745> For the Sun2D renderer we should rely on the implementation of the super class.
        // BufImageSurfaceData.java doesn't have an implementation of copyArea() and relies on the super class.

        int offsetX = 0;
        int offsetY = 0;
        if (sg2d.transformState == SunGraphics2D.TRANSFORM_ANY_TRANSLATE ||
                    sg2d.transformState == SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
            offsetX = (int) sg2d.transform.getTranslateX();
            offsetY = (int) sg2d.transform.getTranslateY();
        } else if (sg2d.transformState != SunGraphics2D.TRANSFORM_ISIDENT) { return false; }

        // reset the clip (this is how it works on windows)
        // we actually can handle a case with any clips but windows ignores the light clip
        Shape clip = sg2d.getClip();
        sg2d.setClip(getBounds());

        // clip copyArea
        Rectangle clippedCopyAreaRect = clipCopyArea(sg2d, x, y, w, h, dx, dy);
        if (clippedCopyAreaRect == null) {
            // clipped out
            return true;
        }

        // the rectangle returned from clipCopyArea() is in the coordinate space of the surface (image)
        // we need to substract the offsetX and offsetY to move it to the coordinate space of the graphics2d.
        // sg2d.drawImage expects the destination rect to be in the coord space of the graphics2d. <rdar://3746194>
        // (vm)
        x = clippedCopyAreaRect.x - offsetX;
        y = clippedCopyAreaRect.y - offsetY;
        w = clippedCopyAreaRect.width;
        h = clippedCopyAreaRect.height;

        // copy (dst coordinates are in the coord space of the graphics2d, and src coordinates are
        // in the coordinate space of the image)
        sg2d.drawImage(this.bim, x + dx, y + dy, x + dx + w, y + dy + h, x + offsetX, y + offsetY, x + w + offsetX, y + h + offsetY, null);

        // restore the clip
        sg2d.setClip(clip);

        return true;
    }

    /**
     * Performs a copyarea from this surface to a buffered image. If null is passed in for the image a new image will be
     * created.
     *
     * Only used by compositor code (private API)
     */
    public BufferedImage copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, BufferedImage dstImage) {
        // create the destination image if needed
        if (dstImage == null) {
            dstImage = getDeviceConfiguration().createCompatibleImage(w, h);
        }

        // copy
        Graphics g = dstImage.createGraphics();
        g.drawImage(this.bim, 0, 0, w, h, x, y, x + w, y + h, null);
        g.dispose();

        return dstImage;
    }

    public boolean xorSurfacePixels(SunGraphics2D sg2d, BufferedImage srcPixels, int x, int y, int w, int h, int colorXOR) {

        int type = this.bim.getType();

        if ((type == BufferedImage.TYPE_INT_ARGB_PRE) || (type == BufferedImage.TYPE_INT_ARGB) || (type == BufferedImage.TYPE_INT_RGB)) { return xorSurfacePixels(createData(srcPixels), colorXOR, x, y, w, h); }

        return false;
    }

    native boolean xorSurfacePixels(SurfaceData src, int colorXOR, int x, int y, int w, int h);

    public void clearRect(BufferedImage bim, int w, int h) {
        OSXOffScreenSurfaceData offsd = (OSXOffScreenSurfaceData) (OSXOffScreenSurfaceData.createData(bim));
        // offsd.clear();
        if (offsd.clearSurfacePixels(w, h) == false) {
            Graphics2D g = bim.createGraphics();
            g.setComposite(AlphaComposite.Clear);
            g.fillRect(0, 0, w, h);
            g.dispose();
        }
    }

    native boolean clearSurfacePixels(int w, int h);

    // 04/06/04 cmc: radr://3612381 Graphics.drawImage ignores bgcolor parameter.
    // getCopyWithBgColor returns a new version of an image, drawn with a background
    // color. Called by blitImage in OSXSurfaceData.java.
    BufferedImage copyWithBgColor_cache = null;

    public SurfaceData getCopyWithBgColor(Color bgColor) {
        int bimW = this.bim.getWidth();
        int bimH = this.bim.getHeight();

        if ((this.copyWithBgColor_cache == null)
                || (this.copyWithBgColor_cache.getWidth() < bimW) || (this.copyWithBgColor_cache.getHeight() < bimH)) {
            GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
            this.copyWithBgColor_cache = gc.createCompatibleImage(bimW, bimH);
        }

        Graphics g2 = this.copyWithBgColor_cache.createGraphics();
        g2.setColor(bgColor);
        g2.fillRect(0, 0, bimW, bimH);
        g2.drawImage(this.bim, 0, 0, bimW, bimH, null);
        g2.dispose();

        return getSurfaceData(this.copyWithBgColor_cache);
    }

    /**
     * Invoked before the raster's contents are to be read (via one of the modifier methods in Raster such as
     * getPixel())
     */
    public void rasterRead() {
        if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
            syncToJavaPixels();
        }
    }

    /**
     * Invoked before the raster's contents are to be written to (via one of the modifier methods in Raster such as
     * setPixel())
     */
    public void rasterWrite() {
        if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
            syncToJavaPixels();
        }

        fImageInfoInt.put(kNeedToSyncFromJavaPixelsIndex, 1); // the pixels will change
    }

//    /**
//     * Invoked when the raster's contents will be taken (via the Raster.getDataBuffer() method)
//     */
//    public void rasterStolen() {
//        fImageInfoInt.put(kImageStolenIndex, 1); // this means we must convert between Java and native pixels every
//                                                 // single primitive! (very expensive)
//        if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
//            syncToJavaPixels();
//        }
//
//        // we know the pixels have been stolen, no need to listen for changes any more
////        if (this.bufImgSunRaster != null) {
////            this.bufImgSunRaster.setRasterListener(null);
////        }
//    }

    private native void syncToJavaPixels();

    // we need to refer to rasters often, so cache them
    void cacheRasters(BufferedImage bim) {
        this.bufImgRaster = bim.getRaster();
        if (this.bufImgRaster instanceof SunWritableRaster) {
            this.bufImgSunRaster = (SunWritableRaster) this.bufImgRaster;
        }
    }

//    void setRasterListener() {
//        if (this.bufImgSunRaster != null) {
//            this.bufImgSunRaster.setRasterListener(this);
//
//            Raster parentRaster = this.bufImgSunRaster.getParent();
//            if (parentRaster != null) {
//                if (parentRaster instanceof SunWritableRaster) {
//                    // mark subimages stolen to turn off lazy pixel conversion (gznote: can we do better here?)
//                    ((SunWritableRaster) parentRaster).notifyStolen();
//                }
//                rasterStolen();
//            }
//        } else {
//            // it's a custom image (non-natively supported) and we can not set a raster listener
//            // so mark the image as stolen - this will turn off LazyPixelConversion optimization (slow, but correct)
//            rasterStolen();
//        }
//    }
}
