/* |
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
* |
|
* This code is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License version 2 only, as |
|
* published by the Free Software Foundation. Oracle designates this |
|
* particular file as subject to the "Classpath" exception as provided |
|
* by Oracle in the LICENSE file that accompanied this code. |
|
* |
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
* version 2 for more details (a copy is included in the LICENSE file that |
|
* accompanied this code). |
|
* |
|
* You should have received a copy of the GNU General Public License version |
|
* 2 along with this work; if not, write to the Free Software Foundation, |
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
* |
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
* or visit www.oracle.com if you need additional information or have any |
|
* questions. |
|
*/ |
|
/* **************************************************************** |
|
****************************************************************** |
|
****************************************************************** |
|
*** COPYRIGHT (c) Eastman Kodak Company, 1997 |
|
*** As an unpublished work pursuant to Title 17 of the United |
|
*** States Code. All rights reserved. |
|
****************************************************************** |
|
****************************************************************** |
|
******************************************************************/ |
|
package java.awt.image; |
|
/** |
|
* This class represents image data which is stored in a band interleaved |
|
* fashion and for |
|
* which each sample of a pixel occupies one data element of the DataBuffer. |
|
* It subclasses ComponentSampleModel but provides a more efficient |
|
* implementation for accessing band interleaved image data than is provided |
|
* by ComponentSampleModel. This class should typically be used when working |
|
* with images which store sample data for each band in a different bank of the |
|
* DataBuffer. Accessor methods are provided so that image data can be |
|
* manipulated directly. Pixel stride is the number of |
|
* data array elements between two samples for the same band on the same |
|
* scanline. The pixel stride for a BandedSampleModel is one. |
|
* Scanline stride is the number of data array elements between |
|
* a given sample and the corresponding sample in the same column of the next |
|
* scanline. Band offsets denote the number |
|
* of data array elements from the first data array element of the bank |
|
* of the DataBuffer holding each band to the first sample of the band. |
|
* The bands are numbered from 0 to N-1. |
|
* Bank indices denote the correspondence between a bank of the data buffer |
|
* and a band of image data. This class supports |
|
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE}, |
|
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT}, |
|
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT}, |
|
* {@link DataBuffer#TYPE_INT TYPE_INT}, |
|
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and |
|
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes |
|
*/ |
|
public final class BandedSampleModel extends ComponentSampleModel |
|
{ |
|
/** |
|
* Constructs a BandedSampleModel with the specified parameters. |
|
* The pixel stride will be one data element. The scanline stride |
|
* will be the same as the width. Each band will be stored in |
|
* a separate bank and all band offsets will be zero. |
|
* @param dataType The data type for storing samples. |
|
* @param w The width (in pixels) of the region of |
|
* image data described. |
|
* @param h The height (in pixels) of the region of image |
|
* data described. |
|
* @param numBands The number of bands for the image data. |
|
* @throws IllegalArgumentException if <code>dataType</code> is not |
|
* one of the supported data types |
|
*/ |
|
public BandedSampleModel(int dataType, int w, int h, int numBands) { |
|
super(dataType, w, h, 1, w, |
|
BandedSampleModel.createIndicesArray(numBands), |
|
BandedSampleModel.createOffsetArray(numBands)); |
|
} |
|
/** |
|
* Constructs a BandedSampleModel with the specified parameters. |
|
* The number of bands will be inferred from the lengths of the |
|
* bandOffsets bankIndices arrays, which must be equal. The pixel |
|
* stride will be one data element. |
|
* @param dataType The data type for storing samples. |
|
* @param w The width (in pixels) of the region of |
|
* image data described. |
|
* @param h The height (in pixels) of the region of |
|
* image data described. |
|
* @param scanlineStride The line stride of the of the image data. |
|
* @param bankIndices The bank index for each band. |
|
* @param bandOffsets The band offset for each band. |
|
* @throws IllegalArgumentException if <code>dataType</code> is not |
|
* one of the supported data types |
|
*/ |
|
public BandedSampleModel(int dataType, |
|
int w, int h, |
|
int scanlineStride, |
|
int bankIndices[], |
|
int bandOffsets[]) { |
|
super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets); |
|
} |
|
/** |
|
* Creates a new BandedSampleModel with the specified |
|
* width and height. The new BandedSampleModel will have the same |
|
* number of bands, storage data type, and bank indices |
|
* as this BandedSampleModel. The band offsets will be compressed |
|
* such that the offset between bands will be w*pixelStride and |
|
* the minimum of all of the band offsets is zero. |
|
* @param w the width of the resulting <code>BandedSampleModel</code> |
|
* @param h the height of the resulting <code>BandedSampleModel</code> |
|
* @return a new <code>BandedSampleModel</code> with the specified |
|
* width and height. |
|
* @throws IllegalArgumentException if <code>w</code> or |
|
* <code>h</code> equals either |
|
* <code>Integer.MAX_VALUE</code> or |
|
* <code>Integer.MIN_VALUE</code> |
|
* @throws IllegalArgumentException if <code>dataType</code> is not |
|
* one of the supported data types |
|
*/ |
|
public SampleModel createCompatibleSampleModel(int w, int h) { |
|
int[] bandOffs; |
|
if (numBanks == 1) { |
|
bandOffs = orderBands(bandOffsets, w*h); |
|
} |
|
else { |
|
bandOffs = new int[bandOffsets.length]; |
|
} |
|
SampleModel sampleModel = |
|
new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs); |
|
return sampleModel; |
|
} |
|
/** |
|
* Creates a new BandedSampleModel with a subset of the bands of this |
|
* BandedSampleModel. The new BandedSampleModel can be |
|
* used with any DataBuffer that the existing BandedSampleModel |
|
* can be used with. The new BandedSampleModel/DataBuffer |
|
* combination will represent an image with a subset of the bands |
|
* of the original BandedSampleModel/DataBuffer combination. |
|
* @throws RasterFormatException if the number of bands is greater than |
|
* the number of banks in this sample model. |
|
* @throws IllegalArgumentException if <code>dataType</code> is not |
|
* one of the supported data types |
|
*/ |
|
public SampleModel createSubsetSampleModel(int bands[]) { |
|
if (bands.length > bankIndices.length) |
|
throw new RasterFormatException("There are only " + |
|
bankIndices.length + |
|
" bands"); |
|
int newBankIndices[] = new int[bands.length]; |
|
int newBandOffsets[] = new int[bands.length]; |
|
for (int i=0; i<bands.length; i++) { |
|
newBankIndices[i] = bankIndices[bands[i]]; |
|
newBandOffsets[i] = bandOffsets[bands[i]]; |
|
} |
|
return new BandedSampleModel(this.dataType, width, height, |
|
this.scanlineStride, |
|
newBankIndices, newBandOffsets); |
|
} |
|
/** |
|
* Creates a DataBuffer that corresponds to this BandedSampleModel, |
|
* The DataBuffer's data type, number of banks, and size |
|
* will be consistent with this BandedSampleModel. |
|
* @throws IllegalArgumentException if <code>dataType</code> is not |
|
* one of the supported types. |
|
*/ |
|
public DataBuffer createDataBuffer() { |
|
DataBuffer dataBuffer = null; |
|
int size = scanlineStride * height; |
|
switch (dataType) { |
|
case DataBuffer.TYPE_BYTE: |
|
dataBuffer = new DataBufferByte(size, numBanks); |
|
break; |
|
case DataBuffer.TYPE_USHORT: |
|
dataBuffer = new DataBufferUShort(size, numBanks); |
|
break; |
|
case DataBuffer.TYPE_SHORT: |
|
dataBuffer = new DataBufferShort(size, numBanks); |
|
break; |
|
case DataBuffer.TYPE_INT: |
|
dataBuffer = new DataBufferInt(size, numBanks); |
|
break; |
|
case DataBuffer.TYPE_FLOAT: |
|
dataBuffer = new DataBufferFloat(size, numBanks); |
|
break; |
|
case DataBuffer.TYPE_DOUBLE: |
|
dataBuffer = new DataBufferDouble(size, numBanks); |
|
break; |
|
default: |
|
throw new IllegalArgumentException("dataType is not one " + |
|
"of the supported types."); |
|
} |
|
return dataBuffer; |
|
} |
|
/** |
|
* Returns data for a single pixel in a primitive array of type |
|
* TransferType. For a BandedSampleModel, this will be the same |
|
* as the data type, and samples will be returned one per array |
|
* element. Generally, obj |
|
* should be passed in as null, so that the Object will be created |
|
* automatically and will be of the right primitive data type. |
|
* <p> |
|
* The following code illustrates transferring data for one pixel from |
|
* DataBuffer <code>db1</code>, whose storage layout is described by |
|
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>, |
|
* whose storage layout is described by |
|
* BandedSampleModel <code>bsm2</code>. |
|
* The transfer will generally be more efficient than using |
|
* getPixel/setPixel. |
|
* <pre> |
|
* BandedSampleModel bsm1, bsm2; |
|
* DataBufferInt db1, db2; |
|
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1), |
|
* db2); |
|
* </pre> |
|
* Using getDataElements/setDataElements to transfer between two |
|
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have |
|
* the same number of bands, corresponding bands have the same number of |
|
* bits per sample, and the TransferTypes are the same. |
|
* <p> |
|
* If obj is non-null, it should be a primitive array of type TransferType. |
|
* Otherwise, a ClassCastException is thrown. An |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds, or if obj is non-null and is not large enough to hold |
|
* the pixel data. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param obj If non-null, a primitive array in which to return |
|
* the pixel data. |
|
* @param data The DataBuffer containing the image data. |
|
* @return the data for the specified pixel. |
|
* @see #setDataElements(int, int, Object, DataBuffer) |
|
*/ |
|
public Object getDataElements(int x, int y, Object obj, DataBuffer data) { |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int type = getTransferType(); |
|
int numDataElems = getNumDataElements(); |
|
int pixelOffset = y*scanlineStride + x; |
|
switch(type) { |
|
case DataBuffer.TYPE_BYTE: |
|
byte[] bdata; |
|
if (obj == null) { |
|
bdata = new byte[numDataElems]; |
|
} else { |
|
bdata = (byte[])obj; |
|
} |
|
for (int i=0; i<numDataElems; i++) { |
|
bdata[i] = (byte)data.getElem(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
obj = (Object)bdata; |
|
break; |
|
case DataBuffer.TYPE_USHORT: |
|
case DataBuffer.TYPE_SHORT: |
|
short[] sdata; |
|
if (obj == null) { |
|
sdata = new short[numDataElems]; |
|
} else { |
|
sdata = (short[])obj; |
|
} |
|
for (int i=0; i<numDataElems; i++) { |
|
sdata[i] = (short)data.getElem(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
obj = (Object)sdata; |
|
break; |
|
case DataBuffer.TYPE_INT: |
|
int[] idata; |
|
if (obj == null) { |
|
idata = new int[numDataElems]; |
|
} else { |
|
idata = (int[])obj; |
|
} |
|
for (int i=0; i<numDataElems; i++) { |
|
idata[i] = data.getElem(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
obj = (Object)idata; |
|
break; |
|
case DataBuffer.TYPE_FLOAT: |
|
float[] fdata; |
|
if (obj == null) { |
|
fdata = new float[numDataElems]; |
|
} else { |
|
fdata = (float[])obj; |
|
} |
|
for (int i=0; i<numDataElems; i++) { |
|
fdata[i] = data.getElemFloat(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
obj = (Object)fdata; |
|
break; |
|
case DataBuffer.TYPE_DOUBLE: |
|
double[] ddata; |
|
if (obj == null) { |
|
ddata = new double[numDataElems]; |
|
} else { |
|
ddata = (double[])obj; |
|
} |
|
for (int i=0; i<numDataElems; i++) { |
|
ddata[i] = data.getElemDouble(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
obj = (Object)ddata; |
|
break; |
|
} |
|
return obj; |
|
} |
|
/** |
|
* Returns all samples for the specified pixel in an int array. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param iArray If non-null, returns the samples in this array |
|
* @param data The DataBuffer containing the image data |
|
* @return the samples for the specified pixel. |
|
* @see #setPixel(int, int, int[], DataBuffer) |
|
*/ |
|
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) { |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int[] pixels; |
|
if (iArray != null) { |
|
pixels = iArray; |
|
} else { |
|
pixels = new int [numBands]; |
|
} |
|
int pixelOffset = y*scanlineStride + x; |
|
for (int i=0; i<numBands; i++) { |
|
pixels[i] = data.getElem(bankIndices[i], |
|
pixelOffset + bandOffsets[i]); |
|
} |
|
return pixels; |
|
} |
|
/** |
|
* Returns all samples for the specified rectangle of pixels in |
|
* an int array, one sample per data array element. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the upper left pixel location |
|
* @param y The Y coordinate of the upper left pixel location |
|
* @param w The width of the pixel rectangle |
|
* @param h The height of the pixel rectangle |
|
* @param iArray If non-null, returns the samples in this array |
|
* @param data The DataBuffer containing the image data |
|
* @return the samples for the pixels within the specified region. |
|
* @see #setPixels(int, int, int, int, int[], DataBuffer) |
|
*/ |
|
public int[] getPixels(int x, int y, int w, int h, |
|
int iArray[], DataBuffer data) { |
|
int x1 = x + w; |
|
int y1 = y + h; |
|
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width || |
|
y < 0 || y >= height || h > height || y1 < 0 || y1 > height) |
|
{ |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int[] pixels; |
|
if (iArray != null) { |
|
pixels = iArray; |
|
} else { |
|
pixels = new int[w*h*numBands]; |
|
} |
|
for (int k = 0; k < numBands; k++) { |
|
int lineOffset = y*scanlineStride + x + bandOffsets[k]; |
|
int srcOffset = k; |
|
int bank = bankIndices[k]; |
|
for (int i = 0; i < h; i++) { |
|
int pixelOffset = lineOffset; |
|
for (int j = 0; j < w; j++) { |
|
pixels[srcOffset] = data.getElem(bank, pixelOffset++); |
|
srcOffset += numBands; |
|
} |
|
lineOffset += scanlineStride; |
|
} |
|
} |
|
return pixels; |
|
} |
|
/** |
|
* Returns as int the sample in a specified band for the pixel |
|
* located at (x,y). |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to return |
|
* @param data The DataBuffer containing the image data |
|
* @return the sample in the specified band for the specified pixel. |
|
* @see #setSample(int, int, int, int, DataBuffer) |
|
*/ |
|
public int getSample(int x, int y, int b, DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int sample = |
|
data.getElem(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b]); |
|
return sample; |
|
} |
|
/** |
|
* Returns the sample in a specified band |
|
* for the pixel located at (x,y) as a float. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to return |
|
* @param data The DataBuffer containing the image data |
|
* @return a float value that represents the sample in the specified |
|
* band for the specified pixel. |
|
*/ |
|
public float getSampleFloat(int x, int y, int b, DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
float sample = data.getElemFloat(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b]); |
|
return sample; |
|
} |
|
/** |
|
* Returns the sample in a specified band |
|
* for a pixel located at (x,y) as a double. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to return |
|
* @param data The DataBuffer containing the image data |
|
* @return a double value that represents the sample in the specified |
|
* band for the specified pixel. |
|
*/ |
|
public double getSampleDouble(int x, int y, int b, DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
double sample = data.getElemDouble(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b]); |
|
return sample; |
|
} |
|
/** |
|
* Returns the samples in a specified band for the specified rectangle |
|
* of pixels in an int array, one sample per data array element. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the upper left pixel location |
|
* @param y The Y coordinate of the upper left pixel location |
|
* @param w The width of the pixel rectangle |
|
* @param h The height of the pixel rectangle |
|
* @param b The band to return |
|
* @param iArray If non-null, returns the samples in this array |
|
* @param data The DataBuffer containing the image data |
|
* @return the samples in the specified band for the pixels within |
|
* the specified region. |
|
* @see #setSamples(int, int, int, int, int, int[], DataBuffer) |
|
*/ |
|
public int[] getSamples(int x, int y, int w, int h, int b, |
|
int iArray[], DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int samples[]; |
|
if (iArray != null) { |
|
samples = iArray; |
|
} else { |
|
samples = new int [w*h]; |
|
} |
|
int lineOffset = y*scanlineStride + x + bandOffsets[b]; |
|
int srcOffset = 0; |
|
int bank = bankIndices[b]; |
|
for (int i = 0; i < h; i++) { |
|
int sampleOffset = lineOffset; |
|
for (int j = 0; j < w; j++) { |
|
samples[srcOffset++] = data.getElem(bank, sampleOffset++); |
|
} |
|
lineOffset += scanlineStride; |
|
} |
|
return samples; |
|
} |
|
/** |
|
* Sets the data for a single pixel in the specified DataBuffer from a |
|
* primitive array of type TransferType. For a BandedSampleModel, |
|
* this will be the same as the data type, and samples are transferred |
|
* one per array element. |
|
* <p> |
|
* The following code illustrates transferring data for one pixel from |
|
* DataBuffer <code>db1</code>, whose storage layout is described by |
|
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>, |
|
* whose storage layout is described by |
|
* BandedSampleModel <code>bsm2</code>. |
|
* The transfer will generally be more efficient than using |
|
* getPixel/setPixel. |
|
* <pre> |
|
* BandedSampleModel bsm1, bsm2; |
|
* DataBufferInt db1, db2; |
|
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1), |
|
* db2); |
|
* </pre> |
|
* Using getDataElements/setDataElements to transfer between two |
|
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have |
|
* the same number of bands, corresponding bands have the same number of |
|
* bits per sample, and the TransferTypes are the same. |
|
* <p> |
|
* obj must be a primitive array of type TransferType. Otherwise, |
|
* a ClassCastException is thrown. An |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds, or if obj is not large enough to hold the pixel data. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param obj If non-null, returns the primitive array in this |
|
* object |
|
* @param data The DataBuffer containing the image data |
|
* @see #getDataElements(int, int, Object, DataBuffer) |
|
*/ |
|
public void setDataElements(int x, int y, Object obj, DataBuffer data) { |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int type = getTransferType(); |
|
int numDataElems = getNumDataElements(); |
|
int pixelOffset = y*scanlineStride + x; |
|
switch(type) { |
|
case DataBuffer.TYPE_BYTE: |
|
byte[] barray = (byte[])obj; |
|
for (int i=0; i<numDataElems; i++) { |
|
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], |
|
barray[i] & 0xff); |
|
} |
|
break; |
|
case DataBuffer.TYPE_USHORT: |
|
case DataBuffer.TYPE_SHORT: |
|
short[] sarray = (short[])obj; |
|
for (int i=0; i<numDataElems; i++) { |
|
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], |
|
sarray[i] & 0xffff); |
|
} |
|
break; |
|
case DataBuffer.TYPE_INT: |
|
int[] iarray = (int[])obj; |
|
for (int i=0; i<numDataElems; i++) { |
|
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], |
|
iarray[i]); |
|
} |
|
break; |
|
case DataBuffer.TYPE_FLOAT: |
|
float[] farray = (float[])obj; |
|
for (int i=0; i<numDataElems; i++) { |
|
data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i], |
|
farray[i]); |
|
} |
|
break; |
|
case DataBuffer.TYPE_DOUBLE: |
|
double[] darray = (double[])obj; |
|
for (int i=0; i<numDataElems; i++) { |
|
data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i], |
|
darray[i]); |
|
} |
|
break; |
|
} |
|
} |
|
/** |
|
* Sets a pixel in the DataBuffer using an int array of samples for input. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param iArray The input samples in an int array |
|
* @param data The DataBuffer containing the image data |
|
* @see #getPixel(int, int, int[], DataBuffer) |
|
*/ |
|
public void setPixel(int x, int y, int iArray[], DataBuffer data) { |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int pixelOffset = y*scanlineStride + x; |
|
for (int i=0; i<numBands; i++) { |
|
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], |
|
iArray[i]); |
|
} |
|
} |
|
/** |
|
* Sets all samples for a rectangle of pixels from an int array containing |
|
* one sample per array element. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the upper left pixel location |
|
* @param y The Y coordinate of the upper left pixel location |
|
* @param w The width of the pixel rectangle |
|
* @param h The height of the pixel rectangle |
|
* @param iArray The input samples in an int array |
|
* @param data The DataBuffer containing the image data |
|
* @see #getPixels(int, int, int, int, int[], DataBuffer) |
|
*/ |
|
public void setPixels(int x, int y, int w, int h, |
|
int iArray[], DataBuffer data) { |
|
int x1 = x + w; |
|
int y1 = y + h; |
|
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width || |
|
y < 0 || y >= height || h > height || y1 < 0 || y1 > height) |
|
{ |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
for (int k = 0; k < numBands; k++) { |
|
int lineOffset = y*scanlineStride + x + bandOffsets[k]; |
|
int srcOffset = k; |
|
int bank = bankIndices[k]; |
|
for (int i = 0; i < h; i++) { |
|
int pixelOffset = lineOffset; |
|
for (int j = 0; j < w; j++) { |
|
data.setElem(bank, pixelOffset++, iArray[srcOffset]); |
|
srcOffset += numBands; |
|
} |
|
lineOffset += scanlineStride; |
|
} |
|
} |
|
} |
|
/** |
|
* Sets a sample in the specified band for the pixel located at (x,y) |
|
* in the DataBuffer using an int for input. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to set |
|
* @param s The input sample as an int |
|
* @param data The DataBuffer containing the image data |
|
* @see #getSample(int, int, int, DataBuffer) |
|
*/ |
|
public void setSample(int x, int y, int b, int s, |
|
DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
data.setElem(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b], s); |
|
} |
|
/** |
|
* Sets a sample in the specified band for the pixel located at (x,y) |
|
* in the DataBuffer using a float for input. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to set |
|
* @param s The input sample as a float |
|
* @param data The DataBuffer containing the image data |
|
* @see #getSample(int, int, int, DataBuffer) |
|
*/ |
|
public void setSample(int x, int y, int b, |
|
float s , |
|
DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
data.setElemFloat(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b], s); |
|
} |
|
/** |
|
* Sets a sample in the specified band for the pixel located at (x,y) |
|
* in the DataBuffer using a double for input. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the pixel location |
|
* @param y The Y coordinate of the pixel location |
|
* @param b The band to set |
|
* @param s The input sample as a double |
|
* @param data The DataBuffer containing the image data |
|
* @see #getSample(int, int, int, DataBuffer) |
|
*/ |
|
public void setSample(int x, int y, int b, |
|
double s, |
|
DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
data.setElemDouble(bankIndices[b], |
|
y*scanlineStride + x + bandOffsets[b], s); |
|
} |
|
/** |
|
* Sets the samples in the specified band for the specified rectangle |
|
* of pixels from an int array containing one sample per data array element. |
|
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are |
|
* not in bounds. |
|
* @param x The X coordinate of the upper left pixel location |
|
* @param y The Y coordinate of the upper left pixel location |
|
* @param w The width of the pixel rectangle |
|
* @param h The height of the pixel rectangle |
|
* @param b The band to set |
|
* @param iArray The input sample array |
|
* @param data The DataBuffer containing the image data |
|
* @see #getSamples(int, int, int, int, int, int[], DataBuffer) |
|
*/ |
|
public void setSamples(int x, int y, int w, int h, int b, |
|
int iArray[], DataBuffer data) { |
|
// Bounds check for 'b' will be performed automatically |
|
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { |
|
throw new ArrayIndexOutOfBoundsException |
|
("Coordinate out of bounds!"); |
|
} |
|
int lineOffset = y*scanlineStride + x + bandOffsets[b]; |
|
int srcOffset = 0; |
|
int bank = bankIndices[b]; |
|
for (int i = 0; i < h; i++) { |
|
int sampleOffset = lineOffset; |
|
for (int j = 0; j < w; j++) { |
|
data.setElem(bank, sampleOffset++, iArray[srcOffset++]); |
|
} |
|
lineOffset += scanlineStride; |
|
} |
|
} |
|
private static int[] createOffsetArray(int numBands) { |
|
int[] bandOffsets = new int[numBands]; |
|
for (int i=0; i < numBands; i++) { |
|
bandOffsets[i] = 0; |
|
} |
|
return bandOffsets; |
|
} |
|
private static int[] createIndicesArray(int numBands) { |
|
int[] bankIndices = new int[numBands]; |
|
for (int i=0; i < numBands; i++) { |
|
bankIndices[i] = i; |
|
} |
|
return bankIndices; |
|
} |
|
// Differentiate hash code from other ComponentSampleModel subclasses |
|
public int hashCode() { |
|
return super.hashCode() ^ 0x2; |
|
} |
|
} |