home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-20 | 15.4 KB | 468 lines |
- /*
- * @(#)MultiPixelPackedSampleModel.java 1.12 98/03/18
- *
- * Copyright 1997, 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
- /* ****************************************************************
- ******************************************************************
- ******************************************************************
- *** COPYRIGHT (c) Eastman Kodak Company, 1997
- *** As an unpublished work pursuant to Title 17 of the United
- *** States Code. All rights reserved.
- ******************************************************************
- ******************************************************************
- ******************************************************************/
-
- package java.awt.image;
-
- /**
- * This class extends SampleModel. It only stores one-banded images,
- * but it can pack multiple one-sample pixels into one data element.
- * Note that pixels are not allowed to span data element. In addition,
- * each pixel must be a power of 2 number of bits and a power of 2
- * number of pixels must fit exactly in one data element. Pixel bit stride
- * is equal to the number of bits per pixel. Scanline stride is in
- * data elements so the last data element may be padded with unused pixels.
- * Data bit offset must be a multiple of pixel bit stride.
- */
-
- public class MultiPixelPackedSampleModel extends SampleModel
- {
- /** The number of bits from one pixel to the next. */
- int pixelBitStride;
-
- /** Bitmask that extracts the rightmost pixel of a data element. */
- int bitMask;
-
- /**
- * The number of pixels that fit in a data Element. Also used
- * as the number of bits per pixel.
- */
- int pixelsPerDataElement;
-
- /** The size of a data element in bits. */
- int dataElementSize;
-
- /** The bitOffset into the dataArray where the first pixel begins. */
- int dataBitOffset;
-
- /** ScanlineStride of the data buffer described in data array elements. */
- int scanlineStride;
-
- /**
- * Constructs a MultiPixelPackedSampleModel with the given data type,
- * width, height and number of bits per pixel.
- * @param dataType The data type for storing samples.
- * @param w The width (in pixels) of the region of
- * image data described.
- * @param h The height (in pixels) of the region of
- * image data described.
- * @param numofBits The pixelBitStride for the region of image data
- * described.
- */
- public MultiPixelPackedSampleModel(int dataType,
- int w,
- int h,
- int numberOfBits) {
- this(dataType,w,h,
- numberOfBits,
- (w*numberOfBits+DataBuffer.sizeOf(dataType)-1)/
- DataBuffer.sizeOf(dataType),
- 0);
- }
-
- /**
- * Constructs a MultiPixelPackedSampleModel with given data type, width,
- * height, number of bits per pixel, scanline stride and data bit
- * offset.
- * @param dataType The data type for storing samples.
- * @param w The width (in pixels) of the region of
- * image data described.
- * @param h The height (in pixels) of the region of
- * image data described.
- * @param pixelBitStride The pixelBitStride of the region of image data
- * described.
- * @param scanlineStride The line stride of the region of the
- * image data described.
- * @param dataBitOffset The data bit offset for the region of image
- * data described.
- */
- public MultiPixelPackedSampleModel(int dataType, int w, int h,
- int pixelBitStride,
- int scanlineStride,
- int dataBitOffset) {
- super(dataType, w, h, 1);
- this.dataType = dataType;
- this.pixelBitStride = pixelBitStride;
- this.scanlineStride = scanlineStride;
- this.dataBitOffset = dataBitOffset;
- this.dataElementSize = DataBuffer.sizeOf(dataType);
- this.pixelsPerDataElement = dataElementSize/pixelBitStride;
- if (pixelsPerDataElement*pixelBitStride != dataElementSize) {
- throw new RasterFormatException("MultiPixelPackedSampleModel " +
- "does not allow pixels to " +
- "span byte boundaries");
- }
- this.bitMask = (1 << pixelBitStride) - 1;
- }
-
-
- /**
- * Creates a new SinglePackedSampleModel with the requested
- * width and height.
- */
- public SampleModel createCompatibleSampleModel(int w, int h) {
- SampleModel sampleModel =
- new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
- return sampleModel;
- }
-
- /**
- * Creates a DataBuffer of the correct type big enough to hold all
- * pixels described by this MultiPixelPackedSampleModel.
- */
- public DataBuffer createCompatibleDataBuffer() {
- DataBuffer dataBuffer = null;
-
- int size = (int)scanlineStride*height;
- switch (dataType) {
- case DataBuffer.BYTE_DATA:
- dataBuffer = new DataBufferByte(size);
- break;
- case DataBuffer.SHORT_DATA:
- dataBuffer = new DataBufferShort(size);
- break;
- case DataBuffer.INT_DATA:
- dataBuffer = new DataBufferInt(size);
- break;
- }
- return dataBuffer;
- }
-
- /**
- * Creates a DataBuffer of the correct type big enough to hold all
- * pixels described by this MultiPixelPackedSampleModel with
- * the desired height and width.
- */
- public DataBuffer createCompatibleDataBuffer(int desiredWidth,
- int desiredHeight) {
- DataBuffer dataBuffer = null;
-
- int size = (int)(desiredWidth*desiredHeight*numBands);
- switch (dataType) {
- case DataBuffer.BYTE_DATA:
- dataBuffer = new DataBufferByte(size);
- break;
- case DataBuffer.SHORT_DATA:
- dataBuffer = new DataBufferShort(size);
- break;
- case DataBuffer.INT_DATA:
- dataBuffer = new DataBufferInt(size);
- break;
- }
- return dataBuffer;
- }
-
-
- /** Returns the size of a pixel in bits. This is equal to the
- * pixel bit stride.
- */
- public int getPixelBitSize() {
- int bitSize = 0;
- int sampleSize[] = getSampleSize();
- for (int i=0; i<sampleSize.length; i++) {
- bitSize += sampleSize[i];
- }
-
- return bitSize;
- }
-
- /** Returns the number of data elements required to store one pixel. */
- public int getNumDataElements() {
- return 1;
- }
-
- /** Returns the size of all bands in bits. */
- public int[] getSampleSize() {
- int sampleSize[] = {pixelBitStride};
- return sampleSize;
- }
-
- /** Returns the size of the requested bands in bits. */
- public int getSampleSize(int band) {
- return pixelBitStride;
- }
-
- /** Returns the offset (in data array elements) of pixel (x,y). */
- public long getOffset(int x, int y) {
- long offset = y * scanlineStride;
- offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
- return offset;
- }
-
- /**
- * Returns offset in bits of the xth pixel of a scanline into the
- * data element in which it's stored.
- */
- public int getBitOffset(int x){
- return (x*pixelBitStride+dataBitOffset)%dataElementSize;
- }
-
- /** Returns the scanline stride. */
- public int getScanlineStride() {
- return scanlineStride;
- }
-
- /** Returns the pixel bit stride in bits. Same as pixel bit size. */
- public int getPixelBitStride() {
- return pixelBitStride;
- }
-
- /** Returns the data bit offset in bits. */
- public int getDataBitOffset() {
- return dataBitOffset;
- }
-
- /** Returns the tranfer type of the data */
- public int getTransferType() {
- if (pixelBitStride > 16)
- return DataBuffer.INT_DATA;
- else if (pixelBitStride > 8)
- return DataBuffer.SHORT_DATA;
- else
- return DataBuffer.BYTE_DATA;
- }
-
- /**
- * This creates a new SampleModel with the requested physical
- * width and height and with a subset of the components of this
- * SampleModel.
- */
- public SampleModel createSubsetSampleModel(int w, int h, int bands[]) {
- if (bands != null) {
- if (bands.length != 1)
- throw new RasterFormatException("MultiPixelPackedSampleModel has "
- + "only one band.");
- }
- SampleModel sm = createCompatibleSampleModel(w, h);
- return sm;
- }
-
- /**
- * Returns the sample in a specified band for a pixel as an int.
- * @param x The X coordinate of the pixel location
- * @param y The Y coordinate of the pixel location
- * @param b The band to return (assumed to be 0)
- * @param data The DataBuffer where image data is stored.
- */
- public int getSample(int x, int y, int b, DataBuffer data) {
- int bitnum = dataBitOffset + x*pixelBitStride;
- int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- return (element >> shift) & bitMask;
- }
-
- /**
- * Sets a sample in the DataBuffer using an int for input.
- * @param x The X coordinate of the pixel location
- * @param y The Y coordinate of the pixel location
- * @param b The band to return (assumed to be 0)
- * @param s The input sample as an int
- * @param data The DataBuffer where image data is stored
- */
- public void setSample(int x, int y, int b, int s,
- DataBuffer data) {
- int bitnum = dataBitOffset + x * pixelBitStride;
- int index = y * scanlineStride + (bitnum / dataElementSize);
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- int element = data.getElem(index);
- element &= ~(bitMask << shift);
- element |= (s & bitMask) << shift;
- data.setElem(index,element);
- }
-
- /**
- * Returns the pixel data in an array of primitives that can be byte,
- * short or int. Which primitive type is returned depends on
- * the transfer type. Data is returned in the packed format,
- * thus increasing efficiency for data transfers. Generally, obj
- * should be passed in as null, so that the Object will be created
- * automatically and will be of the right primitive data type.
- * <pre>
- * MultiPixelPackedSampleModel mppsm1, mppsm2;
- * DataBufferInt db1, db2;
- * mppsm2.setPixelData(x, y, mppsm1.getPixelData(x, y, null, db1), db2);
- * </pre>
- * @param x The X coordinate of the pixel location.
- * @param y The Y coordinate of the pixel location.
- * @param obj If non-null, returns the primitive array in this object.
- * @param data The DataBuffer containing the image data.
- */
- public Object getPixelData(int x, int y, Object obj, DataBuffer data) {
-
- int type = getTransferType();
- int bitnum = dataBitOffset + x*pixelBitStride;
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- int element = 0;
-
- switch(type) {
-
- case DataBuffer.BYTE_DATA:
-
- byte[] bdata;
-
- if (obj == null)
- bdata = new byte[1];
- else
- bdata = (byte[])obj;
-
- element = data.getElem(y*scanlineStride +
- bitnum/dataElementSize);
- bdata[0] = (byte)((element >> shift) & bitMask);
-
- obj = (Object)bdata;
- break;
-
- case DataBuffer.SHORT_DATA:
-
- short[] sdata;
-
- if (obj == null)
- sdata = new short[1];
- else
- sdata = (short[])obj;
-
- element = data.getElem(y*scanlineStride +
- bitnum/dataElementSize);
- sdata[0] = (short)((element >> shift) & bitMask);
-
- obj = (Object)sdata;
- break;
-
- case DataBuffer.INT_DATA:
-
- int[] idata;
-
- if (obj == null)
- idata = new int[1];
- else
- idata = (int[])obj;
-
- element = data.getElem(y*scanlineStride +
- bitnum/dataElementSize);
- idata[0] = (element >> shift) & bitMask;
-
- obj = (Object)idata;
- break;
- }
-
- return obj;
- }
-
- /**
- * Returns the requested pixel as an int.
- * @param x The X coordinate of the pixel location.
- * @param y The Y coordinate of the pixel location.
- * @param data The DataBuffer where image data is stored.
- */
- public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
- int pixels[];
- if (iArray != null) {
- pixels = iArray;
- } else {
- pixels = new int [numBands];
- }
- int bitnum = dataBitOffset + x*pixelBitStride;
- int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- pixels[0] = (element >> shift) & bitMask;
- return pixels;
- }
-
- /**
- * Puts the pixel data from an Object that contains an
- * array of primitives that can be byte,
- * short or int. Which primitive type it contains depends on
- * the transfer type. Data in the Object is in the packed format,
- * thus increasing efficiency for data transfers.
- * <pre>
- * MultiPixelPackedSampleModel mppsm1, mppsm2;
- * DataBufferInt db1, db2;
- * mppsm2.setPixelData(x, y, mppsm1.getPixelData(x, y, null, db1), db2);
- * </pre>
- * @param x The X coordinate of the pixel location.
- * @param y The Y coordinate of the pixel location.
- * @param obj If non-null, returns the primitive array in this object.
- * @param data The DataBuffer containing the image data.
- */
- public void setPixelData(int x, int y, Object obj, DataBuffer data) {
-
- int type = getTransferType();
- int bitnum = dataBitOffset + x * pixelBitStride;
- int index = y * scanlineStride + (bitnum / dataElementSize);
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- int element = data.getElem(index);
- element &= ~(bitMask << shift);
-
- switch(type) {
-
- case DataBuffer.BYTE_DATA:
-
- byte[] barray = (byte[])obj;
- element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
- data.setElem(index, element);
- break;
-
- case DataBuffer.SHORT_DATA:
-
- short[] sarray = (short[])obj;
- element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
- data.setElem(index, element);
- break;
-
- case DataBuffer.INT_DATA:
-
- int[] iarray = (int[])obj;
- element |= (iarray[0] & bitMask) << shift;
- data.setElem(index, element);
- break;
- }
- }
-
- /**
- * Sets a pixel in the DataBuffer using an int for input.
- * @param x The X coordinate of the pixel location
- * @param y The Y coordinate of the pixel location
- * @param s The input sample as an int
- * @param data The DataBuffer where image data is stored
- */
- public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
- int bitnum = dataBitOffset + x * pixelBitStride;
- int index = y * scanlineStride + (bitnum / dataElementSize);
- int shift = dataElementSize - (bitnum & (dataElementSize-1))
- - pixelBitStride;
- int element = data.getElem(index);
- element &= ~(bitMask << shift);
- element |= (iArray[0] & bitMask) << shift;
- data.setElem(index,element);
- }
-
-
- }
-
-
-