multipixelpackedsamplemodel.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 598 行 · 第 1/2 页

JAVA
598
字号
/*
 * $Id: MultiPixelPackedSampleModel.java,v 1.1 2003/11/25 11:41:16 epr Exp $
 */
package java.awt.image;

/**
 * @author epr
 */
public class MultiPixelPackedSampleModel extends SampleModel {

	/** The number of bits from one pixel to the next. */
	private int pixelBitStride;

	/** Bitmask that extracts the rightmost pixel of a data element. */
	private int bitMask;

	/**
	  * The number of pixels that fit in a data element.  Also used
	  * as the number of bits per pixel.
	  */
	private int pixelsPerDataElement;

	/** The size of a data element in bits. */
	private int dataElementSize;

	/** The bit offset into the data array where the first pixel begins.
	 */
	private int dataBitOffset;

	/** ScanlineStride of the data buffer described in data array elements. */
	private int scanlineStride;

	/**
	 * Constructs a <code>MultiPixelPackedSampleModel</code> with the
	 * specified 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 numberOfBits the number of bits per pixel
	 * @throws IllegalArgumentException if <code>dataType</code> is not
	 *         either <code>DataBuffer.TYPE_BYTE</code>,
	 *         <code>DataBuffer.TYPE_USHORT</code>, or
	 *         <code>DataBuffer.TYPE_INT</code>
	 */
	public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits) {
		this(dataType, w, h, numberOfBits, (w * numberOfBits + DataBuffer.getDataTypeSize(dataType) - 1) / DataBuffer.getDataTypeSize(dataType), 0);
		if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT && dataType != DataBuffer.TYPE_INT) {
			throw new IllegalArgumentException("Unsupported data type " + dataType);
		}
	}

	/**
	 * Constructs a <code>MultiPixelPackedSampleModel</code> with 
	 * specified 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 numberOfBits the number of bits per pixel
	 * @param scanlineStride the line stride of the image data
	 * @param dataBitOffset the data bit offset for the region of image
	 *                  data described
	 * @exception RasterFormatException if the number of bits per pixel
	 *                  is not a power of 2 or if a power of 2 number of
	 *			pixels do not fit in one data element.
	 * @throws IllegalArgumentException if <code>w</code> or
	 *         <code>h</code> is not greater than 0
	 * @throws IllegalArgumentException if <code>dataType</code> is not
	 *         either <code>DataBuffer.TYPE_BYTE</code>,
	 *         <code>DataBuffer.TYPE_USHORT</code>, or
	 *         <code>DataBuffer.TYPE_INT</code>
	 */
	public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits, int scanlineStride, int dataBitOffset) {
		super(dataType, w, h, 1);
		if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT && dataType != DataBuffer.TYPE_INT) {
			throw new IllegalArgumentException("Unsupported data type " + dataType);
		}
		this.dataType = dataType;
		this.pixelBitStride = numberOfBits;
		this.scanlineStride = scanlineStride;
		this.dataBitOffset = dataBitOffset;
		this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
		this.pixelsPerDataElement = dataElementSize / numberOfBits;
		if (pixelsPerDataElement * numberOfBits != dataElementSize) {
			throw new RasterFormatException("MultiPixelPackedSampleModel " + "does not allow pixels to " + "span data element boundaries");
		}
		this.bitMask = (1 << numberOfBits) - 1;
	}

	/**
	 * Creates a new <code>MultiPixelPackedSampleModel</code> with the
	 * specified width and height.  The new 
	 * <code>MultiPixelPackedSampleModel</code> has the
	 * same storage data type and number of bits per pixel as this
	 * <code>MultiPixelPackedSampleModel</code>.
	 * @param w the specified width
	 * @param h the specified height
	 * @return a {@link SampleModel} with the specified width and height
	 * and with the same storage data type and number of bits per pixel
	 * as this <code>MultiPixelPackedSampleModel</code>.
	 * @throws IllegalArgumentException if <code>w</code> or
	 *         <code>h</code> is not greater than 0
	 */
	public SampleModel createCompatibleSampleModel(int w, int h) {
		SampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
		return sampleModel;
	}

	/** 
	 * Creates a <code>DataBuffer</code> that corresponds to this
	 * <code>MultiPixelPackedSampleModel</code>.  The
	 * <code>DataBuffer</code> object's data type and size
	 * is consistent with this <code>MultiPixelPackedSampleModel</code>.
	 * The <code>DataBuffer</code> has a single bank.
	 * @return a <code>DataBuffer</code> with the same data type and
	 * size as this <code>MultiPixelPackedSampleModel</code>.
	 */
	public DataBuffer createDataBuffer() {
		DataBuffer dataBuffer = null;

		int size = scanlineStride * height;
		switch (dataType) {
			case DataBuffer.TYPE_BYTE :
				dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
				break;
			case DataBuffer.TYPE_USHORT :
				dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
				break;
			case DataBuffer.TYPE_INT :
				dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
				break;
		}
		return dataBuffer;
	}

	/** 
	 * Returns the number of data elements needed to transfer one pixel
	 * via the {@link #getDataElements} and {@link #setDataElements}
	 * methods.  For a <code>MultiPixelPackedSampleModel</code>, this is
	 * one.
	 * @return the number of data elements.
	 */
	public int getNumDataElements() {
		return 1;
	}

	/** 
	 * Returns the number of bits per sample for all bands. 
	 * @return the number of bits per sample.
	 */
	public int[] getSampleSize() {
		int sampleSize[] = { pixelBitStride };
		return sampleSize;
	}

	/** 
	 * Returns the number of bits per sample for the specified band. 
	 * @param band the specified band
	 * @return the number of bits per sample for the specified band.
	 */
	public int getSampleSize(int band) {
		return pixelBitStride;
	}

	/** 
	 * Returns the offset of pixel (x,&nbsp;y) in data array elements.
	 * @param x,&nbsp;y the specified pixel
	 * @return the offset of the specified pixel.
	 */
	public int getOffset(int x, int y) {
		int offset = y * scanlineStride;
		offset += (x * pixelBitStride + dataBitOffset) / dataElementSize;
		return offset;
	}

	/**
	 *  Returns the offset, in bits, into the data element in which it is
	 *  stored for the <code>x</code>th pixel of a scanline.
	 *  This offset is the same for all scanlines.
	 *  @param x the specified pixel
	 *  @return the bit offset of the specified pixel.
	 */
	public int getBitOffset(int x) {
		return (x * pixelBitStride + dataBitOffset) % dataElementSize;
	}

	/** 
	 * Returns the scanline stride. 
	 * @return the scanline stride of this
	 * <code>MultiPixelPackedSampleModel</code>.
	 */
	public int getScanlineStride() {
		return scanlineStride;
	}

	/** 
	 * Returns the pixel bit stride in bits.  This value is the same as
	 * the number of bits per pixel.
	 * @return the <code>pixelBitStride</code> of this 
	 * <code>MultiPixelPackedSampleModel</code>.
	 */
	public int getPixelBitStride() {
		return pixelBitStride;
	}

	/** 
	 * Returns the data bit offset in bits. 
	 * @return the <code>dataBitOffset</code> of this
	 * <code>MultiPixelPackedSampleModel</code>.
	 */
	public int getDataBitOffset() {
		return dataBitOffset;
	}

	/** 
	 *  Returns the TransferType used to transfer pixels by way of the
	 *  <code>getDataElements</code> and <code>setDataElements</code> 
	 *  methods. The TransferType might or might not be the same as the
	 *  storage DataType.  The TransferType is one of
	 *  DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
	 *  or DataBuffer.TYPE_INT.
	 *  @return the transfertype.
	 */
	public int getTransferType() {
		if (pixelBitStride > 16)
			return DataBuffer.TYPE_INT;
		else if (pixelBitStride > 8)
			return DataBuffer.TYPE_USHORT;
		else
			return DataBuffer.TYPE_BYTE;
	}

	/**
	 * Creates a new <code>MultiPixelPackedSampleModel</code> with a
	 * subset of the bands of this 
	 * <code>MultiPixelPackedSampleModel</code>.  Since a
	 * <code>MultiPixelPackedSampleModel</code> only has one band, the
	 * bands argument must have a length of one and indicate the zeroth
	 * band.
	 * @param bands the specified bands
	 * @return a new <code>SampleModel</code> with a subset of bands of
	 * this <code>MultiPixelPackedSampleModel</code>.
	 * @exception RasterFormatException if the number of bands requested
	 * is not one.
	 * @throws IllegalArgumentException if <code>w</code> or
	 *         <code>h</code> is not greater than 0
	 */
	public SampleModel createSubsetSampleModel(int bands[]) {
		if (bands != null) {
			if (bands.length != 1)
				throw new RasterFormatException("MultiPixelPackedSampleModel has " + "only one band.");
		}
		SampleModel sm = createCompatibleSampleModel(width, height);
		return sm;
	}

	/** 
	 * Returns as <code>int</code> the sample in a specified band for the
	 * pixel located at (x,&nbsp;y).  An 
	 * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
	 * coordinates are not in bounds.
	 * @param x,&nbsp;y the coordinates of the specified pixel
	 * @param b 	the band to return, which is assumed to be 0
	 * @param data      the <code>DataBuffer</code> containing the image
	 *			data
	 * @return the specified band containing the sample of the specified
	 * pixel.
	 * @exception ArrayIndexOutOfBoundException if the specified
	 *		coordinates are not in bounds.
	 * @see #setSample(int, int, int, int, DataBuffer)
	 */
	public int getSample(int x, int y, int b, DataBuffer data) {
		// 'b' must be 0
		if ((x < 0) || (y < 0) || (x >= width) || (y >= height) || (b != 0)) {
			throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
		}
		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 specified band for the pixel located at 
	 * (x,&nbsp;y) in the <code>DataBuffer</code> using an
	 * <code>int</code> for input.
	 * An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
	 * coordinates are not in bounds.
	 * @param x,&nbsp;y the coordinates of the specified pixel
	 * @param b the band to return, which is assumed to be 0
	 * @param s the input sample as an <code>int</code>
	 * @param data the <code>DataBuffer</code> where image data is stored
	 * @exception ArrayIndexOutOfBoundsException if the coordinates are 
	 * not in bounds.
	 * @see #getSample(int, int, int, DataBuffer)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?