summaryrefslogtreecommitdiffstats
path: root/awt/org/apache/harmony/awt/gl/ImageSurface.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/ImageSurface.java')
-rw-r--r--awt/org/apache/harmony/awt/gl/ImageSurface.java323
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;
+ }
+}