ComponentSampleModelJAI.java
上传用户:btjssb159
上传日期:2018-01-04
资源大小:241k
文件大小:38k
源码类别:

DNA

开发平台:

Java

  1. /*
  2.  * Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without 
  5.  * modification, are permitted provided that the following conditions are met:
  6.  * 
  7.  * -Redistributions of source code must retain the above copyright notice, this 
  8.  * list of conditions and the following disclaimer.
  9.  *
  10.  * -Redistribution in binary form must reproduct the above copyright notice,
  11.  * this list of conditions and the following disclaimer in the documentation
  12.  * and/or other materials provided with the distribution.
  13.  * 
  14.  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
  15.  * be used to endorse or promote products derived from this software without
  16.  * specific prior written permission.
  17.  * 
  18.  * This software is provided "AS IS," without a warranty of any kind. ALL
  19.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  20.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  21.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  22.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  23.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  24.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  25.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  26.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  27.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  28.  * POSSIBILITY OF SUCH DAMAGES.
  29.  * 
  30.  * You acknowledge that Software is not designed,licensed or intended for use in 
  31.  * the design, construction, operation or maintenance of any nuclear facility.
  32.  */ 
  33. import java.awt.Point;
  34. import java.awt.Rectangle;
  35. import java.awt.image.ComponentSampleModel;
  36. import java.awt.image.DataBuffer;
  37. import java.awt.image.DataBufferByte;
  38. import java.awt.image.DataBufferShort;
  39. import java.awt.image.DataBufferInt;
  40. import java.awt.image.DataBufferUShort;
  41. import java.awt.image.Raster;
  42. import java.awt.image.SampleModel;
  43. import java.awt.image.WritableRaster;
  44. /**
  45.  *  This class represents image data which is stored such that each sample
  46.  *  of a pixel occupies one data element of the <code>DataBuffer</code>.  It stores the
  47.  *  N samples which make up a pixel in N separate data array elements.
  48.  *  Different bands may be in different banks of the <code>DataBuffer</code>.
  49.  *  Accessor methods are provided so that image data can be manipulated
  50.  *  directly. This class can support different kinds of interleaving, e.g.
  51.  *  band interleaving, scanline interleaving, and pixel interleaving.
  52.  *  Pixel stride is the number of data array elements between two samples
  53.  *  for the same band on the same scanline. Scanline stride is the number
  54.  *  of data array elements between a given sample and the corresponding sample
  55.  *  in the same column of the next scanline.  Band offsets denote the number
  56.  *  of data array elements from the first data array element of the bank
  57.  *  of the <code>DataBuffer</code> holding each band to the first sample of the band.
  58.  *  The bands are numbered from 0 to N-1.  This class can represent image
  59.  *  data for the dataTypes enumerated in java.awt.image.DataBuffer (all
  60.  *  samples of a given <code>ComponentSampleModel</code> are stored with the same precision)
  61.  *  . This class adds support for <code>Double</code> and <code>Float</code> data types in addition
  62.  * to those supported by the <code>ComponentSampleModel</code> class in Java 2D.
  63.  * All strides and offsets must be non-negative.
  64.  *  @see java.awt.image.ComponentSampleModel
  65.  */
  66. public class ComponentSampleModelJAI extends ComponentSampleModel {
  67.     /**
  68.      * Constructs a <code>ComponentSampleModel</code> with the specified
  69.      * parameters.  The number of bands will be given by the length of
  70.      * the bandOffsets array.  All bands will be stored in the first
  71.      * bank of the <code>DataBuffer</code>.
  72.      *
  73.      * @param dataType  The data type for storing samples.
  74.      * @param w  The width (in pixels) of the region of
  75.      * image data described.
  76.      * @param h  The height (in pixels) of the region of
  77.      * image data described.
  78.      * @param pixelStride The pixel stride of the region of image
  79.      * data described.
  80.      * @param scanlineStride The line stride of the region of image
  81.      * data described.
  82.      * @param bandOffsets The offsets of all bands.
  83.      */
  84.     public ComponentSampleModelJAI(int dataType,
  85.                                    int w, int h,
  86.                                    int pixelStride,
  87.                                    int scanlineStride,
  88.                                    int bandOffsets[]) {
  89.         super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
  90.     }
  91.     /**
  92.      * Constructs a <code>ComponentSampleModel</code> with the specified
  93.      * parameters.  The number of bands will be given by the length of
  94.      * the bandOffsets array.  Different bands may be stored in
  95.      * different banks of the <code>DataBuffer</code>.
  96.      *
  97.      * @param dataType  The data type for storing samples.
  98.      * @param w  The width (in pixels) of the region of
  99.      * image data described. 
  100.      * @param h  The height (in pixels) of the region of
  101.      * image data described.
  102.      * @param pixelStride The pixel stride of the region of image
  103.      * data described.
  104.      * @param scanlineStride The line stride of the region of image
  105.      * data described. 
  106.      * @param bankIndices The bank indices of all bands. 
  107.      * @param bandOffsets The band offsets of all bands.
  108.      */
  109.     public ComponentSampleModelJAI(int dataType,
  110.                                    int w, int h,
  111.                                    int pixelStride,
  112.                                    int scanlineStride,
  113.                                    int bankIndices[],
  114.                                    int bandOffsets[]) {
  115.         super(dataType, w, h, pixelStride, scanlineStride, 
  116.               bankIndices, bandOffsets);
  117.     }
  118.     /**
  119.      * Returns the size of the data buffer (in data elements) needed
  120.      * for a data buffer that matches this <code>ComponentSampleModel</code>.
  121.      */
  122.      private long getBufferSize() {
  123.          int maxBandOff=bandOffsets[0];
  124.          for (int i=1; i<bandOffsets.length; i++)
  125.              maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  126.          long size = 0;
  127.          if (maxBandOff >= 0)
  128.              size += maxBandOff+1;
  129.          if (pixelStride > 0)
  130.              size += pixelStride * (width-1);
  131.          if (scanlineStride > 0)
  132.              size += scanlineStride*(height-1);
  133.          return size;
  134.      }
  135.      /**
  136.       * Preserves band ordering with new step factor...
  137.       */
  138.     private int[] JAIorderBands(int orig[], int step) {
  139.         int map[] = new int[orig.length];
  140.         int ret[] = new int[orig.length];
  141.         for (int i=0; i<map.length; i++) map[i] = i;
  142.         for (int i = 0; i < ret.length; i++) {
  143.             int index = i;
  144.             for (int j = i+1; j < ret.length; j++) {
  145.                 if (orig[map[index]] > orig[map[j]]) {
  146.                     index = j;
  147.                 }
  148.             }
  149.             ret[map[index]] = i*step;
  150.             map[index]  = map[i];
  151.         }
  152.         return ret;
  153.     }
  154.     /**
  155.      * Creates a new <code>ComponentSampleModel</code> with the specified
  156.      * width and height.  The new <code>SampleModel</code> will have the same
  157.      * number of bands, storage data type, interleaving scheme, and
  158.      * pixel stride as this <code>SampleModel</code>.
  159.      *
  160.      * @param w The width in pixels.
  161.      * @param h The height in pixels
  162.      */
  163.     public SampleModel createCompatibleSampleModel(int w, int h) {
  164.         SampleModel ret=null;
  165.         long size;
  166.         int minBandOff=bandOffsets[0];
  167.         int maxBandOff=bandOffsets[0];
  168.         for (int i=1; i<bandOffsets.length; i++) {
  169.             minBandOff = Math.min(minBandOff,bandOffsets[i]);
  170.             maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  171.         }
  172.         maxBandOff -= minBandOff;
  173.         int bands   = bandOffsets.length;
  174.         int bandOff[];
  175.         int pStride = Math.abs(pixelStride);
  176.         int lStride = Math.abs(scanlineStride);
  177.         int bStride = Math.abs(maxBandOff);
  178.         if (pStride > lStride) {
  179.             if (pStride > bStride) {
  180.                 if (lStride > bStride) { // pix > line > band
  181.                     bandOff = new int[bandOffsets.length];
  182.                     for (int i=0; i<bands; i++)
  183.                         bandOff[i] = bandOffsets[i]-minBandOff;
  184.                     lStride = bStride+1;
  185.                     pStride = lStride*h;
  186.                 } else { // pix > band > line
  187.                     bandOff = JAIorderBands(bandOffsets,lStride*h);
  188.                     pStride = bands*lStride*h;
  189.                 }
  190.             } else { // band > pix > line
  191.                 pStride = lStride*h;
  192.                 bandOff = JAIorderBands(bandOffsets,pStride*w);
  193.             }
  194.         } else {
  195.             if (pStride > bStride) { // line > pix > band
  196.                 bandOff = new int[bandOffsets.length];
  197.                 for (int i=0; i<bands; i++)
  198.                     bandOff[i] = bandOffsets[i]-minBandOff;
  199.                 pStride = bStride+1;
  200.                 lStride = pStride*w;
  201.             } else {
  202.                 if (lStride > bStride) { // line > band > pix
  203.                     bandOff = JAIorderBands(bandOffsets,pStride*w);
  204.                     lStride = bands*pStride*w;
  205.                 } else { // band > line > pix
  206.                     lStride = pStride*w;
  207.                     bandOff = JAIorderBands(bandOffsets,lStride*h);
  208.                 }
  209.             }
  210.         }
  211.         // make sure we make room for negative offsets...
  212.         int base = 0;
  213.         if (scanlineStride < 0) {
  214.             base += lStride*h;
  215.             lStride *= -1;
  216.         }
  217.         if (pixelStride    < 0) {
  218.             base += pStride*w;
  219.             pStride *= -1;
  220.         }
  221.         for (int i=0; i<bands; i++)
  222.             bandOff[i] += base;
  223.         return new ComponentSampleModelJAI(dataType, w, h, pStride,
  224.                                            lStride, bankIndices, bandOff);
  225.     }
  226.     /**
  227.      * This creates a new <code>ComponentSampleModel</code> with a subset of the bands
  228.      * of this <code>ComponentSampleModel</code>.  The new <code>ComponentSampleModel</code> can be
  229.      * used with any <code>DataBuffer</code> that the existing <code>ComponentSampleModel</code>
  230.      * can be used with.  The new <code>ComponentSampleModel</code>/<code>DataBuffer</code>
  231.      * combination will represent an image with a subset of the bands
  232.      * of the original <code>ComponentSampleModel</code>/<code>DataBuffer</code> combination.
  233.      *
  234.      * @param bands subset of bands of this <code>ComponentSampleModel</code>
  235.      */
  236.     public SampleModel createSubsetSampleModel(int bands[]) {
  237.         int newBankIndices[] = new int[bands.length];
  238.         int newBandOffsets[] = new int[bands.length];
  239.         for (int i=0; i<bands.length; i++) {
  240.             int b = bands[i];
  241.             newBankIndices[i] = bankIndices[b];
  242.             newBandOffsets[i] = bandOffsets[b];
  243.         }
  244.         return new ComponentSampleModelJAI(this.dataType, width, height,
  245.                                            this.pixelStride,
  246.                                            this.scanlineStride,
  247.                                            newBankIndices,
  248.                                            newBandOffsets);
  249.     }
  250.     /**
  251.      * Creates a <code>DataBuffer</code> that corresponds to this <code>ComponentSampleModel</code>.
  252.      * The <code>DataBuffer</code>'s data type, number of banks, and size
  253.      * will be consistent with this <code>ComponentSampleModel</code>.
  254.      */
  255.     public DataBuffer createDataBuffer() {
  256.         DataBuffer dataBuffer = null;
  257.         int size = (int)getBufferSize();
  258.         switch (dataType) {
  259.         case DataBuffer.TYPE_BYTE:
  260.             dataBuffer = new DataBufferByte(size, numBanks);
  261.             break;
  262.         case DataBuffer.TYPE_USHORT:
  263.             dataBuffer = new DataBufferUShort(size, numBanks);
  264.             break;
  265.         case DataBuffer.TYPE_INT:
  266.             dataBuffer = new DataBufferInt(size, numBanks);
  267.             break;
  268.         case DataBuffer.TYPE_SHORT:
  269.             dataBuffer = new DataBufferShort(size, numBanks);
  270.             break;
  271.         case DataBuffer.TYPE_FLOAT:
  272.             dataBuffer = new DataBufferFloat(size, numBanks);
  273.             break;
  274.         case DataBuffer.TYPE_DOUBLE:
  275.             dataBuffer = new DataBufferDouble(size, numBanks);
  276.             break;
  277. default:
  278.             throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
  279.         }
  280.         return dataBuffer;
  281.     }
  282.     /** 
  283.      * Returns data for a single pixel in a primitive array of type
  284.      * TransferType.  For a <code>ComponentSampleModel</code>, this will be the same
  285.      * as the data type, and samples will be returned one per array
  286.      * element.  Generally, obj
  287.      * should be passed in as null, so that the <code>Object</code> will be created
  288.      * automatically and will be of the right primitive data type.
  289.      * <p>
  290.      * The following code illustrates transferring data for one pixel from
  291.      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is described by
  292.      * <code>ComponentSampleModel</code> <code>csm1</code>, to <code>DataBuffer</code> <code>db2</code>,
  293.      * whose storage layout is described by
  294.      * <code>ComponentSampleModel</code> <code>csm2</code>.
  295.      * The transfer will generally be more efficient than using
  296.      * getPixel/setPixel.
  297.      * <pre>
  298.      *       ComponentSampleModel csm1, csm2;
  299.      *      DataBufferInt db1, db2;
  300.      *       csm2.setDataElements(x, y,
  301.      *                            csm1.getDataElements(x, y, null, db1), db2);
  302.      * </pre>
  303.      * Using getDataElements/setDataElements to transfer between two
  304.      * <code>DataBuffer</code>/SampleModel pairs is legitimate if the <code>SampleModel</code>s have
  305.      * the same number of bands, corresponding bands have the same number of
  306.      * bits per sample, and the TransferTypes are the same.
  307.      * <p>
  308.      * @param x  The X coordinate of the pixel location.
  309.      * @param y  The Y coordinate of the pixel location.
  310.      * @param obj       If non-null, a primitive array in which to return
  311.      *                  the pixel data.
  312.      * @param data      The <code>DataBuffer</code> containing the image data.
  313.      * @throws <code>ClassCastException</code> if obj is non-null and is not
  314.      *          a primitive array of type TransferType.
  315.      * @throws <code>ArrayIndexOutOfBoundsException</code> if the coordinates
  316.      *         are not in bounds, or if obj is non-null and is not large 
  317.      *         enough to hold the pixel data. 
  318.      */
  319.     public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
  320. int type = getTransferType();
  321. int numDataElems = getNumDataElements();
  322. int pixelOffset = y*scanlineStride + x*pixelStride;
  323. switch(type) {
  324. case DataBuffer.TYPE_BYTE:
  325.     byte[] bdata;
  326.     if (obj == null)
  327. bdata = new byte[numDataElems];
  328.     else
  329. bdata = (byte[])obj;
  330.     for (int i=0; i<numDataElems; i++) {
  331. bdata[i] = (byte)data.getElem(bankIndices[i],
  332.                                               pixelOffset + bandOffsets[i]);
  333.     }
  334.     obj = (Object)bdata;
  335.     break;
  336. case DataBuffer.TYPE_USHORT:
  337.     short[] usdata;
  338.     if (obj == null)
  339. usdata = new short[numDataElems];
  340.     else
  341. usdata = (short[])obj;
  342.     for (int i=0; i<numDataElems; i++) {
  343. usdata[i] = (short)data.getElem(bankIndices[i],
  344.                                                pixelOffset + bandOffsets[i]);
  345.     }
  346.     obj = (Object)usdata;
  347.     break;
  348. case DataBuffer.TYPE_INT:
  349.     int[] idata;
  350.     if (obj == null)
  351. idata = new int[numDataElems];
  352.     else
  353. idata = (int[])obj;
  354.     for (int i=0; i<numDataElems; i++) {
  355. idata[i] = data.getElem(bankIndices[i],
  356.                                         pixelOffset + bandOffsets[i]);
  357.     }
  358.     obj = (Object)idata;
  359.     break;
  360.         case DataBuffer.TYPE_SHORT:
  361.  
  362.             short[] sdata;
  363.  
  364.             if (obj == null)
  365.                 sdata = new short[numDataElems];
  366.             else
  367.                 sdata = (short[])obj;
  368.  
  369.             for (int i=0; i<numDataElems; i++) {
  370.                 sdata[i] = (short)data.getElem(bankIndices[i],
  371.                                                pixelOffset + bandOffsets[i]);
  372.             }
  373.  
  374.             obj = (Object)sdata;
  375.             break;
  376.  
  377.         case DataBuffer.TYPE_FLOAT:
  378.  
  379.             float[] fdata;
  380.  
  381.             if (obj == null)
  382.                 fdata = new float[numDataElems];
  383.             else
  384.                 fdata = (float[])obj;
  385.  
  386.             for (int i=0; i<numDataElems; i++) {
  387.                 fdata[i] = data.getElemFloat(bankIndices[i],
  388.                                              pixelOffset + bandOffsets[i]);
  389.             }
  390.  
  391.             obj = (Object)fdata;
  392.             break;
  393.         case DataBuffer.TYPE_DOUBLE:
  394.  
  395.             double[] ddata;
  396.  
  397.             if (obj == null)
  398.                 ddata = new double[numDataElems];
  399.             else
  400.                 ddata = (double[])obj;
  401.  
  402.             for (int i=0; i<numDataElems; i++) {
  403.                 ddata[i] = data.getElemDouble(bankIndices[i],
  404.                                               pixelOffset + bandOffsets[i]);
  405.             }
  406.  
  407.             obj = (Object)ddata;
  408.             break;
  409. default:
  410.             throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
  411. }
  412. return obj;
  413.     }
  414.     /**
  415.      * Returns the pixel data for the specified rectangle of pixels in a
  416.      * primitive array of type TransferType.
  417.      * For image data supported by the Java 2D API, this
  418.      * will be one of the dataTypes supported by java.awt.image.DataBuffer.
  419.      * Data may be returned in a packed format, thus increasing efficiency
  420.      * for data transfers. Generally, obj should be passed in as null, so
  421.      * that the <code>Object</code> will be created automatically and will be of the right
  422.      * primitive data type.
  423.      * <p>
  424.      * The following code illustrates transferring data for a rectangular
  425.      * region of pixels from
  426.      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is described by
  427.      * <code>SampleModel</code> <code>sm1</code>, to <code>DataBuffer</code> <code>db2</code>, whose
  428.      * storage layout is described by <code>SampleModel</code> <code>sm2</code>.
  429.      * The transfer will generally be more efficient than using
  430.      * getPixels/setPixels.
  431.      * <pre>
  432.      *       SampleModel sm1, sm2;
  433.      *       DataBuffer db1, db2;
  434.      *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w,
  435.      *                           h, null, db1), db2);
  436.      * </pre>
  437.      * Using getDataElements/setDataElements to transfer between two
  438.      * <code>DataBuffer</code>/SampleModel pairs is legitimate if the <code>SampleModel</code>s have
  439.      * the same number of bands, corresponding bands have the same number of
  440.      * bits per sample, and the TransferTypes are the same.
  441.      * <p>
  442.      * @param x         The minimum X coordinate of the pixel rectangle.
  443.      * @param y         The minimum Y coordinate of the pixel rectangle.
  444.      * @param w         The width of the pixel rectangle.
  445.      * @param h         The height of the pixel rectangle.
  446.      * @param obj       If non-null, a primitive array in which to return
  447.      *                  the pixel data.
  448.      * @param data      The <code>DataBuffer</code> containing the image data.
  449.      * @see #getNumDataElements
  450.      * @see #getTransferType
  451.      * @see java.awt.image.DataBuffer
  452.      * @throws <code>ClassCastException</code> if obj is non-null and is not
  453.      *          a primitive array of type TransferType.
  454.      * @throws <code>ArrayIndexOutOfBoundsException</code> if the coordinates
  455.      *         are not in bounds, or if obj is non-null and is not large 
  456.      *         enough to hold the pixel data. 
  457.      */
  458.     public Object getDataElements(int x, int y, int w, int h,
  459.                                   Object obj, DataBuffer data) {
  460.  
  461.         int type = getTransferType();
  462.         int numDataElems = getNumDataElements();
  463.         int cnt = 0;
  464.         Object o = null;
  465.  
  466.         switch(type) {
  467.         case DataBuffer.TYPE_BYTE: {
  468.             byte[] btemp;
  469.             byte[] bdata;
  470.  
  471.             if (obj == null)
  472.                 bdata = new byte[numDataElems*w*h];
  473.             else
  474.                 bdata = (byte[])obj;
  475.  
  476.             for (int i=y; i<y+h; i++) {
  477.                 for (int j=x; j<x+w; j++) {
  478.                     o = getDataElements(j, i, o, data);
  479.                     btemp = (byte[])o;
  480.                     for (int k=0; k<numDataElems; k++) {
  481.                         bdata[cnt++] = btemp[k];
  482.                     }
  483.                 }
  484.             }
  485.             obj = (Object)bdata;
  486.             break;
  487.         }
  488.  
  489.         case DataBuffer.TYPE_USHORT: {
  490.  
  491.             short[] usdata;
  492.             short[] ustemp;
  493.  
  494.             if (obj == null)
  495.                 usdata = new short[numDataElems*w*h];
  496.             else
  497.                 usdata = (short[])obj;
  498.  
  499.             for (int i=y; i<y+h; i++) {
  500.                 for (int j=x; j<x+w; j++) {
  501.                     o = getDataElements(j, i, o, data);
  502.                     ustemp = (short[])o;
  503.                     for (int k=0; k<numDataElems; k++) {
  504.                         usdata[cnt++] = ustemp[k];
  505.                     }
  506.                 }
  507.             }
  508.  
  509.             obj = (Object)usdata;
  510.             break;
  511.         }
  512.         case DataBuffer.TYPE_INT: {
  513.  
  514.             int[] idata;
  515.             int[] itemp;
  516.  
  517.             if (obj == null)
  518.                 idata = new int[numDataElems*w*h];
  519.             else
  520.                 idata = (int[])obj;
  521.  
  522.             for (int i=y; i<y+h; i++) {
  523.                 for (int j=x; j<x+w; j++) {
  524.                     o = getDataElements(j, i, o, data);
  525.                     itemp = (int[])o;
  526.                     for (int k=0; k<numDataElems; k++) {
  527.                         idata[cnt++] = itemp[k];
  528.                     }
  529.                 }
  530.             }
  531.  
  532.             obj = (Object)idata;
  533.             break;
  534.         }
  535.         case DataBuffer.TYPE_SHORT: {
  536.  
  537.             short[] sdata;
  538.             short[] stemp;
  539.  
  540.             if (obj == null)
  541.                 sdata = new short[numDataElems*w*h];
  542.             else
  543.                 sdata = (short[])obj;
  544.  
  545.             for (int i=y; i<y+h; i++) {
  546.                 for (int j=x; j<x+w; j++) {
  547.                     o = getDataElements(j, i, o, data);
  548.                     stemp = (short[])o;
  549.                     for (int k=0; k<numDataElems; k++) {
  550.                         sdata[cnt++] = stemp[k];
  551.                     }
  552.                 }
  553.             }
  554.  
  555.             obj = (Object)sdata;
  556.             break;
  557.         }
  558.         case DataBuffer.TYPE_FLOAT: {
  559.  
  560.             float[] fdata;
  561.             float[] ftemp;
  562.  
  563.             if (obj == null)
  564.                 fdata = new float[numDataElems*w*h];
  565.             else
  566.                 fdata = (float[])obj;
  567.  
  568.             for (int i=y; i<y+h; i++) {
  569.                 for (int j=x; j<x+w; j++) {
  570.                     o = getDataElements(j, i, o, data);
  571.                     ftemp = (float[])o;
  572.                     for (int k=0; k<numDataElems; k++) {
  573.                         fdata[cnt++] = ftemp[k];
  574.                     }
  575.                 }
  576.             }
  577.  
  578.             obj = (Object)fdata;
  579.             break;
  580.         }
  581.         case DataBuffer.TYPE_DOUBLE: {
  582.  
  583.             double[] ddata;
  584.             double[] dtemp;
  585.  
  586.             if (obj == null)
  587.                 ddata = new double[numDataElems*w*h];
  588.             else
  589.                 ddata = (double[])obj;
  590.  
  591.             for (int i=y; i<y+h; i++) {
  592.                 for (int j=x; j<x+w; j++) {
  593.                     o = getDataElements(j, i, o, data);
  594.                     dtemp = (double[])o;
  595.                     for (int k=0; k<numDataElems; k++) {
  596.                         ddata[cnt++] = dtemp[k];
  597.                     }
  598.                 }
  599.             }
  600.  
  601.             obj = (Object)ddata;
  602.             break;
  603.         }
  604. default:
  605.             throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
  606.         }
  607.  
  608.         return obj;
  609.     }
  610.     /** 
  611.      * Sets the data for a single pixel in the specified <code>DataBuffer</code> from a
  612.      * primitive array of type TransferType.  For a <code>ComponentSampleModel</code>,
  613.      * this will be the same as the data type, and samples are transferred
  614.      * one per array element.
  615.      * <p>
  616.      * The following code illustrates transferring data for one pixel from
  617.      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is described by
  618.      * <code>ComponentSampleModel</code> <code>csm1</code>, to <code>DataBuffer</code> <code>db2</code>,
  619.      * whose storage layout is described by
  620.      * <code>ComponentSampleModel</code> <code>csm2</code>.
  621.      * The transfer will generally be more efficient than using
  622.      * getPixel/setPixel.
  623.      * <pre>
  624.      *       ComponentSampleModel csm1, csm2;
  625.      *      DataBufferInt db1, db2;
  626.      *       csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
  627.      *                            db2);
  628.      * </pre>
  629.      * Using getDataElements/setDataElements to transfer between two
  630.      * <code>DataBuffer</code>/SampleModel pairs is legitimate if the <code>SampleModel</code>s have
  631.      * the same number of bands, corresponding bands have the same number of
  632.      * bits per sample, and the TransferTypes are the same.
  633.      * <p>
  634.      * @param x  The X coordinate of the pixel location.
  635.      * @param y  The Y coordinate of the pixel location.
  636.      * @param obj       A primitive array containing pixel data.
  637.      * @param data      The <code>DataBuffer</code> containing the image data.
  638.      * @throws <code>ClassCastException</code> if obj is non-null and is not
  639.      *          a primitive array of type TransferType.
  640.      * @throws <code>ArrayIndexOutOfBoundsException</code> if the coordinates
  641.      *         are not in bounds, or if obj is non-null and is not large 
  642.      *         enough to hold the pixel data. 
  643.      */
  644.     public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  645. int type = getTransferType();
  646. int numDataElems = getNumDataElements();
  647. int pixelOffset = y*scanlineStride + x*pixelStride;
  648. switch(type) {
  649. case DataBuffer.TYPE_BYTE:
  650.     byte[] barray = (byte[])obj;
  651.     for (int i=0; i<numDataElems; i++) {
  652. data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  653.    ((int)barray[i])&0xff);
  654.     }
  655.     break;
  656. case DataBuffer.TYPE_USHORT:
  657.     short[] usarray = (short[])obj;
  658.     for (int i=0; i<numDataElems; i++) {
  659. data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  660.    ((int)usarray[i])&0xffff);
  661.     }
  662.     break;
  663. case DataBuffer.TYPE_INT:
  664.     int[] iarray = (int[])obj;
  665.     for (int i=0; i<numDataElems; i++) {
  666. data.setElem(bankIndices[i],
  667.                              pixelOffset + bandOffsets[i], iarray[i]);
  668.     }
  669.     break;
  670.         case DataBuffer.TYPE_SHORT:
  671.  
  672.             short[] sarray = (short[])obj;
  673.  
  674.             for (int i=0; i<numDataElems; i++) {
  675.                 data.setElem(bankIndices[i],
  676.                              pixelOffset + bandOffsets[i], sarray[i]);
  677.             }
  678.             break;
  679.         case DataBuffer.TYPE_FLOAT:
  680.  
  681.             float[] farray = (float[])obj;
  682.  
  683.             for (int i=0; i<numDataElems; i++) {
  684.                 data.setElemFloat(bankIndices[i],
  685.                                   pixelOffset + bandOffsets[i], farray[i]);
  686.             }
  687.             break;
  688.         case DataBuffer.TYPE_DOUBLE:
  689.  
  690.             double[] darray = (double[])obj;
  691.  
  692.             for (int i=0; i<numDataElems; i++) {
  693.                 data.setElemDouble(bankIndices[i],
  694.                                    pixelOffset + bandOffsets[i], darray[i]);
  695.             }
  696.             break;
  697. default:
  698.             throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
  699. }
  700.     }
  701.     /**
  702.      * Sets the data for a rectangle of pixels in the specified <code>DataBuffer</code>
  703.      * from a primitive array of type TransferType.  For image data supported
  704.      * by the Java 2D API, this will be one of the dataTypes supported by
  705.      * java.awt.image.DataBuffer.  Data in the array may be in a packed
  706.      * format, thus increasing efficiency for data transfers.
  707.      * <p>
  708.      * The following code illustrates transferring data for a rectangular
  709.      * region of pixels from
  710.      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is described by
  711.      * <code>SampleModel</code> <code>sm1</code>, to <code>DataBuffer</code> <code>db2</code>, whose
  712.      * storage layout is described by <code>SampleModel</code> <code>sm2</code>.
  713.      * The transfer will generally be more efficient than using
  714.      * getPixels/setPixels.
  715.      * <pre>
  716.      *       SampleModel sm1, sm2;
  717.      *       DataBuffer db1, db2;
  718.      *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w, h,
  719.      *                           null, db1), db2);
  720.      * </pre>
  721.      * Using getDataElements/setDataElements to transfer between two
  722.      * <code>DataBuffer</code>/SampleModel pairs is legitimate if the <code>SampleModel</code>s have
  723.      * the same number of bands, corresponding bands have the same number of
  724.      * bits per sample, and the TransferTypes are the same.
  725.      * <p>
  726.      * @param x         The minimum X coordinate of the pixel rectangle.
  727.      * @param y         The minimum Y coordinate of the pixel rectangle.
  728.      * @param w         The width of the pixel rectangle.
  729.      * @param h         The height of the pixel rectangle.
  730.      * @param obj       A primitive array containing pixel data.
  731.      * @param data      The <code>DataBuffer</code> containing the image data.
  732.      * @throws <code>ClassCastException</code> if obj is non-null and is not
  733.      *          a primitive array of type TransferType.
  734.      * @throws <code>ArrayIndexOutOfBoundsException</code> if the coordinates
  735.      *         are not in bounds, or if obj is non-null and is not large 
  736.      *         enough to hold the pixel data. 
  737.      * @see #getNumDataElements
  738.      * @see #getTransferType
  739.      * @see java.awt.image.DataBuffer
  740.      */
  741.     public void setDataElements(int x, int y, int w, int h,
  742.                                 Object obj, DataBuffer data) {
  743.         int cnt = 0;
  744.         Object o = null;
  745.         int type = getTransferType();
  746.         int numDataElems = getNumDataElements();
  747.  
  748.         switch(type) {
  749.  
  750.         case DataBuffer.TYPE_BYTE: {
  751.  
  752.             byte[] barray = (byte[])obj;
  753.             byte[] btemp = new byte[numDataElems];
  754.  
  755.             for (int i=y; i<y+h; i++) {
  756.                 for (int j=x; j<x+w; j++) {
  757.                     for (int k=0; k<numDataElems; k++) {
  758.                         btemp[k] = barray[cnt++];
  759.                     }
  760.  
  761.                     setDataElements(j, i, btemp, data);
  762.                 }
  763.             }
  764.             break;
  765.         }
  766.         case DataBuffer.TYPE_USHORT: {
  767.  
  768.             short[] usarray = (short[])obj;
  769.             short[] ustemp = new short[numDataElems];
  770.  
  771.             for (int i=y; i<y+h; i++) {
  772.                 for (int j=x; j<x+w; j++) {
  773.                     for (int k=0; k<numDataElems; k++) {
  774.                         ustemp[k] = usarray[cnt++];
  775.                     }
  776.                     setDataElements(j, i, ustemp, data);
  777.                 }
  778.             }
  779.             break;
  780.         }
  781.         case DataBuffer.TYPE_INT: {
  782.  
  783.             int[] iArray = (int[])obj;
  784.             int[] itemp = new int[numDataElems];
  785.  
  786.             for (int i=y; i<y+h; i++) {
  787.                 for (int j=x; j<x+w; j++) {
  788.                     for (int k=0; k<numDataElems; k++) {
  789.                         itemp[k] = iArray[cnt++];
  790.                     }
  791.  
  792.                     setDataElements(j, i, itemp, data);
  793.                 }
  794.             }
  795.             break;
  796.         }
  797.         case DataBuffer.TYPE_SHORT: {
  798.  
  799.             short[] sArray = (short[])obj;
  800.             short[] stemp = new short[numDataElems];
  801.  
  802.             for (int i=y; i<y+h; i++) {
  803.                 for (int j=x; j<x+w; j++) {
  804.                     for (int k=0; k<numDataElems; k++) {
  805.                         stemp[k] = sArray[cnt++];
  806.                     }
  807.  
  808.                     setDataElements(j, i, stemp, data);
  809.                 }
  810.             }
  811.             break;
  812.         }
  813.         case DataBuffer.TYPE_FLOAT: {
  814.  
  815.             float[] fArray = (float[])obj;
  816.             float[] ftemp = new float[numDataElems];
  817.  
  818.             for (int i=y; i<y+h; i++) {
  819.                 for (int j=x; j<x+w; j++) {
  820.                     for (int k=0; k<numDataElems; k++) {
  821.                         ftemp[k] = fArray[cnt++];
  822.                     }
  823.  
  824.                     setDataElements(j, i, ftemp, data);
  825.                 }
  826.             }
  827.             break;
  828.         }
  829.         case DataBuffer.TYPE_DOUBLE: {
  830.  
  831.             double[] dArray = (double[])obj;
  832.             double[] dtemp = new double[numDataElems];
  833.  
  834.             for (int i=y; i<y+h; i++) {
  835.                 for (int j=x; j<x+w; j++) {
  836.                     for (int k=0; k<numDataElems; k++) {
  837.                         dtemp[k] = dArray[cnt++];
  838.                     }
  839.  
  840.                     setDataElements(j, i, dtemp, data);
  841.                 }
  842.             }
  843.             break;
  844.         }
  845. default:
  846.             throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
  847.         }
  848.     }
  849.     /**
  850.      * Sets a sample in the specified band for the pixel located at (x,y)
  851.      * in the <code>DataBuffer</code> using a <code>float</code> for input.
  852.      * <code>ArrayIndexOutOfBoundsException</code> may be thrown if the coordinates are
  853.      * not in bounds.
  854.      * @param x  The X coordinate of the pixel location.
  855.      * @param y  The Y coordinate of the pixel location.
  856.      * @param b  The band to set.
  857.      * @param s  The input sample as a <code>float</code>.
  858.      * @param data  The <code>DataBuffer</code> containing the image data.
  859.      *
  860.      * @throws <code>ArrayIndexOutOfBoundsException</code> if coordinates are not in bounds
  861.      */
  862.     public void setSample(int x, int y, int b,
  863.                           float s,
  864.                           DataBuffer data) {
  865.         data.setElemFloat(bankIndices[b],
  866.                           y*scanlineStride + x*pixelStride + bandOffsets[b],
  867.                           s);
  868.     }
  869.     /**
  870.      * Returns the sample in a specified band
  871.      * for the pixel located at (x,y) as a <code>float</code>.
  872.      * <code>ArrayIndexOutOfBoundsException</code> may be thrown if the coordinates are
  873.      * not in bounds.
  874.      * @param x  The X coordinate of the pixel location.
  875.      * @param y  The Y coordinate of the pixel location.
  876.      * @param b  The band to return.
  877.      * @param data  The <code>DataBuffer</code> containing the image data.
  878.      * @return sample   The floating point sample value
  879.      * @throws <code>ArrayIndexOutOfBoundsException</code> if coordinates are not in bounds
  880.      */
  881.     public float getSampleFloat(int x, int y, int b,
  882.                                 DataBuffer data) {
  883.         float sample =
  884.             data.getElemFloat(bankIndices[b],
  885.                               y*scanlineStride + x*pixelStride +
  886.                               bandOffsets[b]);
  887.         return sample;
  888.     }
  889.     /**
  890.      * Sets a sample in the specified band for the pixel located at (x,y)
  891.      * in the <code>DataBuffer</code> using a <code>double</code> for input.
  892.      * <code>ArrayIndexOutOfBoundsException</code> may be thrown if the coordinates are
  893.      * not in bounds.
  894.      * @param x  The X coordinate of the pixel location.
  895.      * @param y  The Y coordinate of the pixel location.
  896.      * @param b  The band to set.
  897.      * @param s  The input sample as a <code>double</code>.
  898.      * @param data  The <code>DataBuffer</code> containing the image data.
  899.      *
  900.      * @throws <code>ArrayIndexOutOfBoundsException</code> if coordinates are not in bounds
  901.      */
  902.     public void setSample(int x, int y, int b,
  903.                           double s,
  904.                           DataBuffer data) {
  905.         data.setElemDouble(bankIndices[b],
  906.                            y*scanlineStride + x*pixelStride + bandOffsets[b],
  907.                            s);
  908.     }
  909.     /**
  910.      * Returns the sample in a specified band
  911.      * for a pixel located at (x,y) as a <code>double</code>.
  912.      * <code>ArrayIndexOutOfBoundsException</code> may be thrown if the coordinates are
  913.      * not in bounds.
  914.      * @param x  The X coordinate of the pixel location.
  915.      * @param y  The Y coordinate of the pixel location.
  916.      * @param b  The band to return.
  917.      * @param data  The <code>DataBuffer</code> containing the image data.
  918.      * @return sample   The <code>double</code> sample value
  919.      * @throws <code>ArrayIndexOutOfBoundsException</code> if coordinates are not in bounds
  920.      */
  921.     public double getSampleDouble(int x, int y, int b,
  922.                                   DataBuffer data) {
  923.         double sample =
  924.             data.getElemDouble(bankIndices[b],
  925.                                y*scanlineStride + x*pixelStride +
  926.                                bandOffsets[b]);
  927.         return sample;
  928.     }
  929.     /**
  930.      * Returns all samples for a rectangle of pixels in a <code>double</code>
  931.      * array, one sample per array element.
  932.      * <code>ArrayIndexOutOfBoundsException</code> may be thrown if the coordinates are
  933.      * not in bounds.
  934.      * @param x         The X coordinate of the upper left pixel location.
  935.      * @param y         The Y coordinate of the upper left pixel location.
  936.      * @param w         The width of the pixel rectangle.
  937.      * @param h         The height of the pixel rectangle.
  938.      * @param dArray    If non-null, returns the samples in this array.
  939.      * @param data      The <code>DataBuffer</code> containing the image data.
  940.      * @throws <code>ArrayIndexOutOfBoundsException</code> if coordinates are not in bounds
  941.      */
  942.     public double[] getPixels(int x, int y, int w, int h,
  943.                               double dArray[], DataBuffer data) {
  944.         double pixels[];
  945.         int    Offset = 0;
  946.  
  947.         if (dArray != null)
  948.             pixels = dArray;
  949.         else
  950.             pixels = new double[numBands * w * h];
  951.  
  952.         for (int i=y; i<(h+y); i++) {
  953.             for (int j=x; j<(w+x); j++) {
  954.                 for (int k=0; k<numBands; k++) {
  955.                     pixels[Offset++] = getSampleDouble(j, i, k, data);
  956.                 }
  957.             }
  958.         }
  959.  
  960.         return pixels;
  961.     }
  962.     /** Returns a <code>String</code> containing the values of all valid fields. */
  963.     public String toString() {
  964.         String ret =  "ComponentSampleModelJAI: " +
  965.                        "  dataType=" + this.getDataType() +
  966.                        "  numBands=" + this.getNumBands() +
  967.                        "  width=" +this.getWidth() +
  968.                        "  height=" +this.getHeight() +
  969.                        "  bandOffsets=[ ";
  970.         for (int i = 0; i < numBands; i++) {
  971.             ret += this.getBandOffsets()[i] + " ";
  972.         }
  973.         ret += "]";
  974.         return ret;
  975.     }
  976. }