I found a problem in the SinglePixelPackedSampleModel. The
getDataElements() method was using the Buffers helper class (which I
would like to get rid of anyway), which in turn is not made for
accessing arbitrary data buffer classes, but only a handful of specific
subclasses. I reimplemented that so that it doesn't check for the
runtime type of the DataBuffer, but instead checks the transfer type of
the DataBuffer and can work with any DataBuffer subclass.
I also fixed the formatting in setDataElements() and removed one
'optimized' getDataElements() method, which isn't really any better (and
Sun does not override this either).
2007-02-08 Roman Kennke <[EMAIL PROTECTED]>
* java/awt/image/SinglePixelPackedSampleModel.java
(getDataElements(int,int,Object,DataBuffer)):
Replace DataBuffer using method with simple
switch. This does not check for the exact type (class) of the
DataBuffer but instead checks the transfer type.
(getDataElements(int,int,int,intObject,DataBuffer)): Removed.
(setDataElements): Fixed indentation.
(setPixels): Removed unused statement.
/Roman
Index: java/awt/image/SinglePixelPackedSampleModel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/image/SinglePixelPackedSampleModel.java,v
retrieving revision 1.15
diff -u -1 -5 -r1.15 SinglePixelPackedSampleModel.java
--- java/awt/image/SinglePixelPackedSampleModel.java 22 Nov 2006 15:18:32 -0000 1.15
+++ java/awt/image/SinglePixelPackedSampleModel.java 8 Feb 2007 15:10:41 -0000
@@ -241,97 +241,63 @@
int numBands = bands.length;
int[] bitMasks = new int[numBands];
for (int b = 0; b < numBands; b++)
bitMasks[b] = this.bitMasks[bands[b]];
return new SinglePixelPackedSampleModel(dataType, width, height,
scanlineStride, bitMasks);
}
public Object getDataElements(int x, int y, Object obj,
DataBuffer data)
{
- int offset = scanlineStride*y + x + data.getOffset();
-
- return Buffers.getData(data, offset, obj,
- 0, // destination offset,
- 1 // length
- );
- }
-
- /**
- * This is a more efficient implementation of the default implementation in
- * the super class.
- * @param x The x-coordinate of the pixel rectangle to store in
- * <code>obj</code>.
- * @param y The y-coordinate of the pixel rectangle to store in
- * <code>obj</code>.
- * @param w The width of the pixel rectangle to store in <code>obj</code>.
- * @param h The height of the pixel rectangle to store in <code>obj</code>.
- * @param obj The primitive array to store the pixels into or null to force
- * creation.
- * @param data The DataBuffer that is the source of the pixel data.
- * @return The primitive array containing the pixel data.
- * @see java.awt.image.SampleModel#getDataElements(int, int, int, int,
- * java.lang.Object, java.awt.image.DataBuffer)
- */
- public Object getDataElements(int x, int y, int w, int h, Object obj,
- DataBuffer data)
- {
- int size = w*h;
- int dataSize = size;
- Object pixelData = null;
- switch (getTransferType())
- {
+ int type = getTransferType();
+ Object ret = null;
+ switch (type)
+ {
case DataBuffer.TYPE_BYTE:
- pixelData = ((DataBufferByte) data).getData();
- if (obj == null) obj = new byte[dataSize];
+ {
+ byte[] in = (byte[]) obj;
+ if (in == null)
+ in = new byte[1];
+ in[0] = (byte) data.getElem(x + y * scanlineStride);
+ ret = in;
+ }
break;
- case DataBuffer.TYPE_USHORT:
- pixelData = ((DataBufferUShort) data).getData();
- if (obj == null) obj = new short[dataSize];
- break;
- case DataBuffer.TYPE_INT:
- pixelData = ((DataBufferInt) data).getData();
- if (obj == null) obj = new int[dataSize];
- break;
- default:
- // Seems like the only sensible thing to do.
- throw new ClassCastException();
- }
- if(x == 0 && scanlineStride == w)
- {
- // The full width need to be copied therefore we can copy in one shot.
- System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj,
- 0, size);
- }
- else
- {
- // Since we do not need the full width we need to copy line by line.
- int outOffset = 0;
- int dataOffset = scanlineStride*y + x + data.getOffset();
- for (int yy = y; yy<(y+h); yy++)
+ case DataBuffer.TYPE_USHORT:
+ {
+ short[] in = (short[]) obj;
+ if (in == null)
+ in = new short[1];
+ in[0] = (short) data.getElem(x + y * scanlineStride);
+ ret = in;
+ }
+ break;
+ case DataBuffer.TYPE_INT:
{
- System.arraycopy(pixelData, dataOffset, obj, outOffset, w);
- dataOffset += scanlineStride;
- outOffset += w;
+ int[] in = (int[]) obj;
+ if (in == null)
+ in = new int[1];
+ in[0] = data.getElem(x + y * scanlineStride);
+ ret = in;
}
+ break;
}
- return obj;
+ return ret;
}
/**
* Returns an array containing the samples for the pixel at (x, y) in the
* specified data buffer. If <code>iArray</code> is not <code>null</code>,
* it will be populated with the sample values and returned as the result of
* this function (this avoids allocating a new array instance).
*
* @param x the x-coordinate of the pixel.
* @param y the y-coordinate of the pixel.
* @param iArray an array to populate with the sample values and return as
* the result (if <code>null</code>, a new array will be allocated).
* @param data the data buffer (<code>null</code> not permitted).
*
* @return The pixel sample values.
@@ -402,54 +368,53 @@
* @param data the data buffer (<code>null</code> not permitted).
*
* @return The sample value.
*
* @throws NullPointerException if <code>data</code> is <code>null</code>.
*/
public int getSample(int x, int y, int b, DataBuffer data)
{
int offset = scanlineStride*y + x;
int samples = data.getElem(offset);
return (samples & bitMasks[b]) >>> bitOffsets[b];
}
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
-
int transferType = getTransferType();
- switch (transferType)
- {
- case DataBuffer.TYPE_BYTE:
- {
- byte[] in = (byte[]) obj;
- data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xff);
- break;
- }
- case DataBuffer.TYPE_USHORT:
- {
- short[] in = (short[]) obj;
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ byte[] in = (byte[]) obj;
+ data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xff);
+ }
+ break;
+ case DataBuffer.TYPE_USHORT:
+ {
+ short[] in = (short[]) obj;
data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xffff);
- break;
- }
- case DataBuffer.TYPE_INT:
- {
- int[] in = (int[]) obj;
+ }
+ break;
+ case DataBuffer.TYPE_INT:
+ {
+ int[] in = (int[]) obj;
data.setElem(y * scanlineStride + x, in[0]);
break;
- }
- }
- }
+ }
+ }
+ }
/**
* Sets the samples for the pixel at (x, y) in the specified data buffer to
* the specified values.
*
* @param x the x-coordinate of the pixel.
* @param y the y-coordinate of the pixel.
* @param iArray the sample values (<code>null</code> not permitted).
* @param data the data buffer (<code>null</code> not permitted).
*
* @throws NullPointerException if either <code>iArray</code> or
* <code>data</code> is <code>null</code>.
*/
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
@@ -467,31 +432,30 @@
* implementation of the super class. It copies the pixel components directly
* from the input array instead of creating a intermediate buffer.
* @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
* @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
* @param w The width of the pixel rectangle in <code>obj</code>.
* @param h The height of the pixel rectangle in <code>obj</code>.
* @param iArray The primitive array containing the pixels to set.
* @param data The DataBuffer to store the pixels into.
* @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[],
* java.awt.image.DataBuffer)
*/
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++)
{
int offset = scanlineStride*yy + x;
for (int xx=x; xx<(x+w); xx++)
{
int samples = 0;
for (int b = 0; b < numBands; b++)
samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
data.setElem(0, offset, samples);
inOffset += numBands;
offset += 1;
}
}
}