1 /* 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt.image; 27 28 /** 29 * This class represents image data which is stored in a pixel interleaved 30 * fashion and for 31 * which each sample of a pixel occupies one data element of the DataBuffer. 32 * It subclasses ComponentSampleModel but provides a more efficient 33 * implementation for accessing pixel interleaved image data than is provided 34 * by ComponentSampleModel. This class 35 * stores sample data for all bands in a single bank of the 36 * DataBuffer. Accessor methods are provided so that image data can be 37 * manipulated directly. Pixel stride is the number of 38 * data array elements between two samples for the same band on the same 39 * scanline. Scanline stride is the number of data array elements between 40 * a given sample and the corresponding sample in the same column of the next 41 * scanline. Band offsets denote the number 42 * of data array elements from the first data array element of the bank 43 * of the DataBuffer holding each band to the first sample of the band. 44 * The bands are numbered from 0 to N-1. 45 * Bank indices denote the correspondence between a bank of the data buffer 46 * and a band of image data. 47 * This class supports 48 * {@link DataBuffer#TYPE_BYTE TYPE_BYTE}, 49 * {@link DataBuffer#TYPE_USHORT TYPE_USHORT}, 50 * {@link DataBuffer#TYPE_SHORT TYPE_SHORT}, 51 * {@link DataBuffer#TYPE_INT TYPE_INT}, 52 * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT} and 53 * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes. 54 */ 55 56 public class PixelInterleavedSampleModel extends ComponentSampleModel 57 { 58 /** 59 * Constructs a PixelInterleavedSampleModel with the specified parameters. 60 * The number of bands will be given by the length of the bandOffsets 61 * array. 62 * @param dataType The data type for storing samples. 63 * @param w The width (in pixels) of the region of 64 * image data described. 65 * @param h The height (in pixels) of the region of 66 * image data described. 67 * @param pixelStride The pixel stride of the image data. 68 * @param scanlineStride The line stride of the image data. 69 * @param bandOffsets The offsets of all bands. 70 * @throws IllegalArgumentException if {@code w} or 71 * {@code h} is not greater than 0 72 * @throws IllegalArgumentException if any offset between bands is 73 * greater than the scanline stride 74 * @throws IllegalArgumentException if the product of 75 * {@code pixelStride} and {@code w} is greater 76 * than {@code scanlineStride} 77 * @throws IllegalArgumentException if {@code pixelStride} is 78 * less than any offset between bands 79 * @throws IllegalArgumentException if {@code dataType} is not 80 * one of the supported data types 81 */ 82 public PixelInterleavedSampleModel(int dataType, 83 int w, int h, 84 int pixelStride, 85 int scanlineStride, 86 int bandOffsets[]) { 87 super(dataType, w, h, pixelStride, scanlineStride, bandOffsets); 88 int minBandOff=this.bandOffsets[0]; 89 int maxBandOff=this.bandOffsets[0]; 90 for (int i=1; i<this.bandOffsets.length; i++) { 91 minBandOff = Math.min(minBandOff,this.bandOffsets[i]); 92 maxBandOff = Math.max(maxBandOff,this.bandOffsets[i]); 93 } 94 maxBandOff -= minBandOff; 95 if (maxBandOff > scanlineStride) { 96 throw new IllegalArgumentException("Offsets between bands must be"+ 97 " less than the scanline "+ 98 " stride"); 99 } 100 if (pixelStride*w > scanlineStride) { 101 throw new IllegalArgumentException("Pixel stride times width "+ 102 "must be less than or "+ 103 "equal to the scanline "+ 104 "stride"); 105 } 106 if (pixelStride < maxBandOff) { 107 throw new IllegalArgumentException("Pixel stride must be greater"+ 108 " than or equal to the offsets"+ 109 " between bands"); 110 } 111 } 112 113 /** 114 * Creates a new PixelInterleavedSampleModel with the specified 115 * width and height. The new PixelInterleavedSampleModel will have the 116 * same number of bands, storage data type, and pixel stride 117 * as this PixelInterleavedSampleModel. The band offsets may be 118 * compressed such that the minimum of all of the band offsets is zero. 119 * @param w the width of the resulting {@code SampleModel} 120 * @param h the height of the resulting {@code SampleModel} 121 * @return a new {@code SampleModel} with the specified width 122 * and height. 123 * @throws IllegalArgumentException if {@code w} or 124 * {@code h} is not greater than 0 125 */ 126 public SampleModel createCompatibleSampleModel(int w, int h) { 127 int minBandoff=bandOffsets[0]; 128 int numBands = bandOffsets.length; 129 for (int i=1; i < numBands; i++) { 130 if (bandOffsets[i] < minBandoff) { 131 minBandoff = bandOffsets[i]; 132 } 133 } 134 int[] bandOff; 135 if (minBandoff > 0) { 136 bandOff = new int[numBands]; 137 for (int i=0; i < numBands; i++) { 138 bandOff[i] = bandOffsets[i] - minBandoff; 139 } 140 } 141 else { 142 bandOff = bandOffsets; 143 } 144 return new PixelInterleavedSampleModel(dataType, w, h, pixelStride, 145 pixelStride*w, bandOff); 146 } 147 148 /** 149 * Creates a new PixelInterleavedSampleModel with a subset of the 150 * bands of this PixelInterleavedSampleModel. The new 151 * PixelInterleavedSampleModel can be used with any DataBuffer that the 152 * existing PixelInterleavedSampleModel can be used with. The new 153 * PixelInterleavedSampleModel/DataBuffer combination will represent 154 * an image with a subset of the bands of the original 155 * PixelInterleavedSampleModel/DataBuffer combination. 156 */ 157 public SampleModel createSubsetSampleModel(int bands[]) { 158 int newBandOffsets[] = new int[bands.length]; 159 for (int i=0; i<bands.length; i++) { 160 newBandOffsets[i] = bandOffsets[bands[i]]; 161 } 162 return new PixelInterleavedSampleModel(this.dataType, width, height, 163 this.pixelStride, 164 scanlineStride, newBandOffsets); 165 } 166 167 // Differentiate hash code from other ComponentSampleModel subclasses 168 public int hashCode() { 169 return super.hashCode() ^ 0x1; 170 } 171 }