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 / BandedSampleModel.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  19.6 KB  |  602 lines

  1. /*
  2.  * @(#)BandedSampleModel.java    1.11 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 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 the SampleModel.  It provides more efficent
  29.  *  implementations for accessing image data than are provided in
  30.  *  SampleModel.  This class will be used when working with images 
  31.  *  which store sample data for each band in a different bank of the
  32.  *  DataBuffer. Accessor methods are provided so that image data can be
  33.  *  manipulated directly. Pixelstride is the number of
  34.  *  data array elements between two samples for the same band on the same
  35.  *  scanline. Scanlinestride is the number of data array elements between
  36.  *  a given sample and the sample in the same column of the next scanline.
  37.  *  Bank Index denotes the correspondence between a bank of the data buffer
  38.  *  and a band of image data. The image bands and the DataBuffer banks are
  39.  *  numbered from 0 to n-1.
  40.  */
  41.  
  42.  
  43. public class BandedSampleModel extends SampleModel
  44. {
  45.     /** Line stride (in data array elements) of the region of image data
  46.      *  described by this BandedSampleModel.
  47.      */
  48.     int scanlineStride;  
  49.  
  50.     /** Pixel stride (in data array elements) of the region of image
  51.      *  data described by this ComponentSampleModel.
  52.      */
  53.     int pixelStride;
  54.     
  55.     /** A tag specifying the data type.  Tags defined in DataBuffer. */
  56.     int dataType;
  57.  
  58.     /** Index for each bank storing a band of image data. */
  59.     int bankIndices[];
  60.  
  61.     /**
  62.      * Constructs a BandedSampleModel with the specified parameters.
  63.      * The number of bands will be given by the length of the bandOffsets array.
  64.      * @param dataType  The data type for storing samples.
  65.      * @param w     The width (in pixels) of the region of
  66.      * image data described. 
  67.      * @param h     The height (in pixels) of the region of image
  68.      * data described.
  69.      * @param numBands  The number of bands for the region of image data
  70.      * described.    
  71.      */
  72.     public BandedSampleModel(int dataType, int w, int h, int numBands) {
  73.     super(dataType, w, h, numBands);
  74.     this.dataType = dataType;
  75.     this.scanlineStride = width;
  76.     this.pixelStride = 1;
  77.     this.bankIndices = new int[numBands];
  78.     for (int i=0; i<numBands; i++)
  79.         bankIndices[i] = i;
  80.     }
  81.  
  82.     /**
  83.      * Constructs a BandedSampleModel with the specified parameters. 
  84.      * @param dataType  The data type for storing samples.
  85.      * @param w     The width (in pixels) of the region of
  86.      * image data described.
  87.      * @param h     The height (in pixels) of the region of
  88.      * image data described.
  89.      * @param numBands  The number of bands for the region of image data
  90.      * described.    
  91.      * @param scanlineStride The line stride of the region of the
  92.      * image data described.
  93.      * @param pixelStride The pixel stride of the region of image
  94.      * data described.
  95.      * @param bankIndices The bank index for each band.
  96.      */
  97.     public BandedSampleModel(int dataType, 
  98.                  int w, int h, int numBands,
  99.                  int scanlineStride, int pixelStride, 
  100.                  int bankIndices[]) {
  101.  
  102.     super(dataType, w, h, numBands);
  103.     if ( numBands > bankIndices.length)
  104.         throw new RasterFormatException("There are only " +
  105.                         bankIndices.length + " data banks");
  106.     this.dataType = dataType;
  107.     this.scanlineStride  = scanlineStride;
  108.     this.pixelStride = pixelStride;
  109.     this.bankIndices = bankIndices;
  110.     }
  111.  
  112.     /**
  113.      * This creates a new BandedSampleModel with the specified
  114.      * width and height.  As much as possible the 'style' of the
  115.      * current BandedSampleModel will be preserved.
  116.      */
  117.     public SampleModel createCompatibleSampleModel(int w, int h) {
  118.        SampleModel sampleModel = 
  119.           new BandedSampleModel(dataType, w, h, numBands,
  120.                 scanlineStride, pixelStride,
  121.                                 bankIndices);
  122.     return sampleModel;
  123.     }
  124.  
  125.     /**
  126.      * This creates a new SampleModel with the specified
  127.      * width and height and with a subset of the bands of this
  128.      * SampleModel. Here there will be no explicit check made to ensure that
  129.      * the subset bands asked for actually exist in the parent.
  130.      */
  131.     public SampleModel createSubsetSampleModel(int w, int h, int bands[]) {
  132.     if (bands.length > bankIndices.length)
  133.         throw new RasterFormatException("There are only " +
  134.                         bankIndices.length +
  135.                         " bands");
  136.     int newBankIndices[] = new int[bands.length];
  137.     for (int i=0; i<bands.length; i++)
  138.         newBankIndices[i] = bankIndices[bands[i]];
  139.         return new BandedSampleModel(this.dataType, w, h, bands.length,
  140.                      this.scanlineStride, this.pixelStride,
  141.                      newBankIndices);
  142.     }
  143.  
  144.     /**
  145.      * Creates a DataBuffer that corresponds to this BandedSampleModel,
  146.      * The DataBuffer's width and height will match this BandedSampleModel's.
  147.      */
  148.     public DataBuffer createCompatibleDataBuffer() {
  149.         DataBuffer dataBuffer = null;
  150.  
  151.     int size = scanlineStride * height;
  152.         switch (dataType) {
  153.         case DataBuffer.BYTE_DATA:
  154.             dataBuffer = new DataBufferByte(size, numBands);
  155.             break;
  156.         case DataBuffer.SHORT_DATA:
  157.             dataBuffer = new DataBufferShort(size, numBands);
  158.             break;
  159.         case DataBuffer.INT_DATA:
  160.             dataBuffer = new DataBufferInt(size, numBands);
  161.             break;       
  162.         }
  163.  
  164.         return dataBuffer;
  165.     }
  166.  
  167.  
  168.     /**
  169.      * Creates a DataBuffer that corresponds to this BandedSampleModel,
  170.      * with a different width and height.
  171.      */
  172.     public DataBuffer createCompatibleDataBuffer(int desiredWidth,
  173.                                                  int desiredHeight) {
  174.        DataBuffer dataBuffer = null;
  175.        int size = desiredWidth * pixelStride * desiredHeight;
  176.  
  177.        switch (dataType) {
  178.        case DataBuffer.BYTE_DATA:
  179.        dataBuffer = new DataBufferByte(size, numBands);
  180.        break;
  181.        case DataBuffer.SHORT_DATA:
  182.             dataBuffer = new DataBufferShort(size, numBands);
  183.             break;
  184.        case DataBuffer.INT_DATA:
  185.        dataBuffer = new DataBufferInt(size, numBands);
  186.        break;
  187.        }
  188.        return dataBuffer;
  189.     }
  190.     
  191.     /** Gets offset of the first band of pixel (x,y).
  192.      *  A sample of the first band can be retrieved from a dataBuffer
  193.      *  data with a BandedSampleModel bsm as
  194.      *  <pre>
  195.      *       data.getElem(bsm.getOffset(x, y));
  196.      *  </pre>
  197.      */
  198.     public long getOffset(int x, int y) {
  199.         long offset = y*scanlineStride + x*pixelStride;
  200.         return offset;
  201.     }
  202.  
  203.     /** Returns the size in bits of samples for all bands. */
  204.     public int[] getSampleSize() {
  205.         int sampleSize[] = new int [numBands];
  206.         int sizeInBits = 0;
  207.         switch (dataType) {
  208.         case DataBuffer.BYTE_DATA:
  209.             sizeInBits = 8;
  210.             break;
  211.         case DataBuffer.SHORT_DATA:
  212.             sizeInBits = 16;
  213.             break;
  214.         case DataBuffer.INT_DATA:
  215.             sizeInBits = 32;
  216.             break;
  217.         }
  218.  
  219.         for (int i=0; i<numBands; i++)
  220.             sampleSize[i] = sizeInBits;
  221.  
  222.         return sampleSize;
  223.     }
  224.  
  225.     /** Returns the size in bits of samples for the specified band. */
  226.     public int getSampleSize(int band) {
  227.         int sampleSize = 0;
  228.         switch (dataType) {
  229.         case DataBuffer.BYTE_DATA:
  230.             sampleSize = 8;
  231.             break;
  232.         case DataBuffer.SHORT_DATA:
  233.             sampleSize = 16;
  234.             break;
  235.         case DataBuffer.INT_DATA:
  236.             sampleSize = 32;
  237.             break;
  238.         }
  239.         return sampleSize;
  240.     }
  241.  
  242.     /** Returns the bank indices for all bands. */
  243.     public int [] getBankIndices() {
  244.         return bankIndices;
  245.     }
  246.  
  247.     /** Returns the scanline stride of this BandedSampleModel.  */
  248.     public int getScanlineStride() {
  249.         return scanlineStride;
  250.     }
  251.     
  252.     /** Returns the pixel stride of this BandedSampleModel. */
  253.     public int getPixelStride() {
  254.         return pixelStride;
  255.     }
  256.     
  257.     /**
  258.      * Returns the number of data elements required to store
  259.      * one pixel. For a BandedSampleModel, this is identical to the
  260.      * number of bands.
  261.      */ 
  262.     public int getNumDataElements() {
  263.     return getNumBands();
  264.     }
  265.  
  266.     /**
  267.      * Returns the transfer type of the underlying data. For a
  268.      * ComponentSampleModel, this is identical to the dataType.
  269.      */
  270.     public int getTransferType() {
  271.     return dataType;
  272.     }
  273.  
  274.     /** 
  275.      * Returns the pixel data in an array of primitives that can be byte,
  276.      * short or int. Which primitive type is returned depends on
  277.      * the transfer type. Data is returned in the packed format,
  278.      * thus increasing efficiency for data transfers. Generally, obj
  279.      * should be passed in as null, so that the Object will be created
  280.      * automatically and will be of the right primitive data type.
  281.      * <pre>
  282.      *          BandedSampleModel bsm1, bsm2;
  283.      *         DataBufferInt db1, db2;
  284.      *          bsm2.setPixelData(x, y, bsm1.getPixelData(x, y, null, db1), db2);
  285.      * </pre>
  286.      * @param x     The X coordinate of the pixel location.
  287.      * @param y     The Y coordinate of the pixel location.
  288.      * @param obj       If non-null, returns the primitive array in this object.
  289.      * @param data      The DataBuffer containing the image data.
  290.      */
  291.     public Object getPixelData(int x, int y, Object obj, DataBuffer data) {
  292.  
  293.     int type = getTransferType();
  294.     int numDataElems = getNumDataElements();
  295.     int pixelOffset = y*scanlineStride + x*pixelStride;
  296.     
  297.     switch(type) {
  298.  
  299.     case DataBuffer.BYTE_DATA:
  300.  
  301.         byte[] bdata;
  302.         
  303.         if (obj == null)
  304.         bdata = new byte[numDataElems];
  305.         else
  306.         bdata = (byte[])obj;
  307.         
  308.         for (int i=0; i<numDataElems; i++) {
  309.         bdata[i] = (byte)data.getElem(bankIndices[i], pixelOffset);
  310.         }
  311.  
  312.         obj = (Object)bdata;
  313.         break;
  314.         
  315.     case DataBuffer.SHORT_DATA:
  316.  
  317.         short[] sdata;
  318.         
  319.         if (obj == null)
  320.         sdata = new short[numDataElems];
  321.         else
  322.         sdata = (short[])obj;
  323.         
  324.         for (int i=0; i<numDataElems; i++) {
  325.         sdata[i] = (short)data.getElem(bankIndices[i], pixelOffset);
  326.         }
  327.         
  328.         obj = (Object)sdata;
  329.         break;
  330.  
  331.     case DataBuffer.INT_DATA:
  332.  
  333.         int[] idata;
  334.         
  335.         if (obj == null)
  336.         idata = new int[numDataElems];
  337.         else
  338.         idata = (int[])obj;
  339.         
  340.         for (int i=0; i<numDataElems; i++) {        
  341.         idata[i] = data.getElem(bankIndices[i], pixelOffset);
  342.         }
  343.         
  344.         obj = (Object)idata;
  345.         break;
  346.     }
  347.  
  348.     return obj;
  349.     }
  350.     
  351.     /**
  352.      * Returns all samples for the specified pixel in an int array.
  353.      * @param x     The X coordinate of the pixel location.
  354.      * @param y     The Y coordinate of the pixel location.
  355.      * @param iArray     If non-null, returns the samples in this array.
  356.      * @param data     The DataBuffer containing the image data.
  357.      */
  358.     public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  359.  
  360.         int pixels[];
  361.  
  362.     if (iArray != null) 
  363.            pixels = iArray;
  364.         else 
  365.            pixels = new int [numBands];
  366.           
  367.         int pixelOffset = y*scanlineStride + x*pixelStride;
  368.         for (int i=0; i<numBands; i++) {
  369.             pixels[i] = data.getElem(bankIndices[i], pixelOffset);
  370.         }
  371.         return pixels;
  372.     }
  373.     
  374.     /**
  375.      * Returns all samples for the specified rectangle of pixels in
  376.      * an int array, one sample per data array element.
  377.      * @param x     The X coordinate of the upper left pixel location.
  378.      * @param y     The Y coordinate of the upper left pixel location.
  379.      * @param w     The width of the pixel rectangle.
  380.      * @param h     The height of the pixel rectangle.
  381.      * @param iArray     If non-null, returns the samples in this array.
  382.      * @param data     The DataBuffer containing the image data.
  383.      */
  384.     public int[] getPixel(int x, int y, int w, int h,
  385.               int iArray[], DataBuffer data) {
  386.         int pixels[];
  387.     
  388.         if (iArray != null) 
  389.            pixels = iArray;
  390.         else 
  391.            pixels = new int [w*h*numBands];
  392.        
  393.         int lineOffset = y*scanlineStride + x*pixelStride;
  394.         int srcOffset = 0;
  395.          
  396.         for (int i = 0; i < h; i++) {
  397.            int pixelOffset = lineOffset;
  398.            for (int j = 0; j < w; j++) {
  399.               for (int k=0; k < numBands; k++) {
  400.                  pixels[srcOffset++] = 
  401.                     data.getElem(bankIndices[k], pixelOffset);
  402.               }
  403.               pixelOffset += pixelStride;
  404.            }
  405.            lineOffset += scanlineStride;
  406.         }
  407.         return pixels;
  408.     }
  409.  
  410.     /** 
  411.      * Returns as int the sample in a specified band for the pixel
  412.      * located at (x,y).
  413.      * @param x     The X coordinate of the pixel location.
  414.      * @param y     The Y coordinate of the pixel location.
  415.      * @param b     The band to return.
  416.      * @param data     The DataBuffer containing the image data.
  417.      */
  418.     public int getSample(int x, int y, int b, DataBuffer data) {
  419.         int sample = data.getElem(bankIndices[b],
  420.                   y*scanlineStride + x*pixelStride);
  421.         return sample;
  422.     }
  423.  
  424.     /**
  425.      * Returns the samples in a specified band for the specified rectangle
  426.      * of pixels in an int array, one sample per data array element.
  427.      * @param x     The X coordinate of the upper left pixel location.
  428.      * @param y     The Y coordinate of the upper left pixel location.
  429.      * @param w     The width of the pixel rectangle.
  430.      * @param h     The height of the pixel rectangle.
  431.      * @param b     The band to return.
  432.      * @param iArray     If non-null, returns the samples in this array.
  433.      * @param data     The DataBuffer containing the image data.
  434.      */
  435.     public int[] getSample(int x, int y, int w, int h, int b,
  436.                int iArray[], DataBuffer data) {
  437.         int samples[];
  438.     int bank = bankIndices[b];
  439.     
  440.         if (iArray != null) 
  441.            samples = iArray;
  442.         else
  443.            samples = new int [w*h];
  444.  
  445.         int lineOffset = y*scanlineStride + x*pixelStride;
  446.         int srcOffset = 0;
  447.          
  448.         for (int i = 0; i < h; i++) {
  449.            int sampleOffset = lineOffset;
  450.            for (int j = 0; j < w; j++) {
  451.            samples[srcOffset++] = 
  452.            data.getElem(bank, sampleOffset);
  453.            sampleOffset += pixelStride;
  454.            }
  455.            lineOffset += scanlineStride;
  456.         }
  457.         return samples;
  458.     }
  459.  
  460.     /** 
  461.      * Puts the pixel data from an Object that contains an
  462.      * array of primitives that can be byte,
  463.      * short or int. Which primitive type it contains depends on
  464.      * the transfer type. Data in the Object is in the packed format,
  465.      * thus increasing efficiency for data transfers.
  466.      * <pre>
  467.      *          BandedSampleModel bsm1, bsm2;
  468.      *         DataBufferInt db1, db2;
  469.      *          bsm2.setPixelData(x, y, bsm1.getPixelData(x, y, null, db1), db2);
  470.      * </pre>
  471.      * @param x     The X coordinate of the pixel location.
  472.      * @param y     The Y coordinate of the pixel location.
  473.      * @param obj       If non-null, returns the primitive array in this object.
  474.      * @param data      The DataBuffer containing the image data.
  475.      */
  476.     public void setPixelData(int x, int y, Object obj, DataBuffer data) {
  477.  
  478.     int type = getTransferType();
  479.     int numDataElems = getNumDataElements();
  480.     int pixelOffset = y*scanlineStride + x*pixelStride;
  481.  
  482.     switch(type) {
  483.  
  484.     case DataBuffer.BYTE_DATA:
  485.  
  486.         byte[] barray = (byte[])obj;
  487.  
  488.         for (int i=0; i<numDataElems; i++) {
  489.         data.setElem(bankIndices[i], pixelOffset,
  490.                  ((int)barray[i])&0xff);
  491.         }
  492.         break;
  493.         
  494.     case DataBuffer.SHORT_DATA:
  495.  
  496.         short[] sarray = (short[])obj;
  497.  
  498.         for (int i=0; i<numDataElems; i++) {
  499.         data.setElem(bankIndices[i], pixelOffset,
  500.                  ((int)sarray[i])&0xffff);
  501.         }
  502.         break;
  503.         
  504.     case DataBuffer.INT_DATA:    
  505.         
  506.         int[] iarray = (int[])obj;
  507.         
  508.         for (int i=0; i<numDataElems; i++) {
  509.         data.setElem(bankIndices[i], pixelOffset, iarray[i]);
  510.         }
  511.         break;
  512.  
  513.     }
  514.     }
  515.         
  516.     /** 
  517.      * Sets a pixel in the DataBuffer using an int array of samples for input.
  518.      * @param x     The X coordinate of the pixel location.
  519.      * @param y     The Y coordinate of the pixel location.
  520.      * @param iArray    The input samples in an int array.
  521.      * @param data     The DataBuffer containing the image data.
  522.      */
  523.     public void setPixel(int x, int y, int iArray[], DataBuffer data) {
  524.        int pixelOffset = y*scanlineStride + x*pixelStride;
  525.        for (int i=0; i<numBands; i++) {
  526.            data.setElem(bankIndices[i], pixelOffset, iArray[i]);
  527.        }
  528.     }
  529.   
  530.     /**
  531.      * Sets all samples for a rectangle of pixels from an int array containing
  532.      * one sample per array element.
  533.      * @param x     The X coordinate of the upper left pixel location.
  534.      * @param y     The Y coordinate of the upper left pixel location.
  535.      * @param w     The width of the pixel rectangle.
  536.      * @param h     The height of the pixel rectangle.
  537.      * @param iArray    The input samples in an int array.
  538.      * @param data      The DataBuffer containing the image data.
  539.      */
  540.     public void setPixel(int x, int y, int w, int h,
  541.              int iArray[], DataBuffer data) {
  542.  
  543.         int lineOffset = y*scanlineStride + x*pixelStride;
  544.         int srcOffset = 0;
  545.  
  546.         for (int i = 0; i < h; i++) {
  547.            int pixelOffset = lineOffset;
  548.            for (int j = 0; j < w; j++) {
  549.               for (int k=0; k < numBands; k++) {
  550.                  data.setElem(bankIndices[k], pixelOffset,
  551.                               iArray[srcOffset++]);
  552.               }
  553.               pixelOffset += pixelStride;
  554.            }
  555.            lineOffset += scanlineStride;
  556.         }
  557.     }
  558.       
  559.     /** 
  560.      * Sets a sample in the specified band for the pixel located at (x,y)
  561.      * in the DataBuffer using an int for input.
  562.      * @param x     The X coordinate of the pixel location.
  563.      * @param y     The Y coordinate of the pixel location.
  564.      * @param b     The band to set.
  565.      * @param s         The input sample as an int.
  566.      * @param data     The DataBuffer containing the image data.
  567.      */
  568.     public void setSample(int x, int y, int b, int s,
  569.                           DataBuffer data) {
  570.         data.setElem(bankIndices[b], y*scanlineStride + x*pixelStride, s);
  571.     }
  572.  
  573.     /**
  574.      * Sets the samples in the specified band for the specified rectangle
  575.      * of pixels from an int array containing one sample per data array element.
  576.      * @param x     The X coordinate of the upper left pixel location.
  577.      * @param y     The Y coordinate of the upper left pixel location.
  578.      * @param w     The width of the pixel rectangle.
  579.      * @param h     The height of the pixel rectangle.
  580.      * @param b     The band to set.
  581.      * @param iArray    The input sample array.
  582.      * @param data     The DataBuffer containing the image data.
  583.      */
  584.     public void setSample(int x, int y, int w, int h, int b,
  585.               int iArray[], DataBuffer data) {
  586.         int lineOffset = y*scanlineStride + x*pixelStride;
  587.         int srcOffset = 0;
  588.     int bank = bankIndices[b];
  589.  
  590.         for (int i = 0; i < h; i++) {
  591.            int sampleOffset = lineOffset;
  592.            for (int j = 0; j < w; j++) {
  593.               data.setElem(bank, sampleOffset, iArray[srcOffset++]);
  594.               sampleOffset += pixelStride;
  595.            }
  596.            lineOffset += scanlineStride;
  597.         }
  598.     }
  599.  
  600. }
  601.  
  602.