📄 componentsamplemodel.java
字号:
/* * @(#)ComponentSampleModel.java 1.43 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* **************************************************************** ****************************************************************** ****************************************************************** *** 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;import java.util.Arrays;/** * This class represents image data which is stored such that each sample * of a pixel occupies one data element of the DataBuffer. It stores the * N samples which make up a pixel in N separate data array elements. * Different bands may be in different banks of the DataBuffer. * Accessor methods are provided so that image data can be manipulated * directly. This class can support different kinds of interleaving, e.g. * band interleaving, scanline interleaving, and pixel interleaving. * Pixel stride is the number of data array elements between two samples * for the same band on the same scanline. Scanline stride is the number * of data array elements between a given sample and the corresponding sample * in the same column of the next scanline. Band offsets denote the number * of data array elements from the first data array element of the bank * of the DataBuffer holding each band to the first sample of the band. * The bands are numbered from 0 to N-1. This class can represent image * data for which each sample is an unsigned integral number which can be * stored in 8, 16, or 32 bits (using <code>DataBuffer.TYPE_BYTE</code>, * <code>DataBuffer.TYPE_USHORT</code>, or <code>DataBuffer.TYPE_INT</code>, * respectively), data for which each sample is a signed integral number * which can be stored in 16 bits (using <code>DataBuffer.TYPE_SHORT</code>), * or data for which each sample is a signed float or double quantity * (using <code>DataBuffer.TYPE_FLOAT</code> or * <code>DataBuffer.TYPE_DOUBLE</code>, respectively). * All samples of a given ComponentSampleModel * are stored with the same precision. All strides and offsets must be * non-negative. This class supports * {@link DataBuffer#TYPE_BYTE TYPE_BYTE}, * {@link DataBuffer#TYPE_USHORT TYPE_USHORT}, * {@link DataBuffer#TYPE_SHORT TYPE_SHORT}, * {@link DataBuffer#TYPE_INT TYPE_INT}, * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE}, * @see java.awt.image.PixelInterleavedSampleModel * @see java.awt.image.BandedSampleModel */public class ComponentSampleModel extends SampleModel{ /** Offsets for all bands in data array elements. */ protected int bandOffsets[]; /** Index for each bank storing a band of image data. */ protected int[] bankIndices; /** * The number of bands in this * <code>ComponentSampleModel</code>. */ protected int numBands = 1; /** * The number of banks in this * <code>ComponentSampleModel</code>. */ protected int numBanks = 1; /** * Line stride (in data array elements) of the region of image * data described by this ComponentSampleModel. */ protected int scanlineStride; /** Pixel stride (in data array elements) of the region of image * data described by this ComponentSampleModel. */ protected int pixelStride; static private native void initIDs(); static { ColorModel.loadLibraries(); initIDs(); } /** * Constructs a ComponentSampleModel with the specified parameters. * The number of bands will be given by the length of the bandOffsets array. * All bands will be stored in the first bank of the DataBuffer. * @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 pixelStride the pixel stride of the region of image * data described * @param scanlineStride the line stride of the region of image * data described * @param bandOffsets the offsets of all bands * @throws IllegalArgumentException if <code>w</code> or * <code>h</code> is not greater than 0 * @throws IllegalArgumentException if <code>pixelStride</code> * is less than 0 * @throws IllegalArgumentException if <code>scanlineStride</code> * is less than 0 * @throws IllegalArgumentException if <code>numBands</code> * is less than 1 * @throws IllegalArgumentException if the product of <code>w</code> * and <code>h</code> is greater than * <code>Integer.MAX_VALUE</code> * @throws IllegalArgumentException if <code>dataType</code> is not * one of the supported data types */ public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride, int bandOffsets[]) { super(dataType, w, h, bandOffsets.length); this.dataType = dataType; this.pixelStride = pixelStride; this.scanlineStride = scanlineStride; this.bandOffsets = (int[])bandOffsets.clone(); numBands = bandOffsets.length; if (pixelStride < 0) { throw new IllegalArgumentException("Pixel stride must be >= 0"); } // TODO - bug 4296691 - remove this check if (scanlineStride < 0) { throw new IllegalArgumentException("Scanline stride must be >= 0"); } if (numBands < 1) { throw new IllegalArgumentException("Must have at least one band."); } if ((dataType < DataBuffer.TYPE_BYTE) || (dataType > DataBuffer.TYPE_DOUBLE)) { throw new IllegalArgumentException("Unsupported dataType."); } bankIndices = new int[numBands]; for (int i=0; i<numBands; i++) { bankIndices[i] = 0; } } /** * Constructs a ComponentSampleModel with the specified parameters. * The number of bands will be given by the length of the bandOffsets array. * Different bands may be stored in different banks of the DataBuffer. * * @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 pixelStride the pixel stride of the region of image * data described * @param scanlineStride The line stride of the region of image * data described * @param bankIndices the bank indices of all bands * @param bandOffsets the band offsets of all bands * @throws IllegalArgumentException if <code>w</code> or * <code>h</code> is not greater than 0 * @throws IllegalArgumentException if <code>pixelStride</code> * is less than 0 * @throws IllegalArgumentException if <code>scanlineStride</code> * is less than 0 * @throws IllegalArgumentException if the length of * <code>bankIndices</code> does not equal the length of * <code>bankOffsets</code> * @throws IllegalArgumentException if any of the bank indices * of <code>bandIndices</code> is less than 0 * @throws IllegalArgumentException if <code>dataType</code> is not * one of the supported data types */ public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride, int bankIndices[], int bandOffsets[]) { super(dataType, w, h, bandOffsets.length); this.dataType = dataType; this.pixelStride = pixelStride; this.scanlineStride = scanlineStride; this.bandOffsets = (int[])bandOffsets.clone(); this.bankIndices = (int[]) bankIndices.clone(); if (pixelStride < 0) { throw new IllegalArgumentException("Pixel stride must be >= 0"); } // TODO - bug 4296691 - remove this check if (scanlineStride < 0) { throw new IllegalArgumentException("Scanline stride must be >= 0"); } if ((dataType < DataBuffer.TYPE_BYTE) || (dataType > DataBuffer.TYPE_DOUBLE)) { throw new IllegalArgumentException("Unsupported dataType."); } int maxBank = bankIndices[0]; if (maxBank < 0) { throw new IllegalArgumentException("Index of bank 0 is less than "+ "0 ("+maxBank+")"); } for (int i=1; i < bankIndices.length; i++) { if (bankIndices[i] > maxBank) { maxBank = bankIndices[i]; } else if (bankIndices[i] < 0) { throw new IllegalArgumentException("Index of bank "+i+ " is less than 0 ("+ maxBank+")"); } } numBanks = maxBank+1; numBands = bandOffsets.length; if (bandOffsets.length != bankIndices.length) { throw new IllegalArgumentException("Length of bandOffsets must "+ "equal length of bankIndices."); } } /** * Returns the size of the data buffer (in data elements) needed * for a data buffer that matches this ComponentSampleModel. */ private long getBufferSize() { int maxBandOff=bandOffsets[0]; for (int i=1; i<bandOffsets.length; i++) maxBandOff = Math.max(maxBandOff,bandOffsets[i]); long size = 0; if (maxBandOff >= 0) size += maxBandOff+1; if (pixelStride > 0) size += pixelStride * (width-1); if (scanlineStride > 0) size += scanlineStride*(height-1); return size; } /** * Preserves band ordering with new step factor... */ int []orderBands(int orig[], int step) { int map[] = new int[orig.length]; int ret[] = new int[orig.length]; for (int i=0; i<map.length; i++) map[i] = i; for (int i = 0; i < ret.length; i++) { int index = i; for (int j = i+1; j < ret.length; j++) { if (orig[map[index]] > orig[map[j]]) { index = j; } } ret[map[index]] = i*step; map[index] = map[i]; } return ret; } /** * Creates a new <code>ComponentSampleModel</code> with the specified * width and height. The new <code>SampleModel</code> will have the same * number of bands, storage data type, interleaving scheme, and * pixel stride as this <code>SampleModel</code>. * @param w the width of the resulting <code>SampleModel</code> * @param h the height of the resulting <code>SampleModel</code> * @return a new <code>ComponentSampleModel</code> with the specified size * @throws IllegalArgumentException if <code>w</code> or * <code>h</code> is not greater than 0 */ public SampleModel createCompatibleSampleModel(int w, int h) { SampleModel ret=null; long size; int minBandOff=bandOffsets[0]; int maxBandOff=bandOffsets[0]; for (int i=1; i<bandOffsets.length; i++) { minBandOff = Math.min(minBandOff,bandOffsets[i]); maxBandOff = Math.max(maxBandOff,bandOffsets[i]); } maxBandOff -= minBandOff; int bands = bandOffsets.length; int bandOff[]; int pStride = Math.abs(pixelStride); int lStride = Math.abs(scanlineStride); int bStride = Math.abs(maxBandOff); if (pStride > lStride) { if (pStride > bStride) { if (lStride > bStride) { // pix > line > band bandOff = new int[bandOffsets.length]; for (int i=0; i<bands; i++) bandOff[i] = bandOffsets[i]-minBandOff; lStride = bStride+1; pStride = lStride*h; } else { // pix > band > line bandOff = orderBands(bandOffsets,lStride*h); pStride = bands*lStride*h; } } else { // band > pix > line pStride = lStride*h; bandOff = orderBands(bandOffsets,pStride*w); } } else { if (pStride > bStride) { // line > pix > band bandOff = new int[bandOffsets.length]; for (int i=0; i<bands; i++) bandOff[i] = bandOffsets[i]-minBandOff; pStride = bStride+1; lStride = pStride*w; } else { if (lStride > bStride) { // line > band > pix bandOff = orderBands(bandOffsets,pStride*w); lStride = bands*pStride*w; } else { // band > line > pix lStride = pStride*w; bandOff = orderBands(bandOffsets,lStride*h); } } } // make sure we make room for negative offsets... int base = 0; if (scanlineStride < 0) { base += lStride*h; lStride *= -1; } if (pixelStride < 0) { base += pStride*w; pStride *= -1; } for (int i=0; i<bands; i++) bandOff[i] += base; return new ComponentSampleModel(dataType, w, h, pStride, lStride, bankIndices, bandOff); } /** * Creates a new ComponentSampleModel with a subset of the bands * of this ComponentSampleModel. The new ComponentSampleModel can be * used with any DataBuffer that the existing ComponentSampleModel * can be used with. The new ComponentSampleModel/DataBuffer * combination will represent an image with a subset of the bands * of the original ComponentSampleModel/DataBuffer combination. * @param bands a subset of bands from this * <code>ComponentSampleModel</code> * @return a <code>ComponentSampleModel</code> created with a subset * of bands from this <code>ComponentSampleModel</code>. */ public SampleModel createSubsetSampleModel(int bands[]) { if (bands.length > bankIndices.length) throw new RasterFormatException("There are only " + bankIndices.length + " bands"); int newBankIndices[] = new int[bands.length]; int newBandOffsets[] = new int[bands.length]; for (int i=0; i<bands.length; i++) { newBankIndices[i] = bankIndices[bands[i]]; newBandOffsets[i] = bandOffsets[bands[i]]; } return new ComponentSampleModel(this.dataType, width, height, this.pixelStride, this.scanlineStride, newBankIndices, newBandOffsets); } /** * Creates a <code>DataBuffer</code> that corresponds to this * <code>ComponentSampleModel</code>. * The <code>DataBuffer</code> object's data type, number of banks, * and size are be consistent with this <code>ComponentSampleModel</code>. * @return a <code>DataBuffer</code> whose data type, number of banks * and size are consistent with this * <code>ComponentSampleModel</code>. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -