home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / image / ComponentSampleModel.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  23.0 KB  |  695 lines

  1. /*
  2.  * @(#)ComponentSampleModel.java    1.14 98/03/18
  3.  *
  4.  * Copyright 1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. /* ****************************************************************
  16.  ******************************************************************
  17.  ******************************************************************
  18.  *** COPYRIGHT (c) Eastman Kodak Company, 1997
  19.  *** As  an unpublished  work pursuant to Title 17 of the United
  20.  *** States Code.  All rights reserved.
  21.  ******************************************************************
  22.  ******************************************************************
  23.  ******************************************************************/
  24.  
  25. package java.awt.image;
  26.  
  27. /**
  28.  *  This class extends SampleModel.  It stores the N samples which
  29.  *  make up a pixel in N separate data array elements all of which
  30.  *  are in the same bank of a dataBuffer. All data array elements reside
  31.  *  in the first bank of a DataBuffer. Each sample occupies one data
  32.  *  array element. Accessor methods are 
  33.  *  provided so that image data can be manipulated directly. This class can
  34.  *  support different kinds of interleaving. Pixelstride is the number of
  35.  *  data array elements between two samples for the same band on the same
  36.  *  scanline. Scanlinestride is the number of data array elements between
  37.  *  a given sample and the sample in the same column of the next scanline.
  38.  *  Band offsets denotes the number of data array elements to the start
  39.  *  of each band in a pixel. The bands are numbered from 0 to n-1. 
  40.  */
  41.  
  42. public class ComponentSampleModel extends SampleModel
  43. {
  44.     /** Offsets for all bands in data array elements. */
  45.     private int bandOffsets[]; 
  46.     
  47.     /**
  48.      *  Line stride (in data array elements) of the region of image
  49.      *  data described by this ComponentSampleModel.
  50.      */
  51.     private int scanlineStride;  
  52.     
  53.     /** Pixel stride (in data array elements) of the region of image
  54.      *  data described by this ComponentSampleModel.
  55.      */
  56.     private int pixelStride;
  57.    
  58.     /** A tag specifying the data type.  Tags defined in DataBuffer. */
  59.     private int dataType;
  60.  
  61.     static private native void initIDs();
  62.     static {
  63.         ColorModel.loadLibraries();
  64.         initIDs();
  65.     }
  66.  
  67.     /**
  68.      * Constructs a ComponentSampleModel with the specified parameters.
  69.      * The number of bands will be given by the length of the bandOffsets array.
  70.      * @param dataType     The data type for storing samples.
  71.      * @param w     The width (in pixels) of the region of
  72.      * image data described. 
  73.      * @param h     The height (in pixels) of the region of
  74.      * image data described.
  75.      * @param pixelStride The pixel stride of the region of image
  76.      * data described.    
  77.      * @param scanlineStride The line stride of the region of image
  78.      * data described. 
  79.      * @param bandOffsets The offsets of all bands. 
  80.      */
  81.     public ComponentSampleModel(int dataType, 
  82.                                 int w, int h,
  83.                                 int pixelStride, 
  84.                                 int scanlineStride, 
  85.                                 int bandOffsets[]) {
  86.     super(dataType, w, h, bandOffsets.length);
  87.     this.dataType = dataType;
  88.     this.pixelStride = pixelStride;
  89.     this.scanlineStride  = scanlineStride;
  90.     this.bandOffsets = (int[])bandOffsets.clone();
  91.     }
  92.  
  93.     
  94.     /** 
  95.      * Returns the size of the data buffer (in data elements) needed
  96.      * for a data buffer that matches this ComponentSampleModel.
  97.      */
  98.      private long getBufferSize() {
  99.          int maxBandOff=bandOffsets[0];
  100.          for (int i=1; i<bandOffsets.length; i++)
  101.              maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  102.  
  103.          long size = 0;
  104.          if (maxBandOff >= 0)
  105.              size += maxBandOff+1;
  106.          if (pixelStride > 0)
  107.              size += pixelStride * (width-1);
  108.          if (scanlineStride > 0)
  109.              size += scanlineStride*(height-1);
  110.          return size;
  111.      }
  112.  
  113.      /**
  114.       * Sorts band offsets so that they are in min to max order
  115.       */
  116.      private int []orderBands(int orig[], int step) {
  117.         int ret[] = (int[])orig.clone();
  118.  
  119.         for (int i = 0; i < ret.length; i++) {
  120.             int index = i;
  121.             for (int j = i+1; j < ret.length; j++) {
  122.                if (ret[index] > ret[j]) {
  123.                    index = j;
  124.                }
  125.             }
  126.             int tmp = ret[index];
  127.             ret[index] = ret[i];
  128.             ret[i] = tmp;
  129.         }
  130.         return ret;
  131.     }
  132.  
  133.     /**
  134.      * This creates a new ComponentSampleModel with the specified
  135.      * width and height.  
  136.      */
  137.     public SampleModel createCompatibleSampleModel(int w, int h) {
  138.         SampleModel ret=null;
  139.         long size;
  140.         int minBandOff=bandOffsets[0];
  141.         int maxBandOff=bandOffsets[0];
  142.         for (int i=1; i<bandOffsets.length; i++) {
  143.             minBandOff = Math.min(minBandOff,bandOffsets[i]);
  144.             maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  145.         }
  146.         maxBandOff -= minBandOff;
  147.  
  148.         int bands   = bandOffsets.length;
  149.         int bandOff[];
  150.         int pStride = Math.abs(pixelStride);
  151.         int lStride = Math.abs(scanlineStride);
  152.         int bStride = Math.abs(maxBandOff);
  153.  
  154.         if (pStride > lStride) {
  155.             if (pStride > bStride) {
  156.                 if (lStride > bStride) { // pix > line > band
  157.                     bandOff = new int[bandOffsets.length];
  158.                     for (int i=0; i<bands; i++)
  159.                         bandOff[i] = bandOffsets[i]-minBandOff;
  160.                     lStride = bStride+1;
  161.                     pStride = lStride*h;
  162.                 } else { // pix > band > line
  163.                     bandOff = orderBands(bandOffsets,lStride*h);
  164.                     pStride = bands*lStride*h;
  165.                 }
  166.             } else { // band > pix > line
  167.                 pStride = lStride*h;
  168.                 bandOff = orderBands(bandOffsets,pStride*w);
  169.             }
  170.         } else {
  171.             if (pStride > bStride) { // line > pix > band
  172.                 bandOff = new int[bandOffsets.length];
  173.                 for (int i=0; i<bands; i++)
  174.                     bandOff[i] = bandOffsets[i]-minBandOff;
  175.                 pStride = bStride+1;
  176.                 lStride = pStride*w;
  177.             } else {
  178.                 if (lStride > bStride) { // line > band > pix
  179.                     bandOff = orderBands(bandOffsets,pStride*w);
  180.                     lStride = bands*pStride*w;
  181.                 } else { // band > line > pix
  182.                     lStride = pStride*w;
  183.                     bandOff = orderBands(bandOffsets,lStride*h);
  184.                 }
  185.             }
  186.         }
  187.  
  188.         // make sure we make room for negative offsets...
  189.         int base = 0;
  190.         if (scanlineStride < 0) {
  191.             base += lStride*h;
  192.             lStride *= -1;
  193.         }
  194.         if (pixelStride    < 0) {
  195.             base += pStride*w;
  196.             pStride *= -1;
  197.         }
  198.  
  199.         for (int i=0; i<bands; i++)
  200.             bandOff[i] += base;
  201.         return new ComponentSampleModel(dataType, w, h, pStride,
  202.                                         lStride, bandOff);
  203.     }
  204.  
  205.     /**
  206.      * This creates a new ComponentSampleModel with the specified
  207.      * width and height and with a subset of the bands of this
  208.      * ComponentSampleModel.
  209.      */
  210.     public SampleModel createSubsetSampleModel(int w, int h, int bands[]) {
  211.         if ((w!=width) || (h!=height)) {
  212.             SampleModel sm = createCompatibleSampleModel(w, h);
  213.             return sm.createSubsetSampleModel(w, h, bands);
  214.         } else {
  215.             int newBandOffsets[] = new int[bands.length];
  216.             for (int i=0; i<bands.length; i++)
  217.                 newBandOffsets[i] = bandOffsets[bands[i]];
  218.             return new ComponentSampleModel(this.dataType, w, h,
  219.                                             this.pixelStride,
  220.                                             this.scanlineStride,
  221.                                             newBandOffsets);
  222.         }
  223.     }
  224.  
  225.     /**
  226.      * Creates a DataBuffer that corresponds to this ComponentSampleModel.
  227.      * The DataBuffer's width and height will match this ComponentSampleModel's.
  228.      */
  229.     public DataBuffer createCompatibleDataBuffer() {
  230.         DataBuffer dataBuffer = null;
  231.  
  232.         int size = (int)getBufferSize();
  233.         switch (dataType) {
  234.         case DataBuffer.BYTE_DATA:
  235.             dataBuffer = new DataBufferByte(size);
  236.             break;
  237.         case DataBuffer.SHORT_DATA:
  238.             dataBuffer = new DataBufferShort(size);
  239.             break;
  240.         case DataBuffer.INT_DATA:
  241.             dataBuffer = new DataBufferInt(size);
  242.             break;       
  243.         }
  244.  
  245.         return dataBuffer;
  246.     }
  247.  
  248.  
  249.     /** 
  250.      * Creates a DataBuffer that corresponds to this ComponentSampleModel,
  251.      * with a different width and height.
  252.      */
  253.     public DataBuffer createCompatibleDataBuffer(int desiredWidth,
  254.                                                  int desiredHeight) {
  255.        DataBuffer dataBuffer = null;
  256.  
  257.         int size = (int)(desiredWidth*desiredHeight*numBands);
  258.         switch (dataType) {
  259.         case DataBuffer.BYTE_DATA:
  260.             dataBuffer = new DataBufferByte(size);
  261.             break;
  262.         case DataBuffer.SHORT_DATA:
  263.             dataBuffer = new DataBufferShort(size);
  264.             break;
  265.         case DataBuffer.INT_DATA:
  266.             dataBuffer = new DataBufferInt(size);
  267.             break;
  268.         }
  269.         return dataBuffer;
  270.     }
  271.  
  272.     /** Gets offset of the first band of pixel (x,y).
  273.      *  A sample of the first band can be retrieved from a dataBuffer
  274.      *  data with a ComponentSampleModel csm as
  275.      * <pre>
  276.      *        data.getElem(csm.getOffset(x, y));
  277.      * </pre>
  278.      */
  279.     public long getOffset(int x, int y) {
  280.         long offset = y*scanlineStride + x*pixelStride;
  281.         return offset;
  282.     }
  283.  
  284.     /** Gets offset for band b of pixel (x,y).
  285.      *  A sample of band b can be retrieved from a dataBuffer data with a
  286.      *  ComponentSampleModel csm as
  287.      * <pre>
  288.      *       data.getElem(csm.getOffset(x, y, b));
  289.      * </pre>
  290.      */
  291.     public long getOffset(int x, int y, int b) {
  292.         long offset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  293.         return offset;
  294.     }
  295.  
  296.     /** Returns the size in bits of samples for all bands. */
  297.     public int[] getSampleSize() {
  298.         int sampleSize[] = new int [numBands];
  299.         int sizeInBits = 0;
  300.         switch (dataType) {
  301.         case DataBuffer.BYTE_DATA:
  302.             sizeInBits = 8;
  303.             break;
  304.         case DataBuffer.SHORT_DATA:
  305.             sizeInBits = 16;
  306.             break;
  307.         case DataBuffer.INT_DATA:
  308.             sizeInBits = 32;
  309.             break;
  310.         }
  311.  
  312.         for (int i=0; i<numBands; i++)
  313.             sampleSize[i] = sizeInBits;
  314.  
  315.         return sampleSize;
  316.     }
  317.  
  318.     /** Returns the size in bits of samples for the specified band. */
  319.     public int getSampleSize(int band) {
  320.         int sampleSize = 0;
  321.         switch (dataType) {
  322.         case DataBuffer.BYTE_DATA:
  323.             sampleSize = 8;
  324.             break;
  325.         case DataBuffer.SHORT_DATA:
  326.             sampleSize = 16;
  327.             break;
  328.         case DataBuffer.INT_DATA:
  329.             sampleSize = 32;
  330.             break;
  331.         }
  332.         return sampleSize;
  333.     }
  334.  
  335.     /**
  336.      * Gets the difference, in data array elements, between a sample of
  337.      * fromBand and a sample of toBand for the same pixel.
  338.      */
  339.     public long getDifference(int fromBand, int toBand) {
  340.         return bandOffsets[toBand] - bandOffsets[fromBand];
  341.     }
  342.  
  343.     /** Returns the band offset of all bands. */
  344.     public int [] getBandOffsets() {
  345.         return (int[])bandOffsets.clone();
  346.     }
  347.  
  348.     /** Returns the scanline stride of this ComponentSampleModel. */ 
  349.     public int getScanlineStride() {
  350.         return scanlineStride;
  351.     }
  352.  
  353.     /** Returns the pixel stride of this ComponentSampleModel. */ 
  354.     public int getPixelStride() {
  355.         return pixelStride;
  356.     }
  357.  
  358.     /**
  359.      * Returns the number of data elements required to store
  360.      * one pixel. For a ComponentSampleModel this is identical to the
  361.      * number of bands.
  362.      */ 
  363.     public int getNumDataElements() {
  364.     return getNumBands();
  365.     }
  366.  
  367.     /**
  368.      * Returns the transfer type of the underlying data. For a
  369.      * ComponentSampleModel, this is identical to the dataType.
  370.      */
  371.     public int getTransferType() {
  372.     return dataType;
  373.     }
  374.     
  375.     /** 
  376.      * Returns the pixel data in an array of primitives that can be byte,
  377.      * short or int. Which primitive type is returned depends on
  378.      * the transfer type. Data is returned in the packed format,
  379.      * thus increasing efficiency for data transfers. Generally, obj
  380.      * should be passed in as null, so that the Object will be created
  381.      * automatically and will be of the right primitive data type.
  382.      * <pre>
  383.      *          ComponentSampleModel csm1, csm2;
  384.      *         DataBufferInt db1, db2;
  385.      *          csm2.setPixelData(x, y, csm1.getPixelData(x, y, null, db1), db2);
  386.      * </pre>
  387.      * @param x     The X coordinate of the pixel location.
  388.      * @param y     The Y coordinate of the pixel location.
  389.      * @param obj       If non-null, returns the primitive array in this object.
  390.      * @param data      The DataBuffer containing the image data.
  391.      */
  392.     public Object getPixelData(int x, int y, Object obj, DataBuffer data) {
  393.  
  394.     int type = getTransferType();
  395.     int numDataElems = getNumDataElements();
  396.     int pixelOffset = y*scanlineStride + x*pixelStride;
  397.     
  398.     switch(type) {
  399.  
  400.     case DataBuffer.BYTE_DATA:
  401.  
  402.         byte[] bdata;
  403.         
  404.         if (obj == null)
  405.         bdata = new byte[numDataElems];
  406.         else
  407.         bdata = (byte[])obj;
  408.         
  409.         for (int i=0; i<numDataElems; i++) {
  410.         bdata[i] = (byte)data.getElem(pixelOffset + bandOffsets[i]);
  411.         }
  412.  
  413.         obj = (Object)bdata;
  414.         break;
  415.         
  416.     case DataBuffer.SHORT_DATA:
  417.  
  418.         short[] sdata;
  419.         
  420.         if (obj == null)
  421.         sdata = new short[numDataElems];
  422.         else
  423.         sdata = (short[])obj;
  424.         
  425.         for (int i=0; i<numDataElems; i++) {
  426.         sdata[i] = (short)data.getElem(pixelOffset + bandOffsets[i]);
  427.         }
  428.  
  429.         obj = (Object)sdata;
  430.         break;
  431.  
  432.     case DataBuffer.INT_DATA:
  433.  
  434.         int[] idata;
  435.         
  436.         if (obj == null)
  437.         idata = new int[numDataElems];
  438.         else
  439.         idata = (int[])obj;
  440.         
  441.         for (int i=0; i<numDataElems; i++) {
  442.         idata[i] = data.getElem(pixelOffset + bandOffsets[i]);
  443.         }
  444.  
  445.         obj = (Object)idata;
  446.         break;
  447.     }
  448.  
  449.     return obj;
  450.     }
  451.     
  452.     /**
  453.      * Returns all samples for the specified pixel in an int array.
  454.      * @param x     The X coordinate of the pixel location.
  455.      * @param y     The Y coordinate of the pixel location.
  456.      * @param iArray     If non-null, returns the samples in this array.
  457.      * @param data     The DataBuffer containing the image data.
  458.      */
  459.     public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  460.         int pixels[];
  461.         if (iArray != null) {
  462.            pixels = iArray;
  463.         } else {
  464.            pixels = new int [numBands];
  465.         }
  466.         int pixelOffset = y*scanlineStride + x*pixelStride;
  467.         for (int i=0; i<numBands; i++) {
  468.             pixels[i] = data.getElem(pixelOffset + bandOffsets[i]);
  469.         }
  470.         return pixels;
  471.     }
  472.  
  473.     /**
  474.      * Returns all samples for the specified rectangle of pixels in
  475.      * an int array, one sample per data array element.
  476.      * @param x     The X coordinate of the upper left pixel location.
  477.      * @param y     The Y coordinate of the upper left pixel location.
  478.      * @param w     The width of the pixel rectangle.
  479.      * @param h     The height of the pixel rectangle.
  480.      * @param iArray     If non-null, returns the samples in this array.
  481.      * @param data     The DataBuffer containing the image data.
  482.      */
  483.     public int[] getPixel(int x, int y, int w, int h,
  484.               int iArray[], DataBuffer data) {
  485.         int pixels[];
  486.         if (iArray != null) {
  487.            pixels = iArray;
  488.         } else {
  489.            pixels = new int [w*h*numBands];
  490.         }
  491.         int lineOffset = y*scanlineStride + x*pixelStride;
  492.         int srcOffset = 0;
  493.          
  494.         for (int i = 0; i < h; i++) {
  495.            int pixelOffset = lineOffset;
  496.            for (int j = 0; j < w; j++) {
  497.               for (int k=0; k < numBands; k++) {
  498.                  pixels[srcOffset++] = 
  499.                     data.getElem(pixelOffset + bandOffsets[k]);
  500.               }
  501.               pixelOffset += pixelStride;
  502.            }
  503.            lineOffset += scanlineStride;
  504.         }
  505.         return pixels;
  506.     }
  507.  
  508.     /**
  509.      * Returns as int the sample in a specified band for the pixel
  510.      * located at (x,y).
  511.      * @param x     The X coordinate of the pixel location.
  512.      * @param y     The Y coordinate of the pixel location.
  513.      * @param b     The band to return.
  514.      * @param data     The DataBuffer containing the image data.
  515.      */
  516.     public int getSample(int x, int y, int b, DataBuffer data) {
  517.         int sample = data.getElem(y*scanlineStride + x*pixelStride +
  518.                      bandOffsets[b]);
  519.         return sample;
  520.     }
  521.  
  522.     /**
  523.      * Returns the samples in a specified band for the specified rectangle
  524.      * of pixels in an int array, one sample per data array element.
  525.      * @param x     The X coordinate of the upper left pixel location.
  526.      * @param y     The Y coordinate of the upper left pixel location.
  527.      * @param w     The width of the pixel rectangle.
  528.      * @param h     The height of the pixel rectangle.
  529.      * @param b     The band to return.
  530.      * @param iArray     If non-null, returns the samples in this array.
  531.      * @param data     The DataBuffer containing the image data.
  532.      */
  533.     public int[] getSample(int x, int y, int w, int h, int b,
  534.                                int iArray[], DataBuffer data) {
  535.         int samples[];
  536.         if (iArray != null) {
  537.            samples = iArray;
  538.         } else {
  539.            samples = new int [w*h];
  540.         }
  541.         int lineOffset = y*scanlineStride + x*pixelStride +  bandOffsets[b];
  542.         int srcOffset = 0;
  543.  
  544.         for (int i = 0; i < h; i++) {
  545.            int sampleOffset = lineOffset;
  546.            for (int j = 0; j < w; j++) {
  547.               samples[srcOffset++] = data.getElem(sampleOffset);
  548.               sampleOffset += pixelStride;
  549.            }
  550.            lineOffset += scanlineStride;
  551.         }
  552.         return samples;
  553.     }
  554.  
  555.     /** 
  556.      * Puts the pixel data from an Object that contains an
  557.      * array of primitives that can be byte,
  558.      * short or int. Which primitive type it contains depends on
  559.      * the transfer type. Data in the Object is in the packed format,
  560.      * thus increasing efficiency for data transfers.
  561.      * <pre>
  562.      *          ComponentSampleModel csm1, csm2;
  563.      *         DataBufferInt db1, db2;
  564.      *          csm2.setPixelData(x, y, csm1.getPixelData(x, y, null, db1), db2);
  565.      * </pre>
  566.      * @param x     The X coordinate of the pixel location.
  567.      * @param y     The Y coordinate of the pixel location.
  568.      * @param obj       If non-null, returns the primitive array in this object.
  569.      * @param data      The DataBuffer containing the image data.
  570.      */
  571.     public void setPixelData(int x, int y, Object obj, DataBuffer data) {
  572.  
  573.     int type = getTransferType();
  574.     int numDataElems = getNumDataElements();
  575.     int pixelOffset = y*scanlineStride + x*pixelStride;
  576.  
  577.     switch(type) {
  578.  
  579.     case DataBuffer.BYTE_DATA:
  580.  
  581.         byte[] barray = (byte[])obj;
  582.  
  583.         for (int i=0; i<numDataElems; i++) {
  584.         data.setElem(pixelOffset + bandOffsets[i],
  585.                ((int)barray[i])&0xff);
  586.         }
  587.         break;
  588.  
  589.     case DataBuffer.SHORT_DATA:
  590.  
  591.         short[] sarray = (short[])obj;
  592.  
  593.         for (int i=0; i<numDataElems; i++) {
  594.         data.setElem(pixelOffset + bandOffsets[i],
  595.                ((int)sarray[i])&0xffff);
  596.         }
  597.         break;
  598.  
  599.     case DataBuffer.INT_DATA:    
  600.         
  601.         int[] iarray = (int[])obj;
  602.         
  603.         for (int i=0; i<numDataElems; i++) {
  604.         data.setElem(pixelOffset + bandOffsets[i], iarray[i]);
  605.         }
  606.         break;
  607.  
  608.     }
  609.     }
  610.     
  611.     /** 
  612.      * Sets a pixel in the DataBuffer using an int array of samples for input.
  613.      * @param x     The X coordinate of the pixel location.
  614.      * @param y     The Y coordinate of the pixel location.
  615.      * @param iArray     The input samples in an int array.
  616.      * @param data     The DataBuffer containing the image data.
  617.      */
  618.     public void setPixel(int x, int y, int iArray[], DataBuffer data) {
  619.        int pixelOffset = y*scanlineStride + x*pixelStride;
  620.        for (int i=0; i<numBands; i++) {
  621.            data.setElem(pixelOffset + bandOffsets[i],iArray[i]);
  622.        }
  623.     }
  624.   
  625.     /**
  626.      * Sets all samples for a rectangle of pixels from an int array containing
  627.      * one sample per array element.
  628.      * @param x     The X coordinate of the upper left pixel location.
  629.      * @param y     The Y coordinate of the upper left pixel location.
  630.      * @param w     The width of the pixel rectangle.
  631.      * @param h         The height of the pixel rectangle.
  632.      * @param iArray     The input samples in an int array.
  633.      * @param data     The DataBuffer containing the image data.
  634.      */
  635.     public void setPixel(int x, int y, int w, int h,
  636.              int iArray[], DataBuffer data) {
  637.     
  638.         int lineOffset = y*scanlineStride + x*pixelStride;
  639.         int srcOffset = 0;
  640.  
  641.         for (int i = 0; i < h; i++) {
  642.            int pixelOffset = lineOffset;
  643.            for (int j = 0; j < w; j++) {
  644.               for (int k=0; k < numBands; k++) {
  645.                  data.setElem(pixelOffset + bandOffsets[k],
  646.                               iArray[srcOffset++]);
  647.               }
  648.               pixelOffset += pixelStride;
  649.            }
  650.            lineOffset += scanlineStride;
  651.         }
  652.     }
  653.       
  654.     /** 
  655.      * Sets a sample in the specified band for the pixel located at (x,y)
  656.      * in the DataBuffer using an int for input.
  657.      * @param x     The X coordinate of the pixel location.
  658.      * @param y     The Y coordinate of the pixel location.
  659.      * @param b     The band to set.
  660.      * @param s     The input sample as an int.
  661.      * @param data     The DataBuffer containing the image data.
  662.      */
  663.     public void setSample(int x, int y, int b, int s,
  664.                           DataBuffer data) {
  665.         data.setElem(y*scanlineStride + x*pixelStride + bandOffsets[b], s);
  666.     }
  667.  
  668.     /**
  669.      * Sets the samples in the specified band for the specified rectangle
  670.      * of pixels from an int array containing one sample per data array element.
  671.      * @param x     The X coordinate of the upper left pixel location.
  672.      * @param y     The Y coordinate of the upper left pixel location.
  673.      * @param w     The width of the pixel rectangle.
  674.      * @param h         The height of the pixel rectangle.
  675.      * @param b     The band to set.
  676.      * @param iArray     The input samples in an int array.
  677.      * @param data     The DataBuffer containing the image data.
  678.      */
  679.     public void setSample(int x, int y, int w, int h, int b,
  680.               int iArray[], DataBuffer data) {
  681.         int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  682.         int srcOffset = 0;
  683.  
  684.         for (int i = 0; i < h; i++) {
  685.            int sampleOffset = lineOffset;
  686.            for (int j = 0; j < w; j++) {
  687.               data.setElem(sampleOffset, iArray[srcOffset++]);
  688.               sampleOffset += pixelStride;
  689.            }
  690.            lineOffset += scanlineStride;
  691.         }
  692.     }
  693. }
  694.  
  695.