Package org.apache.harmony.awt.gl.image

Source Code of org.apache.harmony.awt.gl.image.OffscreenImage

/*
*  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
*/
/*
* Created on 22.12.2004
*
*/
package org.apache.harmony.awt.gl.image;

import java.util.ConcurrentModificationException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import org.apache.harmony.awt.gl.ImageSurface;
import org.apache.harmony.awt.internal.nls.Messages;

import com.jgraph.gaeawt.java.awt.Graphics;
import com.jgraph.gaeawt.java.awt.Image;
import com.jgraph.gaeawt.java.awt.image.BufferedImage;
import com.jgraph.gaeawt.java.awt.image.ColorModel;
import com.jgraph.gaeawt.java.awt.image.ImageConsumer;
import com.jgraph.gaeawt.java.awt.image.ImageObserver;
import com.jgraph.gaeawt.java.awt.image.ImageProducer;
import com.jgraph.gaeawt.java.awt.image.WritableRaster;

/**
* This class represent implementation of abstact Image class
*/
public class OffscreenImage extends Image implements ImageConsumer
{

  static final ColorModel rgbCM = ColorModel.getRGBdefault();

  ImageProducer src;

  BufferedImage image;

  ColorModel cm;

  WritableRaster raster;

  boolean isIntRGB;

  Hashtable<?, ?> properties;

  Vector<ImageObserver> observers;

  int width;

  int height;

  int imageState;

  int hints;

  private boolean producing;

  private boolean done;

  private ImageSurface imageSurf;

  public OffscreenImage(ImageProducer ip)
  {
    imageState = 0;
    src = ip;
    width = -1;
    height = -1;
    observers = new Vector<ImageObserver>();
    producing = false;
    done = false;
  }

  @Override
  public Object getProperty(String name, ImageObserver observer)
  {
    if (name == null)
    {
      // awt.38=Property name is not defined
      throw new NullPointerException(Messages.getString("awt.38")); //$NON-NLS-1$
    }
    if (!done && properties == null)
    {
      startProduction(observer);
    }
    if (properties == null)
    {
      return null;
    }
    Object prop = properties.get(name);
    if (prop == null)
    {
      prop = UndefinedProperty;
    }
    return prop;
  }

  @Override
  public ImageProducer getSource()
  {
    return src;
  }

  @Override
  public int getWidth(ImageObserver observer)
  {
    if (!done && (imageState & ImageObserver.WIDTH) == 0)
    {
      startProduction(observer);
    }
    return width;
  }

  @Override
  public int getHeight(ImageObserver observer)
  {
    if (!done && (imageState & ImageObserver.HEIGHT) == 0)
    {
      startProduction(observer);
    }
    return height;
  }

  @Override
  public Graphics getGraphics()
  {
    // awt.39=This method is not implemented for image obtained from ImageProducer
    throw new UnsupportedOperationException(Messages.getString("awt.39")); //$NON-NLS-1$
  }

  @Override
  public void flush()
  {
    imageUpdate(ImageObserver.ABORT, -1, -1, -1, -1);
    synchronized (this)
    {
      imageState = 0;
      image = null;
      imageSurf = null;
      cm = null;
      raster = null;
      hints = 0;
      width = -1;
      height = -1;
    }
  }

  public void setProperties(Hashtable<?, ?> properties)
  {
    synchronized (this)
    {
      this.properties = properties;
    }
    imageUpdate(ImageObserver.PROPERTIES);
  }

  public synchronized void setColorModel(ColorModel cm)
  {
    this.cm = cm;
  }

