001: /*
002: * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.image;
027:
028: import java.awt.Color;
029: import java.awt.Graphics;
030: import java.awt.Transparency;
031: import java.awt.AWTException;
032: import java.awt.Rectangle;
033: import java.awt.image.BufferedImage;
034: import java.awt.image.ColorModel;
035: import java.awt.image.DirectColorModel;
036: import java.awt.image.IndexColorModel;
037: import java.awt.image.ImageConsumer;
038: import java.awt.image.ImageObserver;
039: import sun.awt.image.ByteComponentRaster;
040: import sun.awt.image.IntegerComponentRaster;
041: import java.awt.image.Raster;
042: import java.awt.image.WritableRaster;
043: import java.awt.image.DataBuffer;
044: import java.awt.image.DataBufferInt;
045: import java.awt.Graphics2D;
046: import java.awt.geom.AffineTransform;
047: import sun.awt.image.ImageWatched;
048: import java.util.Hashtable;
049:
050: public class ImageRepresentation extends ImageWatched implements
051: ImageConsumer {
052: InputStreamImageSource src;
053: ToolkitImage image;
054: int tag;
055:
056: long pData; // used by windows native code only -- internal state REMIND ATTN @@
057:
058: int width = -1;
059: int height = -1;
060: int hints;
061:
062: int availinfo;
063:
064: Rectangle newbits;
065:
066: BufferedImage bimage;
067: WritableRaster biRaster;
068: protected ColorModel cmodel;
069: ColorModel srcModel = null;
070: int[] srcLUT = null;
071: int srcLUTtransIndex = -1;
072: int numSrcLUT = 0;
073: boolean forceCMhint;
074: int sstride;
075: boolean isDefaultBI = false;
076: boolean isSameCM = false;
077:
078: private native static void initIDs();
079:
080: static {
081: /* ensure that the necessary native libraries are loaded */
082: NativeLibLoader.loadLibraries();
083: initIDs();
084: }
085:
086: /**
087: * Create an ImageRepresentation for the given Image. The
088: * width and height are unknown at this point. The color
089: * model is a hint as to the color model to use when creating
090: * the buffered image. If null, the src color model will
091: * be used.
092: */
093: public ImageRepresentation(ToolkitImage im, ColorModel cmodel,
094: boolean forceCMhint) {
095: image = im;
096:
097: if (image.getSource() instanceof InputStreamImageSource) {
098: src = (InputStreamImageSource) image.getSource();
099: }
100:
101: setColorModel(cmodel);
102:
103: this .forceCMhint = forceCMhint;
104: }
105:
106: /* REMIND: Only used for Frame.setIcon - should use ImageWatcher instead */
107: public synchronized void reconstruct(int flags) {
108: if (src != null) {
109: src.checkSecurity(null, false);
110: }
111: int missinginfo = flags & ~availinfo;
112: if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) {
113: numWaiters++;
114: try {
115: startProduction();
116: missinginfo = flags & ~availinfo;
117: while ((availinfo & ImageObserver.ERROR) == 0
118: && missinginfo != 0) {
119: try {
120: wait();
121: } catch (InterruptedException e) {
122: Thread.currentThread().interrupt();
123: return;
124: }
125: missinginfo = flags & ~availinfo;
126: }
127: } finally {
128: decrementWaiters();
129: }
130: }
131: }
132:
133: public void setDimensions(int w, int h) {
134: if (src != null) {
135: src.checkSecurity(null, false);
136: }
137:
138: image.setDimensions(w, h);
139:
140: newInfo(image, (ImageObserver.WIDTH | ImageObserver.HEIGHT), 0,
141: 0, w, h);
142:
143: if (w <= 0 || h <= 0) {
144: imageComplete(ImageConsumer.IMAGEERROR);
145: return;
146: }
147:
148: if (width != w || height != h) {
149: // dimension mismatch => trigger recreation of the buffer
150: bimage = null;
151: }
152:
153: width = w;
154: height = h;
155:
156: availinfo |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
157: }
158:
159: public int getWidth() {
160: return width;
161: }
162:
163: public int getHeight() {
164: return height;
165: }
166:
167: ColorModel getColorModel() {
168: return cmodel;
169: }
170:
171: BufferedImage getBufferedImage() {
172: return bimage;
173: }
174:
175: /**
176: * Returns the BufferedImage that will be used as the representation of
177: * the pixel data. Subclasses can override this method to return
178: * platform specific subclasses of BufferedImage that may or may not be
179: * accelerated.
180: *
181: * It is subclass' responsibility to propagate acceleration priority
182: * to the newly created image.
183: */
184: protected BufferedImage createImage(ColorModel cm,
185: WritableRaster raster, boolean isRasterPremultiplied,
186: Hashtable properties) {
187: BufferedImage bi = new BufferedImage(cm, raster,
188: isRasterPremultiplied, null);
189: bi.setAccelerationPriority(image.getAccelerationPriority());
190: return bi;
191: }
192:
193: public void setProperties(Hashtable<?, ?> props) {
194: if (src != null) {
195: src.checkSecurity(null, false);
196: }
197: image.setProperties(props);
198: newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0);
199: }
200:
201: public void setColorModel(ColorModel model) {
202: if (src != null) {
203: src.checkSecurity(null, false);
204: }
205: srcModel = model;
206:
207: // Check to see if model is INT_RGB
208: if (model instanceof IndexColorModel) {
209: if (model.getTransparency() == model.TRANSLUCENT) {
210: // REMIND:
211: // Probably need to composite anyway so force ARGB
212: cmodel = ColorModel.getRGBdefault();
213: srcLUT = null;
214: } else {
215: IndexColorModel icm = (IndexColorModel) model;
216: numSrcLUT = icm.getMapSize();
217: srcLUT = new int[Math.max(numSrcLUT, 256)];
218: icm.getRGBs(srcLUT);
219: srcLUTtransIndex = icm.getTransparentPixel();
220: cmodel = model;
221: }
222: } else {
223: if (cmodel == null) {
224: cmodel = model;
225: srcLUT = null;
226: } else if (model instanceof DirectColorModel) {
227: // If it is INT_RGB or INT_ARGB, use the model
228: DirectColorModel dcm = (DirectColorModel) model;
229: if ((dcm.getRedMask() == 0xff0000)
230: && (dcm.getGreenMask() == 0xff00)
231: && (dcm.getBlueMask() == 0x00ff)) {
232: cmodel = model;
233: srcLUT = null;
234: }
235: }
236: }
237:
238: isSameCM = (cmodel == model);
239: }
240:
241: void createBufferedImage() {
242: // REMIND: Be careful! Is this called everytime there is a
243: // startProduction? We only want to call it if it is new or
244: // there is an error
245: isDefaultBI = false;
246: try {
247: biRaster = cmodel.createCompatibleWritableRaster(width,
248: height);
249: bimage = createImage(cmodel, biRaster, cmodel
250: .isAlphaPremultiplied(), null);
251: } catch (Exception e) {
252: // Create a default image
253: cmodel = ColorModel.getRGBdefault();
254: biRaster = cmodel.createCompatibleWritableRaster(width,
255: height);
256: bimage = createImage(cmodel, biRaster, false, null);
257: }
258: int type = bimage.getType();
259:
260: if ((cmodel == ColorModel.getRGBdefault())
261: || (type == BufferedImage.TYPE_INT_RGB)
262: || (type == BufferedImage.TYPE_INT_ARGB_PRE)) {
263: isDefaultBI = true;
264: } else if (cmodel instanceof DirectColorModel) {
265: DirectColorModel dcm = (DirectColorModel) cmodel;
266: if (dcm.getRedMask() == 0xff0000
267: && dcm.getGreenMask() == 0xff00
268: && dcm.getBlueMask() == 0xff) {
269: isDefaultBI = true;
270: }
271: }
272: }
273:
274: private void convertToRGB() {
275: int w = bimage.getWidth();
276: int h = bimage.getHeight();
277: int size = w * h;
278:
279: DataBufferInt dbi = new DataBufferInt(size);
280: // Note that stealData() requires a markDirty() afterwards
281: // since we modify the data in it.
282: int newpixels[] = SunWritableRaster.stealData(dbi, 0);
283: if (cmodel instanceof IndexColorModel
284: && biRaster instanceof ByteComponentRaster
285: && biRaster.getNumDataElements() == 1) {
286: ByteComponentRaster bct = (ByteComponentRaster) biRaster;
287: byte[] data = bct.getDataStorage();
288: int coff = bct.getDataOffset(0);
289: for (int i = 0; i < size; i++) {
290: newpixels[i] = srcLUT[data[coff + i] & 0xff];
291: }
292: } else {
293: Object srcpixels = null;
294: int off = 0;
295: for (int y = 0; y < h; y++) {
296: for (int x = 0; x < w; x++) {
297: srcpixels = biRaster.getDataElements(x, y,
298: srcpixels);
299: newpixels[off++] = cmodel.getRGB(srcpixels);
300: }
301: }
302: }
303: // We modified the data array directly above so mark it as dirty now...
304: SunWritableRaster.markDirty(dbi);
305:
306: isSameCM = false;
307: cmodel = ColorModel.getRGBdefault();
308:
309: int bandMasks[] = { 0x00ff0000, 0x0000ff00, 0x000000ff,
310: 0xff000000 };
311:
312: biRaster = Raster.createPackedRaster(dbi, w, h, w, bandMasks,
313: null);
314:
315: bimage = createImage(cmodel, biRaster, cmodel
316: .isAlphaPremultiplied(), null);
317: srcLUT = null;
318: isDefaultBI = true;
319: }
320:
321: public void setHints(int h) {
322: if (src != null) {
323: src.checkSecurity(null, false);
324: }
325: hints = h;
326: }
327:
328: public native void setICMpixels(int x, int y, int w, int h,
329: int[] lut, byte[] pix, int off, int scansize,
330: IntegerComponentRaster ict);
331:
332: public native void setBytePixels(int x, int y, int w, int h,
333: byte[] pix, int off, int scansize, ByteComponentRaster bct,
334: int chanOff);
335:
336: public native int setDiffICM(int x, int y, int w, int h, int[] lut,
337: int transPix, int numLut, IndexColorModel icm, byte[] pix,
338: int off, int scansize, ByteComponentRaster bct, int chanOff);
339:
340: static boolean s_useNative = true;
341:
342: public void setPixels(int x, int y, int w, int h, ColorModel model,
343: byte pix[], int off, int scansize) {
344: int lineOff = off;
345: int poff;
346: int[] newLUT = null;
347:
348: if (src != null) {
349: src.checkSecurity(null, false);
350: }
351:
352: // REMIND: What if the model doesn't fit in default color model?
353: synchronized (this ) {
354: if (bimage == null) {
355: if (cmodel == null) {
356: cmodel = model;
357: }
358: createBufferedImage();
359: }
360: if (isSameCM && (cmodel != model) && (srcLUT != null)
361: && (model instanceof IndexColorModel)
362: && (biRaster instanceof ByteComponentRaster)) {
363: IndexColorModel icm = (IndexColorModel) model;
364: ByteComponentRaster bct = (ByteComponentRaster) biRaster;
365: int numlut = numSrcLUT;
366: if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
367: numSrcLUT, icm, pix, off, scansize, bct, bct
368: .getDataOffset(0)) == 0) {
369: convertToRGB();
370: } else {
371: // Note that setDiffICM modified the raster directly
372: // so we must mark it as changed
373: bct.markDirty();
374: if (numlut != numSrcLUT) {
375: boolean hasAlpha = icm.hasAlpha();
376: if (srcLUTtransIndex != -1) {
377: hasAlpha = true;
378: }
379: int nbits = icm.getPixelSize();
380: icm = new IndexColorModel(nbits, numSrcLUT,
381: srcLUT, 0, hasAlpha, srcLUTtransIndex,
382: (nbits > 8 ? DataBuffer.TYPE_USHORT
383: : DataBuffer.TYPE_BYTE));
384: cmodel = icm;
385: bimage = createImage(icm, bct, false, null);
386: }
387: return;
388: }
389: }
390:
391: if (isDefaultBI) {
392: int pixel;
393: IntegerComponentRaster iraster = (IntegerComponentRaster) biRaster;
394: if (srcLUT != null && model instanceof IndexColorModel) {
395: if (model != srcModel) {
396: // Fill in the new lut
397: ((IndexColorModel) model).getRGBs(srcLUT);
398: srcModel = model;
399: }
400:
401: if (s_useNative) {
402: // Note that setICMpixels modifies the raster directly
403: // so we must mark it as changed afterwards
404: setICMpixels(x, y, w, h, srcLUT, pix, off,
405: scansize, iraster);
406: iraster.markDirty();
407: } else {
408: int[] storage = new int[w * h];
409: int soff = 0;
410: // It is an IndexColorModel
411: for (int yoff = 0; yoff < h; yoff++, lineOff += scansize) {
412: poff = lineOff;
413: for (int i = 0; i < w; i++) {
414: storage[soff++] = srcLUT[pix[poff++] & 0xff];
415: }
416: }
417: iraster.setDataElements(x, y, w, h, storage);
418: }
419: } else {
420: int[] storage = new int[w];
421: for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) {
422: poff = lineOff;
423: for (int i = 0; i < w; i++) {
424: storage[i] = model
425: .getRGB(pix[poff++] & 0xff);
426: }
427: iraster.setDataElements(x, yoff, w, 1, storage);
428: }
429: availinfo |= ImageObserver.SOMEBITS;
430: }
431: } else if ((cmodel == model)
432: && (biRaster instanceof ByteComponentRaster)
433: && (biRaster.getNumDataElements() == 1)) {
434: ByteComponentRaster bt = (ByteComponentRaster) biRaster;
435: if (w * h > 200) {
436: if (off == 0 && scansize == w) {
437: bt.putByteData(x, y, w, h, pix);
438: } else {
439: byte[] bpix = new byte[w];
440: poff = off;
441: for (int yoff = y; yoff < y + h; yoff++) {
442: System.arraycopy(pix, poff, bpix, 0, w);
443: bt.putByteData(x, yoff, w, 1, bpix);
444: poff += scansize;
445: }
446: }
447: } else {
448: // Only is faster if #pixels
449: // Note that setBytePixels modifies the raster directly
450: // so we must mark it as changed afterwards
451: setBytePixels(x, y, w, h, pix, off, scansize, bt,
452: bt.getDataOffset(0));
453: bt.markDirty();
454: }
455: } else {
456: for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) {
457: poff = lineOff;
458: for (int xoff = x; xoff < x + w; xoff++) {
459: bimage.setRGB(xoff, yoff, model
460: .getRGB(pix[poff++] & 0xff));
461: }
462: }
463: availinfo |= ImageObserver.SOMEBITS;
464: }
465: }
466:
467: if ((availinfo & ImageObserver.FRAMEBITS) == 0) {
468: newInfo(image, ImageObserver.SOMEBITS, x, y, w, h);
469: }
470: }
471:
472: public void setPixels(int x, int y, int w, int h, ColorModel model,
473: int pix[], int off, int scansize) {
474: int lineOff = off;
475: int poff;
476:
477: if (src != null) {
478: src.checkSecurity(null, false);
479: }
480:
481: // REMIND: What if the model doesn't fit in default color model?
482: synchronized (this ) {
483: if (bimage == null) {
484: if (cmodel == null) {
485: cmodel = model;
486: }
487: createBufferedImage();
488: }
489:
490: int[] storage = new int[w];
491: int yoff;
492: int pixel;
493:
494: if (cmodel instanceof IndexColorModel) {
495: // REMIND: Right now we don't support writing back into ICM
496: // images.
497: convertToRGB();
498: }
499:
500: if ((model == cmodel)
501: && (biRaster instanceof IntegerComponentRaster)) {
502: IntegerComponentRaster iraster = (IntegerComponentRaster) biRaster;
503:
504: if (off == 0 && scansize == w) {
505: iraster.setDataElements(x, y, w, h, pix);
506: } else {
507: // Need to pack the data
508: for (yoff = y; yoff < y + h; yoff++, lineOff += scansize) {
509: System.arraycopy(pix, lineOff, storage, 0, w);
510: iraster.setDataElements(x, yoff, w, 1, storage);
511: }
512: }
513: } else {
514: if (model.getTransparency() != model.OPAQUE
515: && cmodel.getTransparency() == cmodel.OPAQUE) {
516: convertToRGB();
517: }
518:
519: if (isDefaultBI) {
520: IntegerComponentRaster iraster = (IntegerComponentRaster) biRaster;
521: int[] data = iraster.getDataStorage();
522: if (cmodel.equals(model)) {
523: int sstride = iraster.getScanlineStride();
524: int doff = y * sstride + x;
525: for (yoff = 0; yoff < h; yoff++, lineOff += scansize) {
526: System.arraycopy(pix, lineOff, data, doff,
527: w);
528: doff += sstride;
529: }
530: // Note: manual modification of pixels, mark the
531: // raster as changed
532: iraster.markDirty();
533: } else {
534: for (yoff = y; yoff < y + h; yoff++, lineOff += scansize) {
535: poff = lineOff;
536: for (int i = 0; i < w; i++) {
537: storage[i] = model.getRGB(pix[poff++]);
538: }
539: iraster.setDataElements(x, yoff, w, 1,
540: storage);
541: }
542: }
543:
544: availinfo |= ImageObserver.SOMEBITS;
545: } else {
546: Object tmp = null;
547:
548: for (yoff = y; yoff < y + h; yoff++, lineOff += scansize) {
549: poff = lineOff;
550: for (int xoff = x; xoff < x + w; xoff++) {
551: pixel = model.getRGB(pix[poff++]);
552: tmp = cmodel.getDataElements(pixel, tmp);
553: biRaster.setDataElements(xoff, yoff, tmp);
554: }
555: }
556: availinfo |= ImageObserver.SOMEBITS;
557: }
558: }
559: }
560:
561: // Can't do this here since we might need to transform/clip
562: // the region
563: if (((availinfo & ImageObserver.FRAMEBITS) == 0)) {
564: newInfo(image, ImageObserver.SOMEBITS, x, y, w, h);
565: }
566: }
567:
568: public BufferedImage getOpaqueRGBImage() {
569: if (bimage.getType() == BufferedImage.TYPE_INT_ARGB) {
570: int w = bimage.getWidth();
571: int h = bimage.getHeight();
572: int size = w * h;
573:
574: // Note that we steal the data array here, but only for reading...
575: DataBufferInt db = (DataBufferInt) biRaster.getDataBuffer();
576: int[] pixels = SunWritableRaster.stealData(db, 0);
577:
578: for (int i = 0; i < size; i++) {
579: if ((pixels[i] >>> 24) != 0xff) {
580: return bimage;
581: }
582: }
583:
584: ColorModel opModel = new DirectColorModel(24, 0x00ff0000,
585: 0x0000ff00, 0x000000ff);
586:
587: int bandmasks[] = { 0x00ff0000, 0x0000ff00, 0x000000ff };
588: WritableRaster opRaster = Raster.createPackedRaster(db, w,
589: h, w, bandmasks, null);
590:
591: try {
592: BufferedImage opImage = createImage(opModel, opRaster,
593: false, null);
594: return opImage;
595: } catch (Exception e) {
596: return bimage;
597: }
598: }
599: return bimage;
600: }
601:
602: private boolean consuming = false;
603:
604: public void imageComplete(int status) {
605: if (src != null) {
606: src.checkSecurity(null, false);
607: }
608: boolean done;
609: int info;
610: switch (status) {
611: default:
612: case ImageConsumer.IMAGEABORTED:
613: done = true;
614: info = ImageObserver.ABORT;
615: break;
616: case ImageConsumer.IMAGEERROR:
617: image.addInfo(ImageObserver.ERROR);
618: done = true;
619: info = ImageObserver.ERROR;
620: dispose();
621: break;
622: case ImageConsumer.STATICIMAGEDONE:
623: done = true;
624: info = ImageObserver.ALLBITS;
625: break;
626: case ImageConsumer.SINGLEFRAMEDONE:
627: done = false;
628: info = ImageObserver.FRAMEBITS;
629: break;
630: }
631: synchronized (this ) {
632: if (done) {
633: image.getSource().removeConsumer(this );
634: consuming = false;
635: newbits = null;
636:
637: if (bimage != null) {
638: bimage = getOpaqueRGBImage();
639: }
640: }
641: availinfo |= info;
642: notifyAll();
643: }
644:
645: newInfo(image, info, 0, 0, width, height);
646:
647: image.infoDone(status);
648: }
649:
650: /*synchronized*/void startProduction() {
651: if (!consuming) {
652: consuming = true;
653: image.getSource().startProduction(this );
654: }
655: }
656:
657: private int numWaiters;
658:
659: private synchronized void checkConsumption() {
660: if (isWatcherListEmpty() && numWaiters == 0
661: && ((availinfo & ImageObserver.ALLBITS) == 0)) {
662: dispose();
663: }
664: }
665:
666: public synchronized void notifyWatcherListEmpty() {
667: checkConsumption();
668: }
669:
670: private synchronized void decrementWaiters() {
671: --numWaiters;
672: checkConsumption();
673: }
674:
675: public boolean prepare(ImageObserver iw) {
676: if (src != null) {
677: src.checkSecurity(null, false);
678: }
679: if ((availinfo & ImageObserver.ERROR) != 0) {
680: if (iw != null) {
681: iw.imageUpdate(image, ImageObserver.ERROR
682: | ImageObserver.ABORT, -1, -1, -1, -1);
683: }
684: return false;
685: }
686: boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
687: if (!done) {
688: addWatcher(iw);
689: startProduction();
690: // Some producers deliver image data synchronously
691: done = ((availinfo & ImageObserver.ALLBITS) != 0);
692: }
693: return done;
694: }
695:
696: public int check(ImageObserver iw) {
697:
698: if (src != null) {
699: src.checkSecurity(null, false);
700: }
701: if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) {
702: addWatcher(iw);
703: }
704:
705: return availinfo;
706: }
707:
708: public boolean drawToBufImage(Graphics g, ToolkitImage img, int x,
709: int y, Color bg, ImageObserver iw) {
710:
711: if (src != null) {
712: src.checkSecurity(null, false);
713: }
714: if ((availinfo & ImageObserver.ERROR) != 0) {
715: if (iw != null) {
716: iw.imageUpdate(image, ImageObserver.ERROR
717: | ImageObserver.ABORT, -1, -1, -1, -1);
718: }
719: return false;
720: }
721: boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
722: boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
723:
724: if (!done && !abort) {
725: addWatcher(iw);
726: startProduction();
727: // Some producers deliver image data synchronously
728: done = ((availinfo & ImageObserver.ALLBITS) != 0);
729: }
730:
731: if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
732: g.drawImage(bimage, x, y, bg, null);
733: }
734:
735: return done;
736: }
737:
738: public boolean drawToBufImage(Graphics g, ToolkitImage img, int x,
739: int y, int w, int h, Color bg, ImageObserver iw) {
740:
741: if (src != null) {
742: src.checkSecurity(null, false);
743: }
744: if ((availinfo & ImageObserver.ERROR) != 0) {
745: if (iw != null) {
746: iw.imageUpdate(image, ImageObserver.ERROR
747: | ImageObserver.ABORT, -1, -1, -1, -1);
748: }
749: return false;
750: }
751:
752: boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
753: boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
754:
755: if (!done && !abort) {
756: addWatcher(iw);
757: startProduction();
758: // Some producers deliver image data synchronously
759: done = ((availinfo & ImageObserver.ALLBITS) != 0);
760: }
761:
762: if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
763: g.drawImage(bimage, x, y, w, h, bg, null);
764: }
765:
766: return done;
767: }
768:
769: public boolean drawToBufImage(Graphics g, ToolkitImage img,
770: int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
771: int sx2, int sy2, Color bg, ImageObserver iw) {
772:
773: if (src != null) {
774: src.checkSecurity(null, false);
775: }
776: if ((availinfo & ImageObserver.ERROR) != 0) {
777: if (iw != null) {
778: iw.imageUpdate(image, ImageObserver.ERROR
779: | ImageObserver.ABORT, -1, -1, -1, -1);
780: }
781: return false;
782: }
783: boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
784: boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
785:
786: if (!done && !abort) {
787: addWatcher(iw);
788: startProduction();
789: // Some producers deliver image data synchronously
790: done = ((availinfo & ImageObserver.ALLBITS) != 0);
791: }
792:
793: if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
794: g.drawImage(bimage, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
795: bg, null);
796: }
797:
798: return done;
799: }
800:
801: public boolean drawToBufImage(Graphics g, ToolkitImage img,
802: AffineTransform xform, ImageObserver iw) {
803: Graphics2D g2 = (Graphics2D) g;
804:
805: if (src != null) {
806: src.checkSecurity(null, false);
807: }
808: if ((availinfo & ImageObserver.ERROR) != 0) {
809: if (iw != null) {
810: iw.imageUpdate(image, ImageObserver.ERROR
811: | ImageObserver.ABORT, -1, -1, -1, -1);
812: }
813: return false;
814: }
815: boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
816: boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
817:
818: if (!done && !abort) {
819: addWatcher(iw);
820: startProduction();
821: // Some producers deliver image data synchronously
822: done = ((availinfo & ImageObserver.ALLBITS) != 0);
823: }
824:
825: if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
826: g2.drawImage(bimage, xform, null);
827: }
828:
829: return done;
830: }
831:
832: synchronized void abort() {
833: image.getSource().removeConsumer(this );
834: consuming = false;
835: newbits = null;
836: bimage = null;
837: biRaster = null;
838: cmodel = null;
839: srcLUT = null;
840: isDefaultBI = false;
841: isSameCM = false;
842:
843: newInfo(image, ImageObserver.ABORT, -1, -1, -1, -1);
844: availinfo &= ~(ImageObserver.SOMEBITS | ImageObserver.FRAMEBITS
845: | ImageObserver.ALLBITS | ImageObserver.ERROR);
846: }
847:
848: synchronized void dispose() {
849: image.getSource().removeConsumer(this );
850: consuming = false;
851: newbits = null;
852: availinfo &= ~(ImageObserver.SOMEBITS | ImageObserver.FRAMEBITS | ImageObserver.ALLBITS);
853: }
854:
855: public void setAccelerationPriority(float priority) {
856: if (bimage != null) {
857: bimage.setAccelerationPriority(priority);
858: }
859: }
860: }
|