blob: 8b0ae38b903a3f9958fad39f5089cfaae9343fef [file] [log] [blame]
/*
* 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.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.ArrayList;
import org.apache.harmony.awt.gl.color.LUTColorConverter;
/**
* This class is super class for others types of Surfaces.
* Surface is storing data and data format description, that are using
* in blitting operations
*/
public abstract class Surface implements Transparency{
// Color Space Types
public static final int sRGB_CS = 1;
public static final int Linear_RGB_CS = 2;
public static final int Linear_Gray_CS = 3;
public static final int Custom_CS = 0;
// Color Model Types
public static final int DCM = 1; // Direct Color Model
public static final int ICM = 2; // Index Color Model
public static final int CCM = 3; // Component Color Model
// Sample Model Types
public static final int SPPSM = 1; // Single Pixel Packed Sample Model
public static final int MPPSM = 2; // Multi Pixel Packed Sample Model
public static final int CSM = 3; // Component Sample Model
public static final int PISM = 4; // Pixel Interleaved Sample Model
public static final int BSM = 5; // Banded Sample Model
// Surface Types
private static final int ALPHA_MASK = 0xff000000;
private static final int RED_MASK = 0x00ff0000;
private static final int GREEN_MASK = 0x0000ff00;
private static final int BLUE_MASK = 0x000000ff;
private static final int RED_BGR_MASK = 0x000000ff;
private static final int GREEN_BGR_MASK = 0x0000ff00;
private static final int BLUE_BGR_MASK = 0x00ff0000;
private static final int RED_565_MASK = 0xf800;
private static final int GREEN_565_MASK = 0x07e0;
private static final int BLUE_565_MASK = 0x001f;
private static final int RED_555_MASK = 0x7c00;
private static final int GREEN_555_MASK = 0x03e0;
private static final int BLUE_555_MASK = 0x001f;
static{
//???AWT
/*
System.loadLibrary("gl"); //$NON-NLS-1$
initIDs();
*/
}
protected long surfaceDataPtr; // Pointer for Native Surface data
protected int transparency = OPAQUE;
protected int width;
protected int height;
/**
* This list contains caches with the data of this surface that are valid at the moment.
* Surface should clear this list when its data is updated.
* Caches may check if they are still valid using isCacheValid method.
* When cache gets data from the surface, it should call addValidCache method of the surface.
*/
private final ArrayList<Object> validCaches = new ArrayList<Object>();
public abstract ColorModel getColorModel();
public abstract WritableRaster getRaster();
public abstract int getSurfaceType(); // Syrface type. It is equal
// BufferedImge type
/**
* Lock Native Surface data
*/
public abstract long lock();
/**
* Unlock Native Surface data
*/
public abstract void unlock();
/**
* Dispose Native Surface data
*/
public abstract void dispose();
public abstract Surface getImageSurface();
public long getSurfaceDataPtr(){
return surfaceDataPtr;
}
public final boolean isCaheValid(Object cache) {
return validCaches.contains(cache);
}
public final void addValidCache(Object cache) {
validCaches.add(cache);
}
protected final void clearValidCaches() {
validCaches.clear();
}
/**
* Returns could or coldn't the Surface be blit by Native blitter
* @return - true if the Surface could be blit by Native blitter,
* false in other case
*/
public boolean isNativeDrawable(){
return true;
}
public int getTransparency() {
return transparency;
}
public int getWidth(){
return width;
}
public int getHeight(){
return height;
}
/**
* If Surface has Raster, this method returns data array of Raster's DataBuffer
* @return - data array
*/
public Object getData(){
return null;
}
public boolean invalidated(){
return true;
}
public void validate(){}
public void invalidate(){}
/**
* Computation type of BufferedImage or Surface
* @param cm - ColorModel
* @param raster - WritableRaste
* @return - type of BufferedImage
*/
public static int getType(ColorModel cm, WritableRaster raster){
int transferType = cm.getTransferType();
boolean hasAlpha = cm.hasAlpha();
ColorSpace cs = cm.getColorSpace();
int csType = cs.getType();
SampleModel sm = raster.getSampleModel();
if(csType == ColorSpace.TYPE_RGB){
if(cm instanceof DirectColorModel){
DirectColorModel dcm = (DirectColorModel) cm;
switch (transferType) {
case DataBuffer.TYPE_INT:
if (dcm.getRedMask() == RED_MASK &&
dcm.getGreenMask() == GREEN_MASK &&
dcm.getBlueMask() == BLUE_MASK) {
if (!hasAlpha) {
return BufferedImage.TYPE_INT_RGB;
}
if (dcm.getAlphaMask() == ALPHA_MASK) {
if (dcm.isAlphaPremultiplied()) {
return BufferedImage.TYPE_INT_ARGB_PRE;
}
return BufferedImage.TYPE_INT_ARGB;
}
return BufferedImage.TYPE_CUSTOM;
} else if (dcm.getRedMask() == RED_BGR_MASK &&
dcm.getGreenMask() == GREEN_BGR_MASK &&
dcm.getBlueMask() == BLUE_BGR_MASK) {
if (!hasAlpha) {
return BufferedImage.TYPE_INT_BGR;
}
} else {
return BufferedImage.TYPE_CUSTOM;
}
case DataBuffer.TYPE_USHORT:
if (dcm.getRedMask() == RED_555_MASK &&
dcm.getGreenMask() == GREEN_555_MASK &&
dcm.getBlueMask() == BLUE_555_MASK && !hasAlpha) {
return BufferedImage.TYPE_USHORT_555_RGB;
} else if (dcm.getRedMask() == RED_565_MASK &&
dcm.getGreenMask() == GREEN_565_MASK &&
dcm.getBlueMask() == BLUE_565_MASK) {
return BufferedImage.TYPE_USHORT_565_RGB;
}
default:
return BufferedImage.TYPE_CUSTOM;
}
}else if(cm instanceof IndexColorModel){
IndexColorModel icm = (IndexColorModel) cm;
int pixelBits = icm.getPixelSize();
if(transferType == DataBuffer.TYPE_BYTE){
if(sm instanceof MultiPixelPackedSampleModel && !hasAlpha &&
pixelBits < 5){
return BufferedImage.TYPE_BYTE_BINARY;
}else if(pixelBits == 8){
return BufferedImage.TYPE_BYTE_INDEXED;
}
}
return BufferedImage.TYPE_CUSTOM;
}else if(cm instanceof ComponentColorModel){
ComponentColorModel ccm = (ComponentColorModel) cm;
if(transferType == DataBuffer.TYPE_BYTE &&
sm instanceof ComponentSampleModel){
ComponentSampleModel csm =
(ComponentSampleModel) sm;
int[] offsets = csm.getBandOffsets();
int[] bits = ccm.getComponentSize();
boolean isCustom = false;
for (int i = 0; i < bits.length; i++) {
if (bits[i] != 8 ||
offsets[i] != offsets.length - 1 - i) {
isCustom = true;
break;
}
}
if (!isCustom) {
if (!ccm.hasAlpha()) {
return BufferedImage.TYPE_3BYTE_BGR;
} else if (ccm.isAlphaPremultiplied()) {
return BufferedImage.TYPE_4BYTE_ABGR_PRE;
} else {
return BufferedImage.TYPE_4BYTE_ABGR;
}
}
}
return BufferedImage.TYPE_CUSTOM;
}
return BufferedImage.TYPE_CUSTOM;
}else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
if(cm instanceof ComponentColorModel &&
cm.getNumComponents() == 1){
int bits[] = cm.getComponentSize();
if(transferType == DataBuffer.TYPE_BYTE &&
bits[0] == 8){
return BufferedImage.TYPE_BYTE_GRAY;
}else if(transferType == DataBuffer.TYPE_USHORT &&
bits[0] == 16){
return BufferedImage.TYPE_USHORT_GRAY;
}else{
return BufferedImage.TYPE_CUSTOM;
}
}
return BufferedImage.TYPE_CUSTOM;
}
return BufferedImage.TYPE_CUSTOM;
}
public static Surface getImageSurface(Image image){
return AwtImageBackdoorAccessor.getInstance().getImageSurface(image);
}
@Override
protected void finalize() throws Throwable{
dispose();
}
public static boolean isGrayPallete(IndexColorModel icm){
return AwtImageBackdoorAccessor.getInstance().isGrayPallete(icm);
}
/**
* Initialization of Native data
*
*/
//???AWT: private static native void initIDs();
}