0N/A/*
3261N/A * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.image;
0N/A
0N/Aimport java.awt.Color;
0N/Aimport java.awt.Graphics;
0N/Aimport java.awt.Transparency;
0N/Aimport java.awt.AWTException;
0N/Aimport java.awt.Rectangle;
0N/Aimport java.awt.image.BufferedImage;
0N/Aimport java.awt.image.ColorModel;
0N/Aimport java.awt.image.DirectColorModel;
0N/Aimport java.awt.image.IndexColorModel;
0N/Aimport java.awt.image.ImageConsumer;
0N/Aimport java.awt.image.ImageObserver;
0N/Aimport sun.awt.image.ByteComponentRaster;
0N/Aimport sun.awt.image.IntegerComponentRaster;
0N/Aimport java.awt.image.Raster;
0N/Aimport java.awt.image.WritableRaster;
0N/Aimport java.awt.image.DataBuffer;
0N/Aimport java.awt.image.DataBufferInt;
0N/Aimport java.awt.Graphics2D;
0N/Aimport java.awt.geom.AffineTransform;
0N/Aimport sun.awt.image.ImageWatched;
0N/Aimport java.util.Hashtable;
0N/A
0N/Apublic class ImageRepresentation extends ImageWatched implements ImageConsumer
0N/A{
0N/A InputStreamImageSource src;
0N/A ToolkitImage image;
0N/A int tag;
0N/A
0N/A long pData; // used by windows native code only -- internal state REMIND ATTN @@
0N/A
0N/A int width = -1;
0N/A int height = -1;
0N/A int hints;
0N/A
0N/A int availinfo;
0N/A
0N/A Rectangle newbits;
0N/A
0N/A BufferedImage bimage;
0N/A WritableRaster biRaster;
0N/A protected ColorModel cmodel;
0N/A ColorModel srcModel = null;
0N/A int[] srcLUT = null;
0N/A int srcLUTtransIndex = -1;
0N/A int numSrcLUT = 0;
0N/A boolean forceCMhint;
0N/A int sstride;
0N/A boolean isDefaultBI = false;
0N/A boolean isSameCM = false;
0N/A
0N/A private native static void initIDs();
0N/A
0N/A static {
0N/A /* ensure that the necessary native libraries are loaded */
0N/A NativeLibLoader.loadLibraries();
0N/A initIDs();
0N/A }
0N/A
0N/A /**
0N/A * Create an ImageRepresentation for the given Image. The
0N/A * width and height are unknown at this point. The color
0N/A * model is a hint as to the color model to use when creating
0N/A * the buffered image. If null, the src color model will
0N/A * be used.
0N/A */
0N/A public ImageRepresentation(ToolkitImage im, ColorModel cmodel, boolean
0N/A forceCMhint) {
0N/A image = im;
0N/A
0N/A if (image.getSource() instanceof InputStreamImageSource) {
0N/A src = (InputStreamImageSource) image.getSource();
0N/A }
0N/A
0N/A setColorModel(cmodel);
0N/A
0N/A this.forceCMhint = forceCMhint;
0N/A }
0N/A
0N/A /* REMIND: Only used for Frame.setIcon - should use ImageWatcher instead */
0N/A public synchronized void reconstruct(int flags) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A int missinginfo = flags & ~availinfo;
0N/A if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) {
0N/A numWaiters++;
0N/A try {
0N/A startProduction();
0N/A missinginfo = flags & ~availinfo;
0N/A while ((availinfo & ImageObserver.ERROR) == 0 &&
0N/A missinginfo != 0)
0N/A {
0N/A try {
0N/A wait();
0N/A } catch (InterruptedException e) {
0N/A Thread.currentThread().interrupt();
0N/A return;
0N/A }
0N/A missinginfo = flags & ~availinfo;
0N/A }
0N/A } finally {
0N/A decrementWaiters();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void setDimensions(int w, int h) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A
0N/A image.setDimensions(w, h);
0N/A
0N/A newInfo(image, (ImageObserver.WIDTH | ImageObserver.HEIGHT),
0N/A 0, 0, w, h);
0N/A
0N/A if (w <= 0 || h <= 0) {
0N/A imageComplete(ImageConsumer.IMAGEERROR);
0N/A return;
0N/A }
0N/A
0N/A if (width != w || height != h) {
0N/A // dimension mismatch => trigger recreation of the buffer
0N/A bimage = null;
0N/A }
0N/A
0N/A width = w;
0N/A height = h;
0N/A
0N/A availinfo |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
0N/A }
0N/A
0N/A public int getWidth() {
0N/A return width;
0N/A }
0N/A
0N/A public int getHeight() {
0N/A return height;
0N/A }
0N/A
0N/A ColorModel getColorModel() {
0N/A return cmodel;
0N/A }
0N/A
0N/A BufferedImage getBufferedImage() {
0N/A return bimage;
0N/A }
0N/A
0N/A /**
0N/A * Returns the BufferedImage that will be used as the representation of
0N/A * the pixel data. Subclasses can override this method to return
0N/A * platform specific subclasses of BufferedImage that may or may not be
0N/A * accelerated.
0N/A *
0N/A * It is subclass' responsibility to propagate acceleration priority
0N/A * to the newly created image.
0N/A */
0N/A protected BufferedImage createImage(ColorModel cm,
0N/A WritableRaster raster,
0N/A boolean isRasterPremultiplied,
0N/A Hashtable properties)
0N/A {
0N/A BufferedImage bi =
0N/A new BufferedImage(cm, raster, isRasterPremultiplied, null);
0N/A bi.setAccelerationPriority(image.getAccelerationPriority());
0N/A return bi;
0N/A }
0N/A
0N/A public void setProperties(Hashtable<?,?> props) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A image.setProperties(props);
0N/A newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0);
0N/A }
0N/A
0N/A public void setColorModel(ColorModel model) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A srcModel = model;
0N/A
0N/A // Check to see if model is INT_RGB
0N/A if (model instanceof IndexColorModel) {
0N/A if (model.getTransparency() == model.TRANSLUCENT) {
0N/A // REMIND:
0N/A // Probably need to composite anyway so force ARGB
0N/A cmodel = ColorModel.getRGBdefault();
0N/A srcLUT = null;
0N/A }
0N/A else {
0N/A IndexColorModel icm = (IndexColorModel) model;
0N/A numSrcLUT = icm.getMapSize();
0N/A srcLUT = new int[Math.max(numSrcLUT, 256)];
0N/A icm.getRGBs(srcLUT);
0N/A srcLUTtransIndex = icm.getTransparentPixel();
0N/A cmodel = model;
0N/A }
0N/A }
0N/A else {
0N/A if (cmodel == null) {
0N/A cmodel = model;
0N/A srcLUT = null;
0N/A }
0N/A else if (model instanceof DirectColorModel) {
0N/A // If it is INT_RGB or INT_ARGB, use the model
0N/A DirectColorModel dcm = (DirectColorModel) model;
0N/A if ((dcm.getRedMask() == 0xff0000) &&
0N/A (dcm.getGreenMask() == 0xff00) &&
0N/A (dcm.getBlueMask() == 0x00ff)) {
0N/A cmodel = model;
0N/A srcLUT = null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A isSameCM = (cmodel == model);
0N/A }
0N/A
0N/A void createBufferedImage() {
0N/A // REMIND: Be careful! Is this called everytime there is a
0N/A // startProduction? We only want to call it if it is new or
0N/A // there is an error
0N/A isDefaultBI = false;
0N/A try {
0N/A biRaster = cmodel.createCompatibleWritableRaster(width, height);
0N/A bimage = createImage(cmodel, biRaster,
0N/A cmodel.isAlphaPremultiplied(), null);
0N/A } catch (Exception e) {
0N/A // Create a default image
0N/A cmodel = ColorModel.getRGBdefault();
0N/A biRaster = cmodel.createCompatibleWritableRaster(width, height);
0N/A bimage = createImage(cmodel, biRaster, false, null);
0N/A }
0N/A int type = bimage.getType();
0N/A
0N/A if ((cmodel == ColorModel.getRGBdefault()) ||
0N/A (type == BufferedImage.TYPE_INT_RGB) ||
0N/A (type == BufferedImage.TYPE_INT_ARGB_PRE)) {
0N/A isDefaultBI = true;
0N/A }
0N/A else if (cmodel instanceof DirectColorModel) {
0N/A DirectColorModel dcm = (DirectColorModel) cmodel;
0N/A if (dcm.getRedMask() == 0xff0000 &&
0N/A dcm.getGreenMask() == 0xff00 &&
0N/A dcm.getBlueMask() == 0xff) {
0N/A isDefaultBI = true;
0N/A }
0N/A }
0N/A }
0N/A
0N/A private void convertToRGB() {
0N/A int w = bimage.getWidth();
0N/A int h = bimage.getHeight();
0N/A int size = w*h;
0N/A
0N/A DataBufferInt dbi = new DataBufferInt(size);
0N/A // Note that stealData() requires a markDirty() afterwards
0N/A // since we modify the data in it.
0N/A int newpixels[] = SunWritableRaster.stealData(dbi, 0);
0N/A if (cmodel instanceof IndexColorModel &&
0N/A biRaster instanceof ByteComponentRaster &&
0N/A biRaster.getNumDataElements() == 1)
0N/A {
0N/A ByteComponentRaster bct = (ByteComponentRaster) biRaster;
0N/A byte[] data = bct.getDataStorage();
0N/A int coff = bct.getDataOffset(0);
0N/A for (int i=0; i < size; i++) {
0N/A newpixels[i] = srcLUT[data[coff+i]&0xff];
0N/A }
0N/A }
0N/A else {
0N/A Object srcpixels = null;
0N/A int off=0;
0N/A for (int y=0; y < h; y++) {
0N/A for (int x=0; x < w; x++) {
0N/A srcpixels=biRaster.getDataElements(x, y, srcpixels);
0N/A newpixels[off++] = cmodel.getRGB(srcpixels);
0N/A }
0N/A }
0N/A }
0N/A // We modified the data array directly above so mark it as dirty now...
0N/A SunWritableRaster.markDirty(dbi);
0N/A
0N/A isSameCM = false;
0N/A cmodel = ColorModel.getRGBdefault();
0N/A
0N/A int bandMasks[] = {0x00ff0000,
0N/A 0x0000ff00,
0N/A 0x000000ff,
0N/A 0xff000000};
0N/A
0N/A biRaster = Raster.createPackedRaster(dbi,w,h,w,
0N/A bandMasks,null);
0N/A
0N/A bimage = createImage(cmodel, biRaster,
0N/A cmodel.isAlphaPremultiplied(), null);
0N/A srcLUT = null;
0N/A isDefaultBI = true;
0N/A }
0N/A
0N/A public void setHints(int h) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A hints = h;
0N/A }
0N/A
5896N/A private native boolean setICMpixels(int x, int y, int w, int h, int[] lut,
0N/A byte[] pix, int off, int scansize,
0N/A IntegerComponentRaster ict);
5896N/A private native boolean setDiffICM(int x, int y, int w, int h, int[] lut,
0N/A int transPix, int numLut, IndexColorModel icm,
0N/A byte[] pix, int off, int scansize,
0N/A ByteComponentRaster bct, int chanOff);
0N/A static boolean s_useNative = true;
0N/A
0N/A public void setPixels(int x, int y, int w, int h,
0N/A ColorModel model,
0N/A byte pix[], int off, int scansize) {
0N/A int lineOff=off;
0N/A int poff;
0N/A int[] newLUT=null;
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A
0N/A // REMIND: What if the model doesn't fit in default color model?
0N/A synchronized (this) {
0N/A if (bimage == null) {
0N/A if (cmodel == null) {
0N/A cmodel = model;
0N/A }
0N/A createBufferedImage();
0N/A }
2267N/A
2267N/A if (w <= 0 || h <= 0) {
2267N/A return;
2267N/A }
2267N/A
2267N/A int biWidth = biRaster.getWidth();
2267N/A int biHeight = biRaster.getHeight();
2267N/A
2267N/A int x1 = x+w; // Overflow protection below
2267N/A int y1 = y+h; // Overflow protection below
2267N/A if (x < 0) {
2267N/A off -= x;
2267N/A x = 0;
2267N/A } else if (x1 < 0) {
2267N/A x1 = biWidth; // Must be overflow
2267N/A }
2267N/A if (y < 0) {
2267N/A off -= y*scansize;
2267N/A y = 0;
2267N/A } else if (y1 < 0) {
2267N/A y1 = biHeight; // Must be overflow
2267N/A }
2267N/A if (x1 > biWidth) {
2267N/A x1 = biWidth;
2267N/A }
2267N/A if (y1 > biHeight) {
2267N/A y1 = biHeight;
2267N/A }
2267N/A if (x >= x1 || y >= y1) {
2267N/A return;
2267N/A }
2267N/A // x,y,x1,y1 are all >= 0, so w,h must be >= 0
2267N/A w = x1-x;
2267N/A h = y1-y;
2267N/A // off is first pixel read so it must be in bounds
2267N/A if (off < 0 || off >= pix.length) {
2267N/A // They overflowed their own array
2267N/A throw new ArrayIndexOutOfBoundsException("Data offset out of bounds.");
2267N/A }
2267N/A // pix.length and off are >= 0 so remainder >= 0
2267N/A int remainder = pix.length - off;
2267N/A if (remainder < w) {
2267N/A // They overflowed their own array
2267N/A throw new ArrayIndexOutOfBoundsException("Data array is too short.");
2267N/A }
2267N/A int num;
2267N/A if (scansize < 0) {
2267N/A num = (off / -scansize) + 1;
2267N/A } else if (scansize > 0) {
2267N/A num = ((remainder-w) / scansize) + 1;
2267N/A } else {
2267N/A num = h;
2267N/A }
2267N/A if (h > num) {
2267N/A // They overflowed their own array.
2267N/A throw new ArrayIndexOutOfBoundsException("Data array is too short.");
2267N/A }
2267N/A
0N/A if (isSameCM && (cmodel != model) && (srcLUT != null) &&
0N/A (model instanceof IndexColorModel) &&
0N/A (biRaster instanceof ByteComponentRaster))
0N/A {
0N/A IndexColorModel icm = (IndexColorModel) model;
0N/A ByteComponentRaster bct = (ByteComponentRaster) biRaster;
0N/A int numlut = numSrcLUT;
5896N/A if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
0N/A numSrcLUT, icm,
0N/A pix, off, scansize, bct,
5896N/A bct.getDataOffset(0))) {
0N/A convertToRGB();
0N/A }
0N/A else {
0N/A // Note that setDiffICM modified the raster directly
0N/A // so we must mark it as changed
0N/A bct.markDirty();
0N/A if (numlut != numSrcLUT) {
0N/A boolean hasAlpha = icm.hasAlpha();
0N/A if (srcLUTtransIndex != -1) {
0N/A hasAlpha = true;
0N/A }
0N/A int nbits = icm.getPixelSize();
0N/A icm = new IndexColorModel(nbits,
0N/A numSrcLUT, srcLUT,
0N/A 0, hasAlpha,
0N/A srcLUTtransIndex,
0N/A (nbits > 8
0N/A ? DataBuffer.TYPE_USHORT
0N/A : DataBuffer.TYPE_BYTE));
0N/A cmodel = icm;
0N/A bimage = createImage(icm, bct, false, null);
0N/A }
0N/A return;
0N/A }
0N/A }
0N/A
0N/A if (isDefaultBI) {
0N/A int pixel;
0N/A IntegerComponentRaster iraster =
0N/A (IntegerComponentRaster) biRaster;
0N/A if (srcLUT != null && model instanceof IndexColorModel) {
0N/A if (model != srcModel) {
0N/A // Fill in the new lut
0N/A ((IndexColorModel)model).getRGBs(srcLUT);
0N/A srcModel = model;
0N/A }
0N/A
0N/A if (s_useNative) {
0N/A // Note that setICMpixels modifies the raster directly
0N/A // so we must mark it as changed afterwards
5896N/A if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
5896N/A iraster))
5896N/A {
5896N/A iraster.markDirty();
5896N/A } else {
5896N/A abort();
5896N/A return;
5896N/A }
0N/A }
0N/A else {
0N/A int[] storage = new int[w*h];
0N/A int soff = 0;
0N/A // It is an IndexColorModel
0N/A for (int yoff=0; yoff < h; yoff++,
0N/A lineOff += scansize) {
0N/A poff = lineOff;
0N/A for (int i=0; i < w; i++) {
0N/A storage[soff++] = srcLUT[pix[poff++]&0xff];
0N/A }
0N/A }
0N/A iraster.setDataElements(x, y, w, h, storage);
0N/A }
0N/A }
0N/A else {
0N/A int[] storage = new int[w];
0N/A for (int yoff=y; yoff < y+h; yoff++, lineOff += scansize) {
0N/A poff = lineOff;
0N/A for (int i=0; i < w; i++) {
0N/A storage[i] = model.getRGB(pix[poff++]&0xff);
0N/A }
0N/A iraster.setDataElements(x, yoff, w, 1, storage);
0N/A }
0N/A availinfo |= ImageObserver.SOMEBITS;
0N/A }
0N/A }
0N/A else if ((cmodel == model) &&
0N/A (biRaster instanceof ByteComponentRaster) &&
0N/A (biRaster.getNumDataElements() == 1)){
0N/A ByteComponentRaster bt = (ByteComponentRaster) biRaster;
1841N/A if (off == 0 && scansize == w) {
1841N/A bt.putByteData(x, y, w, h, pix);
0N/A }
0N/A else {
1841N/A byte[] bpix = new byte[w];
1841N/A poff = off;
1841N/A for (int yoff=y; yoff < y+h; yoff++) {
1841N/A System.arraycopy(pix, poff, bpix, 0, w);
1841N/A bt.putByteData(x, yoff, w, 1, bpix);
1841N/A poff += scansize;
1841N/A }
0N/A }
0N/A }
0N/A else {
0N/A for (int yoff=y; yoff < y+h; yoff++, lineOff += scansize) {
0N/A poff = lineOff;
0N/A for (int xoff=x; xoff < x+w; xoff++) {
0N/A bimage.setRGB(xoff, yoff,
0N/A model.getRGB(pix[poff++]&0xff));
0N/A }
0N/A }
0N/A availinfo |= ImageObserver.SOMEBITS;
0N/A }
0N/A }
0N/A
0N/A if ((availinfo & ImageObserver.FRAMEBITS) == 0) {
0N/A newInfo(image, ImageObserver.SOMEBITS, x, y, w, h);
0N/A }
0N/A }
0N/A
0N/A
0N/A public void setPixels(int x, int y, int w, int h, ColorModel model,
0N/A int pix[], int off, int scansize)
0N/A {
0N/A int lineOff=off;
0N/A int poff;
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A
0N/A // REMIND: What if the model doesn't fit in default color model?
0N/A synchronized (this) {
0N/A if (bimage == null) {
0N/A if (cmodel == null) {
0N/A cmodel = model;
0N/A }
0N/A createBufferedImage();
0N/A }
0N/A
0N/A int[] storage = new int[w];
0N/A int yoff;
0N/A int pixel;
0N/A
0N/A if (cmodel instanceof IndexColorModel) {
0N/A // REMIND: Right now we don't support writing back into ICM
0N/A // images.
0N/A convertToRGB();
0N/A }
0N/A
0N/A if ((model == cmodel) &&
0N/A (biRaster instanceof IntegerComponentRaster)) {
0N/A IntegerComponentRaster iraster =
0N/A (IntegerComponentRaster) biRaster;
0N/A
0N/A if (off == 0 && scansize == w) {
0N/A iraster.setDataElements(x, y, w, h, pix);
0N/A }
0N/A else {
0N/A // Need to pack the data
0N/A for (yoff=y; yoff < y+h; yoff++, lineOff+=scansize) {
0N/A System.arraycopy(pix, lineOff, storage, 0, w);
0N/A iraster.setDataElements(x, yoff, w, 1, storage);
0N/A }
0N/A }
0N/A }
0N/A else {
0N/A if (model.getTransparency() != model.OPAQUE &&
0N/A cmodel.getTransparency() == cmodel.OPAQUE) {
0N/A convertToRGB();
0N/A }
0N/A
0N/A if (isDefaultBI) {
0N/A IntegerComponentRaster iraster =
0N/A (IntegerComponentRaster) biRaster;
0N/A int[] data = iraster.getDataStorage();
0N/A if (cmodel.equals(model)) {
0N/A int sstride = iraster.getScanlineStride();
0N/A int doff = y*sstride + x;
0N/A for (yoff=0; yoff < h; yoff++, lineOff += scansize) {
0N/A System.arraycopy(pix, lineOff, data, doff, w);
0N/A doff += sstride;
0N/A }
0N/A // Note: manual modification of pixels, mark the
0N/A // raster as changed
0N/A iraster.markDirty();
0N/A }
0N/A else {
0N/A for (yoff=y; yoff < y+h; yoff++, lineOff += scansize) {
0N/A poff = lineOff;
0N/A for (int i=0; i < w; i++) {
0N/A storage[i]=model.getRGB(pix[poff++]);
0N/A }
0N/A iraster.setDataElements(x, yoff, w, 1, storage);
0N/A }
0N/A }
0N/A
0N/A availinfo |= ImageObserver.SOMEBITS;
0N/A }
0N/A else {
0N/A Object tmp = null;
0N/A
0N/A for (yoff=y; yoff < y+h; yoff++, lineOff += scansize) {
0N/A poff = lineOff;
0N/A for (int xoff=x; xoff < x+w; xoff++) {
0N/A pixel = model.getRGB(pix[poff++]);
0N/A tmp = cmodel.getDataElements(pixel,tmp);
0N/A biRaster.setDataElements(xoff, yoff,tmp);
0N/A }
0N/A }
0N/A availinfo |= ImageObserver.SOMEBITS;
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Can't do this here since we might need to transform/clip
0N/A // the region
0N/A if (((availinfo & ImageObserver.FRAMEBITS) == 0)) {
0N/A newInfo(image, ImageObserver.SOMEBITS, x, y, w, h);
0N/A }
0N/A }
0N/A
0N/A public BufferedImage getOpaqueRGBImage() {
0N/A if (bimage.getType() == BufferedImage.TYPE_INT_ARGB) {
0N/A int w = bimage.getWidth();
0N/A int h = bimage.getHeight();
0N/A int size = w * h;
0N/A
0N/A // Note that we steal the data array here, but only for reading...
0N/A DataBufferInt db = (DataBufferInt)biRaster.getDataBuffer();
0N/A int[] pixels = SunWritableRaster.stealData(db, 0);
0N/A
0N/A for (int i = 0; i < size; i++) {
0N/A if ((pixels[i] >>> 24) != 0xff) {
0N/A return bimage;
0N/A }
0N/A }
0N/A
0N/A ColorModel opModel = new DirectColorModel(24,
0N/A 0x00ff0000,
0N/A 0x0000ff00,
0N/A 0x000000ff);
0N/A
0N/A int bandmasks[] = {0x00ff0000, 0x0000ff00, 0x000000ff};
0N/A WritableRaster opRaster = Raster.createPackedRaster(db, w, h, w,
0N/A bandmasks,
0N/A null);
0N/A
0N/A try {
0N/A BufferedImage opImage = createImage(opModel, opRaster,
0N/A false, null);
0N/A return opImage;
0N/A } catch (Exception e) {
0N/A return bimage;
0N/A }
0N/A }
0N/A return bimage;
0N/A }
0N/A
0N/A private boolean consuming = false;
0N/A
0N/A public void imageComplete(int status) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A boolean done;
0N/A int info;
0N/A switch (status) {
0N/A default:
0N/A case ImageConsumer.IMAGEABORTED:
0N/A done = true;
0N/A info = ImageObserver.ABORT;
0N/A break;
0N/A case ImageConsumer.IMAGEERROR:
0N/A image.addInfo(ImageObserver.ERROR);
0N/A done = true;
0N/A info = ImageObserver.ERROR;
0N/A dispose();
0N/A break;
0N/A case ImageConsumer.STATICIMAGEDONE:
0N/A done = true;
0N/A info = ImageObserver.ALLBITS;
0N/A break;
0N/A case ImageConsumer.SINGLEFRAMEDONE:
0N/A done = false;
0N/A info = ImageObserver.FRAMEBITS;
0N/A break;
0N/A }
0N/A synchronized (this) {
0N/A if (done) {
0N/A image.getSource().removeConsumer(this);
0N/A consuming = false;
0N/A newbits = null;
0N/A
0N/A if (bimage != null) {
0N/A bimage = getOpaqueRGBImage();
0N/A }
0N/A }
0N/A availinfo |= info;
0N/A notifyAll();
0N/A }
0N/A
0N/A newInfo(image, info, 0, 0, width, height);
0N/A
0N/A image.infoDone(status);
0N/A }
0N/A
0N/A /*synchronized*/ void startProduction() {
0N/A if (!consuming) {
0N/A consuming = true;
0N/A image.getSource().startProduction(this);
0N/A }
0N/A }
0N/A
0N/A private int numWaiters;
0N/A
0N/A private synchronized void checkConsumption() {
0N/A if (isWatcherListEmpty() && numWaiters == 0 &&
0N/A ((availinfo & ImageObserver.ALLBITS) == 0))
0N/A {
0N/A dispose();
0N/A }
0N/A }
0N/A
0N/A public synchronized void notifyWatcherListEmpty() {
0N/A checkConsumption();
0N/A }
0N/A
0N/A private synchronized void decrementWaiters() {
0N/A --numWaiters;
0N/A checkConsumption();
0N/A }
0N/A
0N/A public boolean prepare(ImageObserver iw) {
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & ImageObserver.ERROR) != 0) {
0N/A if (iw != null) {
0N/A iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A if (!done) {
0N/A addWatcher(iw);
0N/A startProduction();
0N/A // Some producers deliver image data synchronously
0N/A done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A }
0N/A return done;
0N/A }
0N/A
0N/A public int check(ImageObserver iw) {
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) {
0N/A addWatcher(iw);
0N/A }
0N/A
0N/A return availinfo;
0N/A }
0N/A
0N/A public boolean drawToBufImage(Graphics g, ToolkitImage img,
0N/A int x, int y, Color bg,
0N/A ImageObserver iw) {
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & ImageObserver.ERROR) != 0) {
0N/A if (iw != null) {
0N/A iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
0N/A
0N/A if (!done && !abort) {
0N/A addWatcher(iw);
0N/A startProduction();
0N/A // Some producers deliver image data synchronously
0N/A done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A }
0N/A
0N/A if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
0N/A g.drawImage (bimage, x, y, bg, null);
0N/A }
0N/A
0N/A return done;
0N/A }
0N/A
0N/A public boolean drawToBufImage(Graphics g, ToolkitImage img,
0N/A int x, int y, int w, int h,
0N/A Color bg, ImageObserver iw) {
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & ImageObserver.ERROR) != 0) {
0N/A if (iw != null) {
0N/A iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
0N/A
0N/A if (!done && !abort) {
0N/A addWatcher(iw);
0N/A startProduction();
0N/A // Some producers deliver image data synchronously
0N/A done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A }
0N/A
0N/A if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
0N/A g.drawImage (bimage, x, y, w, h, bg, null);
0N/A }
0N/A
0N/A return done;
0N/A }
0N/A
0N/A public boolean drawToBufImage(Graphics g, ToolkitImage img,
0N/A int dx1, int dy1, int dx2, int dy2,
0N/A int sx1, int sy1, int sx2, int sy2,
0N/A Color bg, ImageObserver iw) {
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & ImageObserver.ERROR) != 0) {
0N/A if (iw != null) {
0N/A iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
0N/A
0N/A if (!done && !abort) {
0N/A addWatcher(iw);
0N/A startProduction();
0N/A // Some producers deliver image data synchronously
0N/A done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A }
0N/A
0N/A if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
0N/A g.drawImage (bimage,
0N/A dx1, dy1, dx2, dy2,
0N/A sx1, sy1, sx2, sy2,
0N/A bg, null);
0N/A }
0N/A
0N/A return done;
0N/A }
0N/A
0N/A public boolean drawToBufImage(Graphics g, ToolkitImage img,
0N/A AffineTransform xform,
0N/A ImageObserver iw)
0N/A {
0N/A Graphics2D g2 = (Graphics2D) g;
0N/A
0N/A if (src != null) {
0N/A src.checkSecurity(null, false);
0N/A }
0N/A if ((availinfo & ImageObserver.ERROR) != 0) {
0N/A if (iw != null) {
0N/A iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A boolean done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A boolean abort = ((availinfo & ImageObserver.ABORT) != 0);
0N/A
0N/A if (!done && !abort) {
0N/A addWatcher(iw);
0N/A startProduction();
0N/A // Some producers deliver image data synchronously
0N/A done = ((availinfo & ImageObserver.ALLBITS) != 0);
0N/A }
0N/A
0N/A if (done || (0 != (availinfo & ImageObserver.FRAMEBITS))) {
0N/A g2.drawImage (bimage, xform, null);
0N/A }
0N/A
0N/A return done;
0N/A }
0N/A
0N/A synchronized void abort() {
0N/A image.getSource().removeConsumer(this);
0N/A consuming = false;
0N/A newbits = null;
0N/A bimage = null;
0N/A biRaster = null;
0N/A cmodel = null;
0N/A srcLUT = null;
0N/A isDefaultBI = false;
0N/A isSameCM = false;
0N/A
0N/A newInfo(image, ImageObserver.ABORT, -1, -1, -1, -1);
0N/A availinfo &= ~(ImageObserver.SOMEBITS
0N/A | ImageObserver.FRAMEBITS
0N/A | ImageObserver.ALLBITS
0N/A | ImageObserver.ERROR);
0N/A }
0N/A
0N/A synchronized void dispose() {
0N/A image.getSource().removeConsumer(this);
0N/A consuming = false;
0N/A newbits = null;
0N/A availinfo &= ~(ImageObserver.SOMEBITS
0N/A | ImageObserver.FRAMEBITS
0N/A | ImageObserver.ALLBITS);
0N/A }
0N/A
0N/A public void setAccelerationPriority(float priority) {
0N/A if (bimage != null) {
0N/A bimage.setAccelerationPriority(priority);
0N/A }
0N/A }
0N/A}