blob: 5840f78d262956e6056ae4a9e3fb95150b4b25a9 [file] [log] [blame]
/* Copyright (C) 2000 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.awt.image;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public abstract class SampleModel
{
/** Width of image described. */
protected int width;
/** Height of image described. */
protected int height;
/** Number of bands in the image described. */
protected int numBands;
/**
* The DataBuffer type that is used to store the data of the image
* described.
*/
protected int dataType;
public SampleModel(int dataType, int w, int h, int numBands)
{
if ((w<=0) || (h<=0)) throw new IllegalArgumentException();
// FIXME: How can an int be greater than Integer.MAX_VALUE?
// FIXME: How do we identify an unsupported data type?
this.dataType = dataType;
this.width = w;
this.height = h;
this.numBands = numBands;
}
public final int getWidth()
{
return width;
}
public final int getHeight()
{
return height;
}
public final int getNumBands()
{
return numBands;
}
public abstract int getNumDataElements();
public final int getDataType()
{
return dataType;
}
public int getTransferType()
{
// FIXME: Is this a reasonable default implementation?
return dataType;
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
if (iArray == null) iArray = new int[numBands];
for (int b=0; b<numBands; b++) iArray[b] = getSample(x, y, b, data);
return iArray;
}
/**
*
* This method is provided as a faster alternative to getPixel(),
* that can be used when there is no need to decode the pixel into
* seperate sample values.
*
* @param obj An array to return the pixel data in. If null, an
* array of the right type and size will be created.
*
* @return A single pixel as an array object of a primitive type,
* based on the transfer type. Eg. if transfer type is
* DataBuffer.TYPE_USHORT, then a short[] object is returned.
*/
public abstract Object getDataElements(int x, int y, Object obj,
DataBuffer data);
public Object getDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
{
int size = w*h;
int numDataElements = getNumDataElements();
int dataSize = numDataElements*size;
if (obj == null)
{
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
obj = new byte[dataSize];
break;
case DataBuffer.TYPE_USHORT:
obj = new short[dataSize];
break;
case DataBuffer.TYPE_INT:
obj = new int[dataSize];
break;
default:
// Seems like the only sensible thing to do.
throw new ClassCastException();
}
}
Object pixelData = null;
int outOffset = 0;
for (int yy = y; yy<(y+h); yy++)
{
for (int xx = x; xx<(x+w); xx++)
{
pixelData = getDataElements(xx, yy, pixelData, data);
System.arraycopy(pixelData, 0, obj, outOffset,
numDataElements);
outOffset += numDataElements;
}
}
return obj;
}
public abstract void setDataElements(int x, int y, Object obj,
DataBuffer data);
public void setDataElements(int x, int y, int w, int h,
Object obj, DataBuffer data)
{
int size = w*h;
int numDataElements = getNumDataElements();
int dataSize = numDataElements*size;
Object pixelData;
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
pixelData = new byte[numDataElements];
break;
case DataBuffer.TYPE_USHORT:
pixelData = new short[numDataElements];
break;
case DataBuffer.TYPE_INT:
pixelData = new int[numDataElements];
break;
default:
// Seems like the only sensible thing to do.
throw new ClassCastException();
}
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(obj, inOffset, pixelData, 0,
numDataElements);
setDataElements(xx, yy, pixelData, data);
inOffset += numDataElements;
}
}
}
public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
{
if (fArray == null) fArray = new float[numBands];
for (int b=0; b<numBands; b++)
{
fArray[0] = getSampleFloat(x, y, b, data);
}
return fArray;
}
public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
if (dArray == null) dArray = new double[numBands];
for (int b=0; b<numBands; b++)
{
dArray[0] = getSampleDouble(x, y, b, data);
}
return dArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
int[] pixel = null;
if (iArray == null) iArray = new int[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, iArray, outOffset, numBands);
outOffset += numBands;
}
}
return iArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public float[] getPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
float[] pixel = null;
if (fArray == null) fArray = new float[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, fArray, outOffset, numBands);
outOffset += numBands;
}
}
return fArray;
}
/* FIXME: Should it return a banded or pixel interleaved array of
samples? (Assume interleaved.) */
public double[] getPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
int size = w*h;
int outOffset = 0;
double[] pixel = null;
if (dArray == null) dArray = new double[w*h*numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
getPixel(xx, yy, pixel, data);
System.arraycopy(pixel, 0, dArray, outOffset, numBands);
outOffset += numBands;
}
}
return dArray;
}
public abstract int getSample(int x, int y, int b, DataBuffer data);
public float getSampleFloat(int x, int y, int b, DataBuffer data)
{
return getSample(x, y, b, data);
}
public double getSampleDouble(int x, int y, int b, DataBuffer data)
{
return getSampleFloat(x, y, b, data);
}
public int[] getSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (iArray == null) iArray = new int[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
iArray[outOffset++] = getSample(xx, yy, b, data);
}
}
return iArray;
}
public float[] getSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (fArray == null) fArray = new float[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
}
}
return fArray;
}
public double[] getSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data)
{
int size = w*h;
int outOffset = 0;
if (dArray == null) dArray = new double[size];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
}
}
return dArray;
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, iArray[b], data);
}
public void setPixel(int x, int y, float[] fArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, fArray[b], data);
}
public void setPixel(int x, int y, double[] dArray, DataBuffer data)
{
for (int b=0; b<numBands; b++) setSample(x, y, b, dArray[b], data);
}
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int inOffset = 0;
int[] pixel = new int[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(iArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public void setPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
int inOffset = 0;
float[] pixel = new float[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(fArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public void setPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
int inOffset = 0;
double[] pixel = new double[numBands];
for (int yy=y; yy<(y+h); yy++)
{
for (int xx=x; xx<(x+w); xx++)
{
System.arraycopy(dArray, inOffset, pixel, 0, numBands);
setPixel(xx, yy, pixel, data);
inOffset += numBands;
}
}
}
public abstract void setSample(int x, int y, int b, int s,
DataBuffer data);
public void setSample(int x, int y, int b, float s,
DataBuffer data)
{
setSample(x, y, b, (int) s, data);
}
public void setSample(int x, int y, int b, double s,
DataBuffer data)
{
setSample(x, y, b, (float) s, data);
}
public void setSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, iArray[inOffset++], data);
}
public void setSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, fArray[inOffset++], data);
}
public void setSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data) {
int size = w*h;
int inOffset = 0;
for (int yy=y; yy<(y+h); yy++)
for (int xx=x; xx<(x+w); xx++)
setSample(xx, yy, b, dArray[inOffset++], data);
}
public abstract SampleModel createCompatibleSampleModel(int w, int h);
public abstract SampleModel createSubsetSampleModel(int[] bands);
public abstract DataBuffer createDataBuffer();
public abstract int[] getSampleSize();
public abstract int getSampleSize(int band);
}