diff options
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/ImageSurface.java')
-rw-r--r-- | awt/org/apache/harmony/awt/gl/ImageSurface.java | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/awt/org/apache/harmony/awt/gl/ImageSurface.java b/awt/org/apache/harmony/awt/gl/ImageSurface.java new file mode 100644 index 0000000..6368dd8 --- /dev/null +++ b/awt/org/apache/harmony/awt/gl/ImageSurface.java @@ -0,0 +1,323 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Igor V. Stolyarov + * @version $Revision$ + * Created on 10.11.2005 + * + */ +package org.apache.harmony.awt.gl; + +import java.awt.color.ColorSpace; +import java.awt.image.BandedSampleModel; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DirectColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.PixelInterleavedSampleModel; +import java.awt.image.SampleModel; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.WritableRaster; + +import org.apache.harmony.awt.gl.color.LUTColorConverter; +import org.apache.harmony.awt.gl.image.DataBufferListener; +import org.apache.harmony.awt.internal.nls.Messages; + + +/** + * This class represent Surface for different types of Images (BufferedImage, + * OffscreenImage and so on) + */ +public class ImageSurface extends Surface implements DataBufferListener { + + boolean nativeDrawable = true; + int surfaceType; + int csType; + ColorModel cm; + WritableRaster raster; + Object data; + + boolean needToRefresh = true; + boolean dataTaken = false; + + private long cachedDataPtr; // Pointer for cached Image Data + private boolean alphaPre; // Cached Image Data alpha premultiplied + + public ImageSurface(ColorModel cm, WritableRaster raster){ + this(cm, raster, Surface.getType(cm, raster)); + } + + public ImageSurface(ColorModel cm, WritableRaster raster, int type){ + if (!cm.isCompatibleRaster(raster)) { + // awt.4D=The raster is incompatible with this ColorModel + throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$ + } + this.cm = cm; + this.raster = raster; + surfaceType = type; + + data = AwtImageBackdoorAccessor.getInstance(). + getData(raster.getDataBuffer()); + ColorSpace cs = cm.getColorSpace(); + transparency = cm.getTransparency(); + width = raster.getWidth(); + height = raster.getHeight(); + + // For the moment we can build natively only images which have + // sRGB, Linear_RGB, Linear_Gray Color Space and type different + // from BufferedImage.TYPE_CUSTOM + if(cs == LUTColorConverter.sRGB_CS){ + csType = sRGB_CS; + }else if(cs == LUTColorConverter.LINEAR_RGB_CS){ + csType = Linear_RGB_CS; + }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){ + csType = Linear_Gray_CS; + }else{ + csType = Custom_CS; + nativeDrawable = false; + } + + if(type == BufferedImage.TYPE_CUSTOM){ + nativeDrawable = false; + } + } + + @Override + public ColorModel getColorModel() { + return cm; + } + + @Override + public WritableRaster getRaster() { + return raster; + } + + @Override + public long getSurfaceDataPtr() { + if(surfaceDataPtr == 0L && nativeDrawable){ + createSufaceStructure(); + } + return surfaceDataPtr; + } + + @Override + public Object getData(){ + return data; + } + + @Override + public boolean isNativeDrawable(){ + return nativeDrawable; + } + + @Override + public int getSurfaceType() { + return surfaceType; + } + + /** + * Creates native Surface structure which used for native blitting + */ + private void createSufaceStructure(){ + int cmType = 0; + int numComponents = cm.getNumComponents(); + boolean hasAlpha = cm.hasAlpha(); + boolean isAlphaPre = cm.isAlphaPremultiplied(); + int transparency = cm.getTransparency(); + int bits[] = cm.getComponentSize(); + int pixelStride = cm.getPixelSize(); + int masks[] = null; + int colorMap[] = null; + int colorMapSize = 0; + int transpPixel = -1; + boolean isGrayPallete = false; + SampleModel sm = raster.getSampleModel(); + int smType = 0; + int dataType = sm.getDataType(); + int scanlineStride = 0; + int bankIndeces[] = null; + int bandOffsets[] = null; + int offset = raster.getDataBuffer().getOffset(); + + if(cm instanceof DirectColorModel){ + cmType = DCM; + DirectColorModel dcm = (DirectColorModel) cm; + masks = dcm.getMasks(); + smType = SPPSM; + SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm; + scanlineStride = sppsm.getScanlineStride(); + + }else if(cm instanceof IndexColorModel){ + cmType = ICM; + IndexColorModel icm = (IndexColorModel) cm; + colorMapSize = icm.getMapSize(); + colorMap = new int[colorMapSize]; + icm.getRGBs(colorMap); + transpPixel = icm.getTransparentPixel(); + isGrayPallete = Surface.isGrayPallete(icm); + + if(sm instanceof MultiPixelPackedSampleModel){ + smType = MPPSM; + MultiPixelPackedSampleModel mppsm = + (MultiPixelPackedSampleModel) sm; + scanlineStride = mppsm.getScanlineStride(); + }else if(sm instanceof ComponentSampleModel){ + smType = CSM; + ComponentSampleModel csm = + (ComponentSampleModel) sm; + scanlineStride = csm.getScanlineStride(); + }else{ + // awt.4D=The raster is incompatible with this ColorModel + throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$ + } + + }else if(cm instanceof ComponentColorModel){ + cmType = CCM; + if(sm instanceof ComponentSampleModel){ + ComponentSampleModel csm = (ComponentSampleModel) sm; + scanlineStride = csm.getScanlineStride(); + bankIndeces = csm.getBankIndices(); + bandOffsets = csm.getBandOffsets(); + if(sm instanceof PixelInterleavedSampleModel){ + smType = PISM; + }else if(sm instanceof BandedSampleModel){ + smType = BSM; + }else{ + smType = CSM; + } + }else{ + // awt.4D=The raster is incompatible with this ColorModel + throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$ + } + + }else{ + surfaceDataPtr = 0L; + return; + } + surfaceDataPtr = createSurfStruct(surfaceType, width, height, cmType, csType, smType, dataType, + numComponents, pixelStride, scanlineStride, bits, masks, colorMapSize, + colorMap, transpPixel, isGrayPallete, bankIndeces, bandOffsets, + offset, hasAlpha, isAlphaPre, transparency); + } + + @Override + public void dispose() { + if(surfaceDataPtr != 0L){ + dispose(surfaceDataPtr); + surfaceDataPtr = 0L; + } + } + + public long getCachedData(boolean alphaPre){ + if(nativeDrawable){ + if(cachedDataPtr == 0L || needToRefresh || this.alphaPre != alphaPre){ + cachedDataPtr = updateCache(getSurfaceDataPtr(), data, alphaPre); + this.alphaPre = alphaPre; + validate(); + } + } + return cachedDataPtr; + } + + private native long createSurfStruct(int surfaceType, int width, int height, + int cmType, int csType, int smType, int dataType, + int numComponents, int pixelStride, int scanlineStride, + int bits[], int masks[], int colorMapSize, int colorMap[], + int transpPixel, boolean isGrayPalette, int bankIndeces[], + int bandOffsets[], int offset, boolean hasAlpha, boolean isAlphaPre, + int transparency); + + private native void dispose(long structPtr); + + private native void setImageSize(long structPtr, int width, int height); + + private native long updateCache(long structPtr, Object data, boolean alphaPre); + + /** + * Supposes that new raster is compatible with an old one + * @param r + */ + public void setRaster(WritableRaster r) { + raster = r; + data = AwtImageBackdoorAccessor.getInstance().getData(r.getDataBuffer()); + if (surfaceDataPtr != 0) { + setImageSize(surfaceDataPtr, r.getWidth(), r.getHeight()); + } + this.width = r.getWidth(); + this.height = r.getHeight(); + } + + @Override + public long lock() { + // TODO + return 0; + } + + @Override + public void unlock() { + //TODO + } + + @Override + public Surface getImageSurface() { + return this; + } + + public void dataChanged() { + needToRefresh = true; + clearValidCaches(); + } + + public void dataTaken() { + dataTaken = true; + needToRefresh = true; + clearValidCaches(); + } + + public void dataReleased(){ + dataTaken = false; + needToRefresh = true; + clearValidCaches(); + } + + @Override + public void invalidate(){ + needToRefresh = true; + clearValidCaches(); + } + + @Override + public void validate(){ + if(!needToRefresh) { + return; + } + if(!dataTaken){ + needToRefresh = false; + AwtImageBackdoorAccessor ba = AwtImageBackdoorAccessor.getInstance(); + ba.validate(raster.getDataBuffer()); + } + + } + + @Override + public boolean invalidated(){ + return needToRefresh; + } +} |