ComponentSampleModel.java [plain text]
package java.awt.image;
import gnu.java.awt.Buffers;
public class ComponentSampleModel extends SampleModel
{
protected int[] bandOffsets;
protected int[] bankIndices;
protected int numBanks;
protected int scanlineStride;
protected int pixelStride;
private boolean tightPixelPacking = false;
public ComponentSampleModel(int dataType,
int w, int h,
int pixelStride,
int scanlineStride,
int[] bandOffsets)
{
this(dataType, w, h, pixelStride, scanlineStride,
new int[bandOffsets.length], bandOffsets);
}
public ComponentSampleModel(int dataType,
int w, int h,
int pixelStride,
int scanlineStride,
int[] bankIndices,
int[] bandOffsets)
{
super(dataType, w, h, bandOffsets.length);
if ((pixelStride<0) || (scanlineStride<0) ||
(bandOffsets.length<1) ||
(bandOffsets.length != bankIndices.length))
throw new IllegalArgumentException();
this.bandOffsets = bandOffsets;
this.bankIndices = bankIndices;
this.numBanks = 0;
for (int b=0; b<bankIndices.length; b++)
this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
this.scanlineStride = scanlineStride;
this.pixelStride = pixelStride;
if (pixelStride == numBands)
{
tightPixelPacking = true;
for (int b=0; b<numBands; b++) {
if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
{
tightPixelPacking = false;
break;
}
}
}
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
return new ComponentSampleModel(dataType, w, h, pixelStride,
scanlineStride, bankIndices,
bandOffsets);
}
public SampleModel createSubsetSampleModel(int[] bands)
{
int numBands = bands.length;
int[] bankIndices = new int[numBands];
int[] bandOffsets = new int[numBands];
for (int b=0; b<numBands; b++)
{
bankIndices[b] = this.bankIndices[bands[b]];
bandOffsets[b] = this.bandOffsets[bands[b]];
}
return new ComponentSampleModel(dataType, width, height, pixelStride,
scanlineStride, bankIndices,
bandOffsets);
}
public DataBuffer createDataBuffer()
{
int highestOffset = 0;
for (int b=0; b<numBands; b++)
{
highestOffset = Math.max(highestOffset, bandOffsets[b]);
}
int size = pixelStride*(width-1) + scanlineStride*(height-1) +
highestOffset + 1;
return Buffers.createBuffer(getDataType(), size, numBanks);
}
public int getOffset(int x, int y)
{
return getOffset(x, y, 0);
}
public int getOffset(int x, int y, int b)
{
return bandOffsets[b] + pixelStride*x + scanlineStride*y;
}
public final int[] getSampleSize()
{
int size = DataBuffer.getDataTypeSize(getDataType());
int[] sizes = new int[numBands];
java.util.Arrays.fill(sizes, size);
return sizes;
}
public final int getSampleSize(int band)
{
return DataBuffer.getDataTypeSize(getDataType());
}
public final int[] getBankIndices()
{
return bankIndices;
}
public final int[] getBandOffsets()
{
return bandOffsets;
}
public final int getScanlineStride()
{
return scanlineStride;
}
public final int getPixelStride()
{
return pixelStride;
}
public final int getNumDataElements()
{
return numBands;
}
public Object getDataElements(int x, int y, Object obj, DataBuffer data)
{
int xyOffset = pixelStride*x + scanlineStride*y;
int[] totalBandDataOffsets = new int[numBands];
int[] bankOffsets = data.getOffsets();
for (int b=0; b<numBands; b++)
{
totalBandDataOffsets[b] =
bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
}
try
{
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
DataBufferByte inByte = (DataBufferByte) data;
byte[] outByte = (byte[]) obj;
if (outByte == null) outByte = new byte[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outByte[b] = inByte.getData(bankIndices[b])[dOffset];
}
return outByte;
case DataBuffer.TYPE_USHORT:
DataBufferUShort inUShort = (DataBufferUShort) data;
short[] outUShort = (short[]) obj;
if (outUShort == null) outUShort = new short[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
}
return outUShort;
case DataBuffer.TYPE_SHORT:
DataBufferShort inShort = (DataBufferShort) data;
short[] outShort = (short[]) obj;
if (outShort == null) outShort = new short[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outShort[b] = inShort.getData(bankIndices[b])[dOffset];
}
return outShort;
case DataBuffer.TYPE_INT:
DataBufferInt inInt = (DataBufferInt) data;
int[] outInt = (int[]) obj;
if (outInt == null) outInt = new int[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outInt[b] = inInt.getData(bankIndices[b])[dOffset];
}
return outInt;
case DataBuffer.TYPE_FLOAT:
DataBufferFloat inFloat = (DataBufferFloat) data;
float[] outFloat = (float[]) obj;
if (outFloat == null) outFloat = new float[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
}
return outFloat;
case DataBuffer.TYPE_DOUBLE:
DataBufferDouble inDouble = (DataBufferDouble) data;
double[] outDouble = (double[]) obj;
if (outDouble == null) outDouble = new double[numBands];
for (int b=0; b<numBands; b++)
{
int dOffset = totalBandDataOffsets[b];
outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
}
return outDouble;
default:
throw new IllegalStateException("unknown transfer type " +
getTransferType());
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
String msg = "While reading data elements, " +
"x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
", data.getSize()=" + data.getSize() + ": " + aioobe;
throw new ArrayIndexOutOfBoundsException(msg);
}
}
public Object getDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
{
if (!tightPixelPacking)
{
return super.getDataElements(x, y, w, h, obj, data);
}
int rowSize = w*numBands;
int dataSize = rowSize*h;
DataBuffer transferBuffer =
Buffers.createBuffer(getTransferType(), obj, dataSize);
obj = Buffers.getData(transferBuffer);
int inOffset =
pixelStride*x +
scanlineStride*y +
data.getOffset();
if (scanlineStride == rowSize)
{
rowSize *= h;
h = 1;
}
int outOffset = 0;
Object inArray = Buffers.getData(data);
for (int yd = 0; yd<h; yd++)
{
System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
inOffset += scanlineStride;
outOffset += rowSize;
}
return obj;
}
public void setDataElements(int x, int y, int w, int h,
Object obj, DataBuffer data)
{
if (!tightPixelPacking)
{
super.setDataElements(x, y, w, h, obj, data);
return;
}
int rowSize = w*numBands;
int dataSize = rowSize*h;
DataBuffer transferBuffer =
Buffers.createBufferFromData(getTransferType(), obj, dataSize);
int[] bankOffsets = data.getOffsets();
int outOffset =
pixelStride*x +
scanlineStride*y +
bankOffsets[0];
if (scanlineStride == rowSize)
{
rowSize *= h;
h = 1;
}
int inOffset = 0;
Object outArray = Buffers.getData(data);
for (int yd = 0; yd<h; yd++)
{
System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
outOffset += scanlineStride;
inOffset += rowSize;
}
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
if (iArray == null) iArray = new int[numBands];
for (int b=0; b<numBands; b++)
{
iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
}
return iArray;
}
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
if (iArray == null) iArray = new int[numBands*w*h];
int outOffset = 0;
for (y=0; y<h; y++)
{
int lineOffset = offset;
for (x=0; x<w; x++)
{
for (int b=0; b<numBands; b++)
{
iArray[outOffset++] =
data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
}
lineOffset += pixelStride;
}
offset += scanlineStride;
}
return iArray;
}
public int getSample(int x, int y, int b, DataBuffer data)
{
return data.getElem(bankIndices[b], getOffset(x, y, b));
}
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
int[] totalBandDataOffsets = new int[numBands];
int[] bankOffsets = data.getOffsets();
for (int b=0; b<numBands; b++)
totalBandDataOffsets[b] =
bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
{
DataBufferByte out = (DataBufferByte) data;
byte[] in = (byte[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_USHORT:
{
DataBufferUShort out = (DataBufferUShort) data;
short[] in = (short[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_SHORT:
{
DataBufferShort out = (DataBufferShort) data;
short[] in = (short[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
int[] in = (int[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_FLOAT:
{
DataBufferFloat out = (DataBufferFloat) data;
float[] in = (float[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
case DataBuffer.TYPE_DOUBLE:
{
DataBufferDouble out = (DataBufferDouble) data;
double[] in = (double[]) obj;
for (int b=0; b<numBands; b++)
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
return;
}
default:
throw new UnsupportedOperationException("transfer type not " +
"implemented");
}
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = pixelStride*x + scanlineStride*y;
for (int b=0; b<numBands; b++)
data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
}
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
data.setElem(bankIndices[b], getOffset(x, y, b), s);
}
}