  /*
   * We suppose what in case loading JPEG image then image has DirectColorModel
   * and for infill image Raster will use setPixels method with int array.
   *
   * In case loading GIF image, for raster infill, is used setPixels method with
   * byte array and Color Model is IndexColorModel. But Color Model may
   * be changed during this process. Then is called setPixels method with
   * int array and image force to default color model - int ARGB. The rest
   * pixels are sending in DirectColorModel.
   */
  public void setPixels(int x, int y, int w, int h, ColorModel model,
      int[] pixels, int off, int scansize)
  {

    if (raster == null)
    {
      if (cm == null)
      {
        if (model == null)
        {
          // awt.3A=Color Model is null
          throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
        }
        cm = model;
      }
      createRaster();
    }

    if (model == null)
    {
      model = cm;
    }
    if (cm != model)
    {
      forceToIntARGB();
    }

    int[] db = raster.getDataBuffer();
    int[] surfData = db;

    synchronized (surfData)
    {
      if (cm == model && raster.getNumDataElements() == 1)
      {

        int data[] = surfData;
        int scanline = raster.getWidth();
        int rof = y * scanline + x;
        for (int lineOff = off, line = y; line < y + h; line++, lineOff += scansize, rof += scanline)
        {

          System.arraycopy(pixels, lineOff, data, rof, w);
        }

      }
      else if (isIntRGB)
      {
        int buff[] = new int[w];
        int data[] = surfData;
        int scanline = raster.getWidth();
        int rof = y * scanline + x;
        for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize, rof += scanline)
        {

          for (int sx = x, idx = 0; sx < x + w; sx++, idx++)
          {
            buff[idx] = pixels[sOff + idx];
          }
          System.arraycopy(buff, 0, data, rof, w);
        }
      }
      else
      {
        int buf;
        for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize)
        {
          for (int sx = x, idx = 0; sx < x + w; sx++, idx++)
          {
            int rgb = pixels[sOff + idx];
            buf = rgb;
            raster.setDataElements(sx, sy, buf);
          }
        }
      }
    }

    imageUpdate(ImageObserver.SOMEBITS);
  }

  public void setPixels(int x, int y, int w, int h, ColorModel model,
      byte[] pixels, int off, int scansize)
  {
    if (raster == null)
    {
      if (cm == null)
      {
        if (model == null)
        {
          // awt.3A=Color Model is null
          throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
        }
        cm = model;
      }
      createRaster();
    }
    if (model == null)
    {
      model = cm;
    }
    if (model != cm && cm != rgbCM)
    {
      forceToIntARGB();
    }

    int[] db = raster.getDataBuffer();
    int[] surfData = db;

    synchronized (surfData)
    {
      if (isIntRGB)
      {
        int buff[] = new int[w];
        int data[] = surfData;
        int scanline = raster.getWidth();
        int rof = + y * scanline + x;

        for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize, rof += scanline)
        {
          for (int sx = x, idx = 0; sx < x + w; sx++, idx++)
          {
            buff[idx] = pixels[sOff + idx] & 0xff;
          }
          System.arraycopy(buff, 0, data, rof, w);
        }
      }

      for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize)
      {
        for (int sx = x, idx = 0; sx < x + w; sx++, idx++)
        {
          int rgb = pixels[sOff + idx] & 0xff;
          raster.setDataElements(sx, sy, rgb);
        }
      }
    }

    imageUpdate(ImageObserver.SOMEBITS);
  }

  public void setDimensions(int width, int height)
  {
    if (width <= 0 || height <= 0)
    {
      imageComplete(IMAGEERROR);
      return;
    }
    synchronized (this)
    {
      this.width = width;
      this.height = height;
    }
    imageUpdate(ImageObserver.WIDTH | ImageObserver.HEIGHT);

  }

  public void setHints(int hints)
  {
    synchronized (this)
    {
      this.hints = hints;
    }
  }

  public void imageComplete(int state)
  {
    int flag;
    switch (state)
    {
      case IMAGEABORTED:
        flag = ImageObserver.ABORT;
        break;
      case IMAGEERROR:
        flag = ImageObserver.ERROR | ImageObserver.ABORT;
        break;
      case SINGLEFRAMEDONE:
        flag = ImageObserver.FRAMEBITS;
        break;
      case STATICIMAGEDONE:
        flag = ImageObserver.ALLBITS;
        break;
      default:
        // awt.3B=Incorrect ImageConsumer completion status
        throw new IllegalArgumentException(Messages.getString("awt.3B")); //$NON-NLS-1$
    }

    imageUpdate(flag);
    if ((imageState & (ImageObserver.ERROR | ImageObserver.ABORT | ImageObserver.ALLBITS)) != 0)
    {

      stopProduction();
    }

  }

  public BufferedImage getBufferedImage()
  {
    if (image == null)
    {
      ColorModel model = getColorModel();
      WritableRaster wr = getRaster();
      if (model != null && wr != null)
      {
        image = new BufferedImage(model, wr, null);
      }
    }
    return image;
  }

  public int checkImage(ImageObserver observer)
  {
    synchronized (this)
    {
      addObserver(observer);
    }
    return imageState;
  }

  public boolean prepareImage(ImageObserver observer)
  {
    if (!done)
    {
      if ((imageState & ImageObserver.ERROR) != 0)
      {
        if (observer != null)
        {
          observer.imageUpdate(this, ImageObserver.ERROR
              | ImageObserver.ABORT, -1, -1, -1, -1);
        }
        return false;
      }
      startProduction(observer);
    }

    return ((imageState & ImageObserver.ALLBITS) != 0);
  }

  public ColorModel getColorModel()
  {
    if (cm == null)
    {
      startProduction(null);
    }
    return cm;
  }

  public WritableRaster getRaster()
  {
    if (raster == null)
    {
      startProduction(null);
    }
    return raster;
  }

  public int getState()
  {
    return imageState;
  }

  private void addObserver(ImageObserver observer)
  {
    if (observer != null)
    {
      if (observers.contains(observer))
        return;

      if ((imageState & ImageObserver.ERROR) != 0)
      {
        observer.imageUpdate(this, ImageObserver.ERROR
            | ImageObserver.ABORT, -1, -1, -1, -1);

        return;
      }

      if ((imageState & ImageObserver.ALLBITS) != 0)
      {
        observer.imageUpdate(this, imageState, 0, 0, width, height);

        return;
      }
      synchronized (observers)
      {
        observers.add(observer);
      }
    }
  }

  private void startProduction(ImageObserver observer)
  {
    addObserver(observer);
    if (!producing && !done)
    {
      synchronized (this)
      {
        imageState &= ~ImageObserver.ABORT;
        producing = true;
        src.startProduction(this);
      }
    }
  }

  private synchronized void stopProduction()
  {
    producing = false;
    src.removeConsumer(this);
    synchronized (observers)
    {
      observers.clear();
    }
  }

  private void createRaster()
  {
    try
    {
      raster = cm.createCompatibleWritableRaster(width, height);
      isIntRGB = true;
    }
    catch (Exception e)
    {
      cm = ColorModel.getRGBdefault();
      raster = cm.createCompatibleWritableRaster(width, height);
      isIntRGB = true;
    }
  }

  private void imageUpdate(int state)
  {
    imageUpdate(state, 0, 0, width, height);
  }

  private void imageUpdate(int state, int x, int y, int width, int height)
  {
    synchronized (this)
    {
      imageState |= state;
      if ((imageState & (ImageObserver.ALLBITS)) != 0)
      {
        done = true;
      }
    }
    ImageObserver observer = null;

    for (Iterator<ImageObserver> i = observers.iterator(); i.hasNext();)
    {
      try
      {
        observer = i.next();
      }
      catch (ConcurrentModificationException e)
      {
        i = observers.iterator();
        continue;
      }
      observer.imageUpdate(this, imageState, x, y, width, height);
    }

  }

  private void forceToIntARGB()
  {

    int w = raster.getWidth();
    int h = raster.getHeight();

    WritableRaster destRaster = rgbCM.createCompatibleWritableRaster(w, h);

    int pixels[] = new int[w];

    for (int y = 0; y < h; y++)
    {
      for (int x = 0; x < w; x++)
      {
        pixels[x] = raster.getDataElements(x, y);
      }
      destRaster.setDataElements(0, y, w, 1, pixels);
    }

    synchronized (this)
    {
      if (imageSurf != null)
      {
        imageSurf.dispose();
        imageSurf = null;
      }
      if (image != null)
      {
        image.flush();
        image = null;
      }
      cm = rgbCM;
      raster = destRaster;
      isIntRGB = true;
    }
  }

  public ImageSurface getImageSurface()
  {
    if (imageSurf == null)
    {
      ColorModel model = getColorModel();
      WritableRaster wr = getRaster();
      if (model != null && wr != null)
      {
        imageSurf = new ImageSurface(model, wr);
      }
    }
    return imageSurf;
  }
}
TOP

Related Classes of org.apache.harmony.awt.gl.image.OffscreenImage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.