BandedSampleModel.java [plain text]
package java.awt.image;
public final class BandedSampleModel extends ComponentSampleModel
{
private int[] bitMasks;
private int[] bitOffsets;
private int[] sampleSize;
private int dataBitOffset;
private int elemBits;
private int numberOfBits;
private int numElems;
public BandedSampleModel(int dataType, int w, int h, int numBands)
{
super(dataType, w, h, 1, w, new int[numBands]);
}
public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
int[] bankIndices, int[] bandOffsets)
{
super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
int[] newoffsets = new int[bandOffsets.length];
int[] order = new int[bandOffsets.length];
for (int i=0; i < bandOffsets.length; i++)
order[i] = i;
for (int i=0; i < bandOffsets.length; i++)
for (int j=i+1; j < bandOffsets.length; i++)
if (bankIndices[order[i]] > bankIndices[order[j]]
|| (bankIndices[order[i]] == bankIndices[order[j]]
&& bandOffsets[order[i]] > bandOffsets[order[j]]))
{
int t = order[i]; order[i] = order[j]; order[j] = t;
}
int bank = 0;
int offset = 0;
for (int i=0; i < bandOffsets.length; i++)
{
if (bankIndices[order[i]] != bank)
{
bank = bankIndices[order[i]];
offset = 0;
}
newoffsets[order[i]] = offset;
offset += w * scanlineStride;
}
return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
}
public SampleModel createSubsetSampleModel(int[] bands)
{
int[] newoff = new int[bands.length];
int[] newbanks = new int[bands.length];
for (int i=0; i < bands.length; i++)
{
int b = bands[i];
newoff[i] = bandOffsets[b];
newbanks[i] = bankIndices[b];
}
if (bands.length > bankIndices.length)
throw new
RasterFormatException("BandedSampleModel createSubsetSampleModel too"
+" many bands");
return new BandedSampleModel(dataType, width, height, scanlineStride,
newbanks, newoff);
}
public Object getDataElements(int x, int y, Object obj,
DataBuffer data)
{
int pixel = getSample(x, y, 0, data);
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
{
byte[] b = (byte[])obj;
if (b == null) b = new byte[numBands];
for (int i=0; i < numBands; i++)
b[i] = (byte)getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
{
short[] b = (short[])obj;
if (b == null) b = new short[numBands];
for (int i=0; i < numBands; i++)
b[i] = (short)getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_INT:
{
int[] b = (int[])obj;
if (b == null) b = new int[numBands];
for (int i=0; i < numBands; i++)
b[i] = getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_FLOAT:
{
float[] b = (float[])obj;
if (b == null) b = new float[numBands];
for (int i=0; i < numBands; i++)
b[i] = getSampleFloat(x, y, i, data);
return b;
}
case DataBuffer.TYPE_DOUBLE:
{
double[] b = (double[])obj;
if (b == null) b = new double[numBands];
for (int i=0; i < numBands; i++)
b[i] = getSample(x, y, i, data);
return b;
}
default:
throw new ClassCastException();
}
}
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
if (iArray == null) iArray = new int[numBands];
for (int i=0; i < numBands; i++)
iArray[i] = getSample(x, y, 0, data);
return iArray;
}
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
if (iArray == null) iArray = new int[w*h*numBands];
int outOffset = 0;
for (y=0; y<h; y++)
{
for (x=0; x<w;)
{
for (int b=0; b < numBands; b++)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
iArray[outOffset++] =
data.getElem(bankIndices[b], offset);
}
}
}
return iArray;
}
public int getSample(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
return data.getElem(bankIndices[b], offset);
}
public float getSampleFloat(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
return data.getElemFloat(bankIndices[b], offset);
}
public double getSampleDouble(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
return data.getElemDouble(bankIndices[b], offset);
}
public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
DataBuffer data)
{
if (iArray == null) iArray = new int[w*h];
int outOffset = 0;
for (y=0; y<h; y++)
{
for (x=0; x<w;)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
iArray[outOffset++] =
data.getElem(bankIndices[b], offset);
}
}
return iArray;
}
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int transferType = getTransferType();
if (getTransferType() != data.getDataType())
{
throw new IllegalArgumentException("transfer type ("+
getTransferType()+"), "+
"does not match data "+
"buffer type (" +
data.getDataType() +
").");
}
int offset = y * scanlineStride + x;
try
{
switch (transferType)
{
case DataBuffer.TYPE_BYTE:
{
DataBufferByte out = (DataBufferByte) data;
byte[] in = (byte[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
case DataBuffer.TYPE_SHORT:
{
DataBufferShort out = (DataBufferShort) data;
short[] in = (short[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
case DataBuffer.TYPE_USHORT:
{
DataBufferUShort out = (DataBufferUShort) data;
short[] in = (short[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
int[] in = (int[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
case DataBuffer.TYPE_FLOAT:
{
DataBufferFloat out = (DataBufferFloat) data;
float[] in = (float[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
case DataBuffer.TYPE_DOUBLE:
{
DataBufferDouble out = (DataBufferDouble) data;
double[] in = (double[]) obj;
for (int i=0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
return;
}
default:
throw new ClassCastException("Unsupported data type");
}
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
String msg = "While writing data elements" +
", x="+x+", y="+y+
", width="+width+", height="+height+
", scanlineStride="+scanlineStride+
", offset="+offset+
", data.getSize()="+data.getSize()+
", data.getOffset()="+data.getOffset()+
": " +
aioobe;
throw new ArrayIndexOutOfBoundsException(msg);
}
}
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
for (int b=0; b < numBands; b++)
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
iArray[b]);
}
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int inOffset = 0;
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = y * scanlineStride + (x + ww);
for (int b=0; b < numBands; b++)
data.setElem(bankIndices[b], bandOffsets[b] + offset,
iArray[inOffset++]);
}
y++;
}
}
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
}
public void setSample(int x, int y, int b, float s, DataBuffer data)
{
data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
}
public void setSample(int x, int y, int b, double s, DataBuffer data)
{
data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
}
public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
DataBuffer data)
{
int inOffset = 0;
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
{
DataBufferByte out = (DataBufferByte) data;
byte[] bank = out.getData(bankIndices[b]);
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
bank[offset] = (byte)iArray[inOffset++];
}
y++;
}
return;
}
case DataBuffer.TYPE_SHORT:
{
DataBufferShort out = (DataBufferShort) data;
short[] bank = out.getData(bankIndices[b]);
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
bank[offset] = (short)iArray[inOffset++];
}
y++;
}
return;
}
case DataBuffer.TYPE_USHORT:
{
DataBufferShort out = (DataBufferShort) data;
short[] bank = out.getData(bankIndices[b]);
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
bank[offset] = (short)iArray[inOffset++];
}
y++;
}
return;
}
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
int[] bank = out.getData(bankIndices[b]);
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
bank[offset] = iArray[inOffset++];
}
y++;
}
return;
}
case DataBuffer.TYPE_FLOAT:
case DataBuffer.TYPE_DOUBLE:
break;
default:
throw new ClassCastException("Unsupported data type");
}
for (int hh = 0; hh < h; hh++)
{
for (int ww = 0; ww < w; ww++)
{
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
data.setElem(bankIndices[b], offset, iArray[inOffset++]);
}
y++;
}
}
public String toString()
{
StringBuffer result = new StringBuffer();
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
for(int i=0; i < bitMasks.length; i+=1)
{
result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
}
result.append("]");
return result.toString();
}
}