001: /*
002: * @(#)X11Image.java 1.25 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.awt;
029:
030: import java.util.Hashtable;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.Vector;
034: import java.awt.image.ImageProducer;
035: import java.awt.image.ImageObserver;
036: import java.awt.image.ImageConsumer;
037: import java.awt.image.ColorModel;
038: import java.awt.image.IndexColorModel;
039: import java.awt.image.DirectColorModel;
040:
041: /** @version 1.16, 12/05/01
042: */
043:
044: class X11Image extends java.awt.image.BufferedImage implements
045: ImageConsumer {
046: static final int REDRAW_COUNT = 20;
047: int Xpixmap; /* X Drawable pixmap, so you can use the XDraw funcs with image */
048: int Xclipmask; /* XImage, clientside XBitmap of clipmask, no need for draw func functionality */
049: int width, height;
050: int status;
051: private Hashtable myProperties;
052: private HashSet observers = new HashSet();
053: private ColorModel colorModel;
054: private int scanlineCount;
055: private ImageProducer myProducer;
056: private Vector XpixmapList; /* Was going to be used with multiple frame images */
057:
058: /* create the offscreen image source */
059: private native int pCreatePixmap(int width, int height, Color bg);
060:
061: private native int pCreatePixmapImg(int Ximage, int width,
062: int height); /* This will destroy the image */
063:
064: private native int pCreateClipmask(int width, int height); /* needed for transparency */
065:
066: private native int pGetSubPixmapImage(int Ximage, int x, int y,
067: int width, int height);
068:
069: private native int pGetSubImage(int Ximage, int x, int y,
070: int width, int height);
071:
072: static private native void initIDs();
073:
074: static {
075: Toolkit.getDefaultToolkit();
076: initIDs();
077: }
078:
079: X11Image(int w, int h, Color background) {
080: width = w;
081: height = h;
082: if ((width > 0) && (height > 0)) {
083: Xpixmap = pCreatePixmap(w, h, background);
084: Xclipmask = pCreateClipmask(w, h);
085: /* status |= ImageObserver.WIDTH|ImageObserver.HEIGHT; */
086: }
087: colorModel = Toolkit.getDefaultToolkit().getColorModel();
088: }
089:
090: X11Image(ImageProducer imageProd) {
091: width = -1;
092: height = -1;
093: myProducer = imageProd;
094: myProducer.startProduction(this );
095: }
096:
097: X11Image(int Ximage, int Xclipmask, int w, int h) {
098: Xpixmap = pCreatePixmapImg(Ximage, w, h);
099: this .Xclipmask = Xclipmask;
100: width = w;
101: height = h;
102: colorModel = Toolkit.getDefaultToolkit().getColorModel();
103: }
104:
105: public Graphics getGraphics() {
106: return new X11Graphics(this );
107: }
108:
109: public int getWidth() {
110: return width;
111: }
112:
113: public int getWidth(ImageObserver observer) {
114: if (width == -1)
115: addObserver(observer);
116: return width;
117: }
118:
119: public int getHeight() {
120: return height;
121: }
122:
123: public int getHeight(ImageObserver observer) {
124: if (height == -1)
125: addObserver(observer);
126: return height;
127: }
128:
129: public Object getProperty(String name, ImageObserver observer) {
130: if (myProperties == null) {
131: addObserver(observer);
132: return UndefinedProperty;
133: }
134: return myProperties.get(name);
135: }
136:
137: public String[] getPropertyNames() {
138: Object[] names = myProperties.keySet().toArray();
139: String[] newNames = new String[names.length];
140: System.arraycopy(names, 0, newNames, 0, newNames.length);
141: return newNames;
142: }
143:
144: int getStatus(ImageObserver observer) {
145: addObserver(observer);
146: return status;
147: }
148:
149: public java.awt.image.BufferedImage getSubImage(int x, int y,
150: int w, int h) {
151: int Ximage = pGetSubPixmapImage(Xpixmap, x, y, w, h);
152: int newXclipmask = pGetSubImage(Xclipmask, x, y, w, h);
153: return new X11Image(Ximage, newXclipmask, w, h);
154: }
155:
156: boolean prepareImage(int width, int height, ImageObserver observer) {
157: addObserver(observer);
158: if ((width > 0) && (height > 0)) {
159: setDimensions(width, height);
160: return true;
161: }
162: return false;
163: }
164:
165: void addObserver(ImageObserver observer) {
166: if (observer != null)
167: observers.add(observer);
168: }
169:
170: public void flush() {
171: }
172:
173: public ImageProducer getSource() {
174: return myProducer;
175: }
176:
177: /***** --- Consumer Stuff --- *****/
178:
179: public void imageComplete(int stat) {
180: int obsStat = 0;
181: if (stat == STATICIMAGEDONE)
182: obsStat = ImageObserver.ALLBITS;
183: else if (stat == SINGLEFRAMEDONE)
184: obsStat = ImageObserver.FRAMEBITS;
185: else if (stat == IMAGEERROR)
186: obsStat = ImageObserver.ERROR;
187: else if (stat == IMAGEABORTED)
188: obsStat = ImageObserver.ABORT;
189: status |= obsStat;
190: if ((obsStat != 0) && (observers != null)) {
191: Iterator obs = observers.iterator();
192: synchronized (observers) {
193: while (obs.hasNext()) {
194: ImageObserver iobs = (ImageObserver) obs.next();
195: iobs
196: .imageUpdate(this , obsStat, 0, 0, width,
197: height);
198: }
199: }
200: }
201: if ((obsStat & (ImageObserver.ALLBITS | ImageObserver.ERROR | ImageObserver.ABORT)) != 0)
202: myProducer.removeConsumer(this );
203: }
204:
205: public void setColorModel(ColorModel cm) {
206: colorModel = cm;
207: }
208:
209: public void setDimensions(int width, int height) {
210: if (Xpixmap != 0)
211: Thread.dumpStack();
212: this .width = width;
213: this .height = height;
214: if ((this .width > 0) && (this .height > 0)) {
215: Xpixmap = pCreatePixmap(this .width, this .height, null);
216: Xclipmask = pCreateClipmask(this .width, this .height);
217: }
218: /*
219: if(this.width>0) status|=ImageObserver.WIDTH;
220: if(this.height>0) status|=ImageObserver.HEIGHT;
221: */
222:
223: Iterator obs = observers.iterator();
224: synchronized (observers) {
225: while (obs.hasNext()) {
226: ImageObserver iobs = (ImageObserver) obs.next();
227: iobs.imageUpdate(this , ImageObserver.WIDTH, 0, 0,
228: width, 0);
229: iobs.imageUpdate(this , ImageObserver.HEIGHT, 0, 0, 0,
230: height);
231: }
232: }
233: }
234:
235: public void setProperties(Hashtable props) {
236: myProperties = props;
237: }
238:
239: public void setHints(int hints) {/*
240: System.out.println("ImageHints:");
241:
242: if((hints&RANDOMPIXELORDER) != 0)
243: System.out.println("Hints: random order");
244:
245: if((hints&TOPDOWNLEFTRIGHT) != 0)
246: System.out.println("Hints: top down");
247:
248: if((hints&COMPLETESCANLINES) != 0)
249: System.out.println("Hints: complete scan lines");
250:
251: if((hints&SINGLEPASS) != 0)
252: System.out.println("Hints: single pass");
253:
254: if((hints&SINGLEFRAME) != 0)
255: System.out.println("Hints: single frame");
256: */
257: }
258:
259: private native void pSetPixels(int src, int clipmask, int[] pixels,
260: int x, int y, int w, int h, int scansize);
261:
262: private native int[] pGetPixels(int src, int clipmask,
263: int[] pixels, int x, int y, int w, int h, int scansize,
264: int offset);
265:
266: private native int[] XIndexColorCvt(ColorModel cm, byte[] pixels,
267: int off);
268:
269: private native int[] XIndexColorCvt(ColorModel cm, int[] pixels,
270: int off);
271:
272: private native int[] XDirectColorCvt(ColorModel cm, int[] pixels,
273: int off);
274:
275: private int[] XDefaultColorCvt(ColorModel cm, byte[] pixels, int off) {
276: int[] p = new int[pixels.length - off];
277: for (int i = off; i < pixels.length; i++)
278: p[i - off] = cm.getRGB(pixels[i] & 0xFF);
279: return p;
280: }
281:
282: private int[] XDefaultColorCvt(ColorModel cm, int[] pixels, int off) {
283: int[] p = new int[pixels.length - off];
284: for (int i = off; i < pixels.length; i++)
285: p[i - off] = cm.getRGB(pixels[i]);
286: return p;
287: }
288:
289: public void setPixels(int x, int y, int w, int h, ColorModel cm,
290: byte[] pixels, int off, int scansize) {
291: int[] p;
292: if (cm instanceof IndexColorModel)
293: p = XIndexColorCvt(cm, pixels, off);
294: else
295: p = XDefaultColorCvt(cm, pixels, off);
296: if (scansize == 0)
297: scansize = p.length;
298: pSetPixels(Xpixmap, Xclipmask, p, x, y, w, h, scansize);
299: scanlineCount++;
300: if (scanlineCount % REDRAW_COUNT == 0) {
301: Iterator obs = observers.iterator();
302: synchronized (observers) {
303: while (obs.hasNext()) {
304: ImageObserver iobs = (ImageObserver) obs.next();
305: iobs.imageUpdate(this , ImageObserver.SOMEBITS, x,
306: y, w, h);
307: }
308: }
309: }
310: }
311:
312: public void setPixels(int x, int y, int w, int h, ColorModel cm,
313: int[] pixels, int off, int scansize) {
314: int[] p;
315: if (cm instanceof DirectColorModel)
316: p = XDirectColorCvt(cm, pixels, off);
317: else if (cm instanceof IndexColorModel)
318: p = XIndexColorCvt(cm, pixels, off);
319: else
320: p = XDefaultColorCvt(cm, pixels, off);
321: if (scansize == 0)
322: scansize = p.length;
323: pSetPixels(Xpixmap, Xclipmask, p, x, y, w, h, scansize);
324: scanlineCount++;
325: status |= ImageObserver.SOMEBITS;
326: if (scanlineCount % REDRAW_COUNT == 0) {
327: Iterator obs = observers.iterator();
328: synchronized (observers) {
329: while (obs.hasNext()) {
330: ImageObserver iobs = (ImageObserver) obs.next();
331: iobs.imageUpdate(this , ImageObserver.SOMEBITS, x,
332: y, w, h);
333: }
334: }
335: }
336: }
337:
338: public void setRGB(int startX, int startY, int w, int h,
339: int[] rgbArray, int offset, int scansize) {
340: System.out.println("setRGB...." + colorModel);
341: int[] p = XDirectColorCvt(colorModel, rgbArray, offset);
342: if (scansize == 0)
343: scansize = p.length;
344: pSetPixels(Xpixmap, Xclipmask, p, startX, startY, w, h,
345: scansize);
346: }
347:
348: public int[] getRGB(int startX, int startY, int w, int h,
349: int[] rgbArray, int offset, int scansize) {
350: return null;
351: }
352: }
|