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;
       }
     }
   }
   

Reply via email to