summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/image/PixelGrabber.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/java/awt/image/PixelGrabber.java')
-rw-r--r--awt/java/awt/image/PixelGrabber.java408
1 files changed, 408 insertions, 0 deletions
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
new file mode 100644
index 0000000..cecd5c8
--- /dev/null
+++ b/awt/java/awt/image/PixelGrabber.java
@@ -0,0 +1,408 @@
+/*
+ * 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
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PixelGrabber implements ImageConsumer {
+
+ int width;
+ int height;
+ int X;
+ int Y;
+ int offset;
+ int scanline;
+ ImageProducer producer;
+
+ byte bData[];
+ int iData[];
+ ColorModel cm;
+
+ private int grabberStatus;
+ private int dataType;
+ private boolean isGrabbing;
+ private boolean isRGB;
+
+
+ private static final int DATA_TYPE_BYTE = 0;
+ private static final int DATA_TYPE_INT = 1;
+ private static final int DATA_TYPE_UNDEFINED = 2;
+
+ private static final int ALL_BITS = (ImageObserver.FRAMEBITS |
+ ImageObserver.ALLBITS);
+
+ private static final int GRABBING_STOP = ALL_BITS | ImageObserver.ERROR;
+
+
+
+ public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix,
+ int off, int scansize) {
+ initialize(ip, x, y, w, h, pix, off, scansize, true);
+ }
+
+ public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix,
+ int off, int scansize) {
+ initialize(img.getSource(), x, y, w, h, pix, off, scansize, true);
+ }
+
+ public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) {
+ initialize(img.getSource(), x, y, w, h, null, 0, 0, forceRGB);
+ }
+
+ public void setProperties(Hashtable<?, ?> props) {
+ return;
+ }
+
+ public synchronized Object getPixels() {
+ switch(dataType){
+ case DATA_TYPE_BYTE:
+ return bData;
+ case DATA_TYPE_INT:
+ return iData;
+ default:
+ return null;
+ }
+ }
+
+ public void setColorModel(ColorModel model) {
+ return;
+ }
+
+ public void setPixels(int srcX, int srcY, int srcW, int srcH,
+ ColorModel model, byte[] pixels, int srcOff, int srcScan) {
+ if(srcY < Y){
+ int delta = Y - srcY;
+ if(delta >= height) {
+ return;
+ }
+ srcY += delta;
+ srcH -= delta;
+ srcOff += srcScan * delta;
+ }
+
+ if(srcY + srcH > Y + height){
+ srcH = Y + height - srcY;
+ if(srcH <= 0) {
+ return;
+ }
+ }
+
+ if(srcX < X){
+ int delta = X - srcX;
+ if(delta >= width) {
+ return;
+ }
+ srcW -= delta;
+ srcX += delta;
+ srcOff += delta;
+ }
+
+ if(srcX + srcW > X + width){
+ srcW = X + width - srcX;
+ if(srcW <= 0) {
+ return;
+ }
+ }
+ if(scanline == 0) {
+ scanline = width;
+ }
+ int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+ switch(dataType){
+ case DATA_TYPE_UNDEFINED:
+ cm = model;
+ if(model != ColorModel.getRGBdefault()){
+ bData = new byte[width * height];
+ isRGB = false;
+ dataType = DATA_TYPE_BYTE;
+ }else{
+ iData = new int[width * height];
+ isRGB = true;
+ dataType = DATA_TYPE_INT;
+ }
+ case DATA_TYPE_BYTE:
+ if(!isRGB && cm == model){
+ for(int y = 0; y < srcH; y++){
+ System.arraycopy(pixels, srcOff, bData, realOff, srcW);
+ srcOff += srcScan;
+ realOff += scanline;
+ }
+ break;
+ }
+ forceToRGB();
+ case DATA_TYPE_INT:
+ for(int y = 0; y < srcH; y++){
+ for(int x = 0; x < srcW; x++){
+ iData[realOff + x] = cm.getRGB(pixels[srcOff + x] & 0xff);
+ }
+ srcOff += srcScan;
+ realOff += scanline;
+ }
+ }
+
+ return;
+ }
+
+ public void setPixels(int srcX, int srcY, int srcW, int srcH,
+ ColorModel model, int[] pixels, int srcOff, int srcScan) {
+
+ if(srcY < Y){
+ int delta = Y - srcY;
+ if(delta >= height) {
+ return;
+ }
+ srcY += delta;
+ srcH -= delta;
+ srcOff += srcScan * delta;
+ }
+
+ if(srcY + srcH > Y + height){
+ srcH = Y + height - srcY;
+ if(srcH <= 0) {
+ return;
+ }
+ }
+
+ if(srcX < X){
+ int delta = X - srcX;
+ if(delta >= width) {
+ return;
+ }
+ srcW -= delta;
+ srcX += delta;
+ srcOff += delta;
+ }
+
+ if(srcX + srcW > X + width){
+ srcW = X + width - srcX;
+ if(srcW <= 0) {
+ return;
+ }
+ }
+ if(scanline == 0) {
+ scanline = width;
+ }
+ int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+
+ int mask = 0xFF;
+
+ switch(dataType){
+ case DATA_TYPE_UNDEFINED:
+ cm = model;
+ iData = new int[width * height];
+ dataType = DATA_TYPE_INT;
+ isRGB = (cm == ColorModel.getRGBdefault());
+
+ case DATA_TYPE_INT:
+ if(cm == model){
+ for(int y = 0; y < srcH; y++){
+ System.arraycopy(pixels, srcOff, iData, realOff, srcW);
+ srcOff += srcScan;
+ realOff += scanline;
+ }
+ break;
+ }
+ mask = 0xFFFFFFFF;
+
+ case DATA_TYPE_BYTE:
+ forceToRGB();
+ for(int y = 0; y < srcH; y++){
+ for(int x = 0; x < srcW; x++){
+ iData[realOff+x] = cm.getRGB(pixels[srcOff+x] & mask);
+ }
+ srcOff += srcScan;
+ realOff += scanline;
+ }
+ }
+ }
+
+ public synchronized ColorModel getColorModel() {
+ return cm;
+ }
+
+ public synchronized boolean grabPixels(long ms)
+ throws InterruptedException {
+ if((grabberStatus & GRABBING_STOP) != 0){
+ return ((grabberStatus & ALL_BITS) != 0);
+ }
+
+ long start = System.currentTimeMillis();
+
+ if(!isGrabbing){
+ isGrabbing = true;
+ grabberStatus &= ~ImageObserver.ABORT;
+ producer.startProduction(this);
+ }
+ while((grabberStatus & GRABBING_STOP) == 0){
+ if(ms != 0){
+ ms = start + ms - System.currentTimeMillis();
+ if(ms <= 0) {
+ break;
+ }
+ }
+ wait(ms);
+ }
+
+ return ((grabberStatus & ALL_BITS) != 0);
+ }
+
+ public void setDimensions(int w, int h) {
+ if(width < 0) {
+ width = w - X;
+ }
+ if(height < 0) {
+ height = h - Y;
+ }
+
+ grabberStatus |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
+
+ if(width <=0 || height <=0){
+ imageComplete(STATICIMAGEDONE);
+ return;
+ }
+
+ if(isRGB && dataType == DATA_TYPE_UNDEFINED){
+ iData = new int[width * height];
+ dataType = DATA_TYPE_INT;
+ scanline = width;
+ }
+ }
+
+ public void setHints(int hints) {
+ return;
+ }
+
+ public synchronized void imageComplete(int status) {
+ switch(status){
+ case IMAGEABORTED:
+ grabberStatus |= ImageObserver.ABORT;
+ break;
+ case IMAGEERROR:
+ grabberStatus |= ImageObserver.ERROR | ImageObserver.ABORT;
+ break;
+ case SINGLEFRAMEDONE:
+ grabberStatus |= ImageObserver.FRAMEBITS;
+ break;
+ case STATICIMAGEDONE:
+ grabberStatus |= ImageObserver.ALLBITS;
+ break;
+ default:
+ // awt.26A=Incorrect ImageConsumer completion status
+ throw new IllegalArgumentException(Messages.getString("awt.26A")); //$NON-NLS-1$
+ }
+ isGrabbing = false;
+ producer.removeConsumer(this);
+ notifyAll();
+ }
+
+ public boolean grabPixels() throws InterruptedException {
+ return grabPixels(0);
+ }
+
+ public synchronized void startGrabbing() {
+ if((grabberStatus & GRABBING_STOP) != 0){
+ return;
+ }
+ if(!isGrabbing){
+ isGrabbing = true;
+ grabberStatus &= ~ImageObserver.ABORT;
+ producer.startProduction(this);
+ }
+ }
+
+ public synchronized void abortGrabbing() {
+ imageComplete(IMAGEABORTED);
+ }
+
+ public synchronized int status() {
+ return grabberStatus;
+ }
+
+ public synchronized int getWidth() {
+ if(width < 0) {
+ return -1;
+ }
+ return width;
+ }
+
+ public synchronized int getStatus() {
+ return grabberStatus;
+ }
+
+ public synchronized int getHeight() {
+ if(height < 0) {
+ return -1;
+ }
+ return height;
+ }
+
+ private void initialize(ImageProducer ip, int x, int y, int w, int h,
+ int pixels[], int off, int scansize, boolean forceRGB){
+
+ producer = ip;
+ X = x;
+ Y = y;
+ width = w;
+ height = h;
+ iData = pixels;
+ dataType = (pixels == null) ? DATA_TYPE_UNDEFINED : DATA_TYPE_INT;
+ offset = off;
+ scanline = scansize;
+ if(forceRGB){
+ cm = ColorModel.getRGBdefault();
+ isRGB = true;
+ }
+ }
+
+ /**
+ * Force pixels to INT RGB mode
+ */
+ private void forceToRGB(){
+ if (isRGB)
+ return;
+
+ switch(dataType){
+ case DATA_TYPE_BYTE:
+ iData = new int[width * height];
+ for(int i = 0; i < iData.length; i++){
+ iData[i] = cm.getRGB(bData[i] & 0xff);
+ }
+ dataType = DATA_TYPE_INT;
+ bData = null;
+ break;
+
+ case DATA_TYPE_INT:
+ int buff[] = new int[width * height];
+ for(int i = 0; i < iData.length; i++){
+ buff[i] = cm.getRGB(iData[i]);
+ }
+ iData = buff;
+ break;
+ }
+ offset = 0;
+ scanline = width;
+ cm = ColorModel.getRGBdefault();
+ isRGB = true;
+ }
+
+}