001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Igor V. Stolyarov
019: * @version $Revision$
020: * Created on 10.11.2005
021: *
022: */package org.apache.harmony.awt.gl;
023:
024: import java.awt.Image;
025: import java.awt.Rectangle;
026: import java.awt.Transparency;
027: import java.awt.color.ColorSpace;
028: import java.awt.image.BufferedImage;
029: import java.awt.image.ColorModel;
030: import java.awt.image.ComponentColorModel;
031: import java.awt.image.ComponentSampleModel;
032: import java.awt.image.DataBuffer;
033: import java.awt.image.DirectColorModel;
034: import java.awt.image.IndexColorModel;
035: import java.awt.image.MultiPixelPackedSampleModel;
036: import java.awt.image.SampleModel;
037: import java.awt.image.WritableRaster;
038: import java.util.ArrayList;
039:
040: import org.apache.harmony.awt.gl.color.LUTColorConverter;
041:
042: /**
043: * This class is super class for others types of Surfaces.
044: * Surface is storing data and data format description, that are using
045: * in blitting operations
046: */
047: public abstract class Surface implements Transparency {
048:
049: // Color Space Types
050: public static final int sRGB_CS = 1;
051: public static final int Linear_RGB_CS = 2;
052: public static final int Linear_Gray_CS = 3;
053: public static final int Custom_CS = 0;
054:
055: // Color Model Types
056: public static final int DCM = 1; // Direct Color Model
057: public static final int ICM = 2; // Index Color Model
058: public static final int CCM = 3; // Component Color Model
059:
060: // Sample Model Types
061: public static final int SPPSM = 1; // Single Pixel Packed Sample Model
062: public static final int MPPSM = 2; // Multi Pixel Packed Sample Model
063: public static final int CSM = 3; // Component Sample Model
064: public static final int PISM = 4; // Pixel Interleaved Sample Model
065: public static final int BSM = 5; // Banded Sample Model
066:
067: // Surface Types
068: private static final int ALPHA_MASK = 0xff000000;
069: private static final int RED_MASK = 0x00ff0000;
070: private static final int GREEN_MASK = 0x0000ff00;
071: private static final int BLUE_MASK = 0x000000ff;
072: private static final int RED_BGR_MASK = 0x000000ff;
073: private static final int GREEN_BGR_MASK = 0x0000ff00;
074: private static final int BLUE_BGR_MASK = 0x00ff0000;
075: private static final int RED_565_MASK = 0xf800;
076: private static final int GREEN_565_MASK = 0x07e0;
077: private static final int BLUE_565_MASK = 0x001f;
078: private static final int RED_555_MASK = 0x7c00;
079: private static final int GREEN_555_MASK = 0x03e0;
080: private static final int BLUE_555_MASK = 0x001f;
081:
082: static {
083: System.loadLibrary("gl"); //$NON-NLS-1$
084: initIDs();
085: }
086:
087: protected long surfaceDataPtr; // Pointer for Native Surface data
088: protected int transparency = OPAQUE;
089: protected int width;
090: protected int height;
091:
092: protected MultiRectArea dirtyRegions;
093:
094: /**
095: * This list contains caches with the data of this surface that are valid at the moment.
096: * Surface should clear this list when its data is updated.
097: * Caches may check if they are still valid using isCacheValid method.
098: * When cache gets data from the surface, it should call addValidCache method of the surface.
099: */
100: private final ArrayList<Object> validCaches = new ArrayList<Object>();
101:
102: public abstract ColorModel getColorModel();
103:
104: public abstract WritableRaster getRaster();
105:
106: public abstract int getSurfaceType(); // Syrface type. It is equal
107:
108: // BufferedImge type
109: /**
110: * Lock Native Surface data
111: */
112: public abstract long lock();
113:
114: /**
115: * Unlock Native Surface data
116: */
117: public abstract void unlock();
118:
119: /**
120: * Dispose Native Surface data
121: */
122: public abstract void dispose();
123:
124: public abstract Surface getImageSurface();
125:
126: public long getSurfaceDataPtr() {
127: return surfaceDataPtr;
128: }
129:
130: public final boolean isCaheValid(Object cache) {
131: return validCaches.contains(cache);
132: }
133:
134: public final void addValidCache(Object cache) {
135: validCaches.add(cache);
136: }
137:
138: protected final void clearValidCaches() {
139: validCaches.clear();
140: }
141:
142: /**
143: * Returns could or coldn't the Surface be blit by Native blitter
144: * @return - true if the Surface could be blit by Native blitter,
145: * false in other case
146: */
147: public boolean isNativeDrawable() {
148: return true;
149: }
150:
151: public int getTransparency() {
152: return transparency;
153: }
154:
155: public int getWidth() {
156: return width;
157: }
158:
159: public int getHeight() {
160: return height;
161: }
162:
163: /**
164: * If Surface has Raster, this method returns data array of Raster's DataBuffer
165: * @return - data array
166: */
167: public Object getData() {
168: return null;
169: }
170:
171: public boolean invalidated() {
172: return true;
173: }
174:
175: public void validate() {
176: }
177:
178: public void invalidate() {
179: }
180:
181: public void addDirtyRegion(Rectangle r) {
182: if (dirtyRegions == null) {
183: dirtyRegions = new MultiRectArea(r);
184: } else {
185: Rectangle rects[] = dirtyRegions.getRectangles();
186: if (rects.length == 1) {
187: if (rects[0].contains(r))
188: return;
189: }
190: dirtyRegions.add(r);
191: }
192: invalidate();
193: }
194:
195: public void releaseDurtyRegions() {
196: dirtyRegions = null;
197: }
198:
199: public int[] getDirtyRegions() {
200: if (dirtyRegions != null)
201: return dirtyRegions.rect;
202: else
203: return null;
204: }
205:
206: /**
207: * Computation type of BufferedImage or Surface
208: * @param cm - ColorModel
209: * @param raster - WritableRaste
210: * @return - type of BufferedImage
211: */
212: public static int getType(ColorModel cm, WritableRaster raster) {
213: int transferType = cm.getTransferType();
214: boolean hasAlpha = cm.hasAlpha();
215: ColorSpace cs = cm.getColorSpace();
216: int csType = cs.getType();
217: SampleModel sm = raster.getSampleModel();
218:
219: if (csType == ColorSpace.TYPE_RGB) {
220: if (cm instanceof DirectColorModel) {
221: DirectColorModel dcm = (DirectColorModel) cm;
222: switch (transferType) {
223: case DataBuffer.TYPE_INT:
224: if (dcm.getRedMask() == RED_MASK
225: && dcm.getGreenMask() == GREEN_MASK
226: && dcm.getBlueMask() == BLUE_MASK) {
227: if (!hasAlpha) {
228: return BufferedImage.TYPE_INT_RGB;
229: }
230: if (dcm.getAlphaMask() == ALPHA_MASK) {
231: if (dcm.isAlphaPremultiplied()) {
232: return BufferedImage.TYPE_INT_ARGB_PRE;
233: }
234: return BufferedImage.TYPE_INT_ARGB;
235: }
236: return BufferedImage.TYPE_CUSTOM;
237: } else if (dcm.getRedMask() == RED_BGR_MASK
238: && dcm.getGreenMask() == GREEN_BGR_MASK
239: && dcm.getBlueMask() == BLUE_BGR_MASK) {
240: if (!hasAlpha) {
241: return BufferedImage.TYPE_INT_BGR;
242: }
243: } else {
244: return BufferedImage.TYPE_CUSTOM;
245: }
246: case DataBuffer.TYPE_USHORT:
247: if (dcm.getRedMask() == RED_555_MASK
248: && dcm.getGreenMask() == GREEN_555_MASK
249: && dcm.getBlueMask() == BLUE_555_MASK
250: && !hasAlpha) {
251: return BufferedImage.TYPE_USHORT_555_RGB;
252: } else if (dcm.getRedMask() == RED_565_MASK
253: && dcm.getGreenMask() == GREEN_565_MASK
254: && dcm.getBlueMask() == BLUE_565_MASK) {
255: return BufferedImage.TYPE_USHORT_565_RGB;
256: }
257: default:
258: return BufferedImage.TYPE_CUSTOM;
259: }
260: } else if (cm instanceof IndexColorModel) {
261: IndexColorModel icm = (IndexColorModel) cm;
262: int pixelBits = icm.getPixelSize();
263: if (transferType == DataBuffer.TYPE_BYTE) {
264: if (sm instanceof MultiPixelPackedSampleModel
265: && !hasAlpha && pixelBits < 5) {
266: return BufferedImage.TYPE_BYTE_BINARY;
267: } else if (pixelBits == 8) {
268: return BufferedImage.TYPE_BYTE_INDEXED;
269: }
270: }
271: return BufferedImage.TYPE_CUSTOM;
272: } else if (cm instanceof ComponentColorModel) {
273: ComponentColorModel ccm = (ComponentColorModel) cm;
274: if (transferType == DataBuffer.TYPE_BYTE
275: && sm instanceof ComponentSampleModel) {
276: ComponentSampleModel csm = (ComponentSampleModel) sm;
277: int[] offsets = csm.getBandOffsets();
278: int[] bits = ccm.getComponentSize();
279: boolean isCustom = false;
280: for (int i = 0; i < bits.length; i++) {
281: if (bits[i] != 8
282: || offsets[i] != offsets.length - 1 - i) {
283: isCustom = true;
284: break;
285: }
286: }
287: if (!isCustom) {
288: if (!ccm.hasAlpha()) {
289: return BufferedImage.TYPE_3BYTE_BGR;
290: } else if (ccm.isAlphaPremultiplied()) {
291: return BufferedImage.TYPE_4BYTE_ABGR_PRE;
292: } else {
293: return BufferedImage.TYPE_4BYTE_ABGR;
294: }
295: }
296: }
297: return BufferedImage.TYPE_CUSTOM;
298: }
299: return BufferedImage.TYPE_CUSTOM;
300: } else if (cs == LUTColorConverter.LINEAR_GRAY_CS) {
301: if (cm instanceof ComponentColorModel
302: && cm.getNumComponents() == 1) {
303: int bits[] = cm.getComponentSize();
304: if (transferType == DataBuffer.TYPE_BYTE
305: && bits[0] == 8) {
306: return BufferedImage.TYPE_BYTE_GRAY;
307: } else if (transferType == DataBuffer.TYPE_USHORT
308: && bits[0] == 16) {
309: return BufferedImage.TYPE_USHORT_GRAY;
310: } else {
311: return BufferedImage.TYPE_CUSTOM;
312: }
313: }
314: return BufferedImage.TYPE_CUSTOM;
315: }
316: return BufferedImage.TYPE_CUSTOM;
317: }
318:
319: public static Surface getImageSurface(Image image) {
320: return AwtImageBackdoorAccessor.getInstance().getImageSurface(
321: image);
322: }
323:
324: @Override
325: protected void finalize() throws Throwable {
326: dispose();
327: }
328:
329: public static boolean isGrayPallete(IndexColorModel icm) {
330: return AwtImageBackdoorAccessor.getInstance()
331: .isGrayPallete(icm);
332: }
333:
334: /**
335: * Initialization of Native data
336: *
337: */
338: private static native void initIDs();
339: }
|