1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Igor V. Stolyarov 19 * @version $Revision$ 20 */ 21 22 package java.awt.image; 23 24 import org.apache.harmony.awt.internal.nls.Messages; 25 26 /** 27 * The BandedSampleModel class provides samples of pixels in an image which is 28 * stored in a band interleaved method. Each pixel's sample takes one data 29 * element of the DataBuffer. The pixel stride for a BandedSampleModel is one. 30 * 31 * @since Android 1.0 32 */ 33 public final class BandedSampleModel extends ComponentSampleModel { 34 35 /** 36 * Creates the indices. 37 * 38 * @param numBands 39 * the num bands. 40 * @return the int[]. 41 */ createIndices(int numBands)42 private static int[] createIndices(int numBands) { 43 int indices[] = new int[numBands]; 44 for (int i = 0; i < numBands; i++) { 45 indices[i] = i; 46 } 47 return indices; 48 } 49 50 /** 51 * Creates the offsets. 52 * 53 * @param numBands 54 * the num bands. 55 * @return the int[]. 56 */ createOffsets(int numBands)57 private static int[] createOffsets(int numBands) { 58 int offsets[] = new int[numBands]; 59 for (int i = 0; i < numBands; i++) { 60 offsets[i] = 0; 61 } 62 return offsets; 63 } 64 65 /** 66 * Instantiates a new BandedSampleModel object with the specified data type 67 * of samples, the width, height and bands number of image data. 68 * 69 * @param dataType 70 * the data type of samples. 71 * @param w 72 * the width of image data. 73 * @param h 74 * the height of image data. 75 * @param numBands 76 * the number of bands. 77 */ BandedSampleModel(int dataType, int w, int h, int numBands)78 public BandedSampleModel(int dataType, int w, int h, int numBands) { 79 this(dataType, w, h, w, BandedSampleModel.createIndices(numBands), BandedSampleModel 80 .createOffsets(numBands)); 81 } 82 83 /** 84 * Instantiates a new BandedSampleModel object with the specified data type 85 * of samples, the width, height and bands number of image data. 86 * 87 * @param dataType 88 * the data type of samples. 89 * @param w 90 * the width of image data. 91 * @param h 92 * the height of image data. 93 * @param scanlineStride 94 * the scanline stride of the of the image data. 95 * @param bankIndices 96 * the array of the bank indices. 97 * @param bandOffsets 98 * the array of the band offsets. 99 */ BandedSampleModel(int dataType, int w, int h, int scanlineStride, int bankIndices[], int bandOffsets[])100 public BandedSampleModel(int dataType, int w, int h, int scanlineStride, int bankIndices[], 101 int bandOffsets[]) { 102 super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets); 103 } 104 105 @Override createCompatibleSampleModel(int w, int h)106 public SampleModel createCompatibleSampleModel(int w, int h) { 107 return new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffsets); 108 } 109 110 @Override createDataBuffer()111 public DataBuffer createDataBuffer() { 112 DataBuffer data = null; 113 int size = scanlineStride * height; 114 115 switch (dataType) { 116 case DataBuffer.TYPE_BYTE: 117 data = new DataBufferByte(size, numBanks); 118 break; 119 case DataBuffer.TYPE_SHORT: 120 case DataBuffer.TYPE_USHORT: 121 data = new DataBufferShort(size, numBanks); 122 break; 123 case DataBuffer.TYPE_INT: 124 data = new DataBufferInt(size, numBanks); 125 break; 126 case DataBuffer.TYPE_FLOAT: 127 data = new DataBufferFloat(size, numBanks); 128 break; 129 case DataBuffer.TYPE_DOUBLE: 130 data = new DataBufferDouble(size, numBanks); 131 break; 132 } 133 134 return data; 135 136 } 137 138 @Override createSubsetSampleModel(int[] bands)139 public SampleModel createSubsetSampleModel(int[] bands) { 140 if (bands.length > numBands) { 141 // awt.64=The number of the bands in the subset is greater than the 142 // number of bands in the sample model 143 throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$ 144 } 145 146 int indices[] = new int[bands.length]; 147 int offsets[] = new int[bands.length]; 148 149 for (int i = 0; i < bands.length; i++) { 150 indices[i] = bankIndices[bands[i]]; 151 offsets[i] = bandOffsets[bands[i]]; 152 } 153 154 return new BandedSampleModel(dataType, width, height, scanlineStride, indices, offsets); 155 } 156 157 @Override getDataElements(int x, int y, Object obj, DataBuffer data)158 public Object getDataElements(int x, int y, Object obj, DataBuffer data) { 159 switch (dataType) { 160 case DataBuffer.TYPE_BYTE: { 161 byte bdata[]; 162 163 if (obj == null) { 164 bdata = new byte[numBands]; 165 } else { 166 bdata = (byte[])obj; 167 } 168 169 for (int i = 0; i < numBands; i++) { 170 bdata[i] = (byte)getSample(x, y, i, data); 171 } 172 173 obj = bdata; 174 break; 175 } 176 case DataBuffer.TYPE_SHORT: 177 case DataBuffer.TYPE_USHORT: { 178 short sdata[]; 179 180 if (obj == null) { 181 sdata = new short[numBands]; 182 } else { 183 sdata = (short[])obj; 184 } 185 186 for (int i = 0; i < numBands; i++) { 187 sdata[i] = (short)getSample(x, y, i, data); 188 } 189 190 obj = sdata; 191 break; 192 } 193 case DataBuffer.TYPE_INT: { 194 int idata[]; 195 196 if (obj == null) { 197 idata = new int[numBands]; 198 } else { 199 idata = (int[])obj; 200 } 201 202 for (int i = 0; i < numBands; i++) { 203 idata[i] = getSample(x, y, i, data); 204 } 205 206 obj = idata; 207 break; 208 } 209 case DataBuffer.TYPE_FLOAT: { 210 float fdata[]; 211 212 if (obj == null) { 213 fdata = new float[numBands]; 214 } else { 215 fdata = (float[])obj; 216 } 217 218 for (int i = 0; i < numBands; i++) { 219 fdata[i] = getSampleFloat(x, y, i, data); 220 } 221 222 obj = fdata; 223 break; 224 } 225 case DataBuffer.TYPE_DOUBLE: { 226 double ddata[]; 227 228 if (obj == null) { 229 ddata = new double[numBands]; 230 } else { 231 ddata = (double[])obj; 232 } 233 234 for (int i = 0; i < numBands; i++) { 235 ddata[i] = getSampleDouble(x, y, i, data); 236 } 237 238 obj = ddata; 239 break; 240 } 241 } 242 243 return obj; 244 } 245 246 @Override getPixel(int x, int y, int iArray[], DataBuffer data)247 public int[] getPixel(int x, int y, int iArray[], DataBuffer data) { 248 int pixel[]; 249 if (iArray == null) { 250 pixel = new int[numBands]; 251 } else { 252 pixel = iArray; 253 } 254 255 for (int i = 0; i < numBands; i++) { 256 pixel[i] = getSample(x, y, i, data); 257 } 258 259 return pixel; 260 } 261 262 @Override getSample(int x, int y, int b, DataBuffer data)263 public int getSample(int x, int y, int b, DataBuffer data) { 264 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 265 // awt.63=Coordinates are not in bounds 266 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 267 } 268 269 return data.getElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b]); 270 } 271 272 @Override getSampleDouble(int x, int y, int b, DataBuffer data)273 public double getSampleDouble(int x, int y, int b, DataBuffer data) { 274 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 275 // awt.63=Coordinates are not in bounds 276 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 277 } 278 279 return data.getElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b]); 280 } 281 282 @Override getSampleFloat(int x, int y, int b, DataBuffer data)283 public float getSampleFloat(int x, int y, int b, DataBuffer data) { 284 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 285 // awt.63=Coordinates are not in bounds 286 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 287 } 288 289 return data.getElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b]); 290 } 291 292 @Override getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data)293 public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) { 294 int samples[]; 295 int idx = 0; 296 297 if (iArray == null) { 298 samples = new int[w * h]; 299 } else { 300 samples = iArray; 301 } 302 303 for (int i = y; i < y + h; i++) { 304 for (int j = x; j < x + w; j++) { 305 samples[idx++] = getSample(j, i, b, data); 306 } 307 } 308 309 return samples; 310 } 311 312 @Override hashCode()313 public int hashCode() { 314 int hash = super.hashCode(); 315 int tmp = hash >>> 8; 316 hash <<= 8; 317 hash |= tmp; 318 319 return hash ^ 0x55; 320 } 321 322 @Override setDataElements(int x, int y, Object obj, DataBuffer data)323 public void setDataElements(int x, int y, Object obj, DataBuffer data) { 324 switch (dataType) { 325 case DataBuffer.TYPE_BYTE: 326 byte bdata[] = (byte[])obj; 327 for (int i = 0; i < numBands; i++) { 328 setSample(x, y, i, bdata[i] & 0xff, data); 329 } 330 break; 331 332 case DataBuffer.TYPE_SHORT: 333 case DataBuffer.TYPE_USHORT: 334 short sdata[] = (short[])obj; 335 for (int i = 0; i < numBands; i++) { 336 setSample(x, y, i, sdata[i] & 0xffff, data); 337 } 338 break; 339 340 case DataBuffer.TYPE_INT: 341 int idata[] = (int[])obj; 342 for (int i = 0; i < numBands; i++) { 343 setSample(x, y, i, idata[i], data); 344 } 345 break; 346 347 case DataBuffer.TYPE_FLOAT: 348 float fdata[] = (float[])obj; 349 for (int i = 0; i < numBands; i++) { 350 setSample(x, y, i, fdata[i], data); 351 } 352 break; 353 354 case DataBuffer.TYPE_DOUBLE: 355 double ddata[] = (double[])obj; 356 for (int i = 0; i < numBands; i++) { 357 setSample(x, y, i, ddata[i], data); 358 } 359 break; 360 } 361 } 362 363 @Override setPixel(int x, int y, int iArray[], DataBuffer data)364 public void setPixel(int x, int y, int iArray[], DataBuffer data) { 365 for (int i = 0; i < numBands; i++) { 366 setSample(x, y, i, iArray[i], data); 367 } 368 } 369 370 @Override setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data)371 public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) { 372 int idx = 0; 373 374 for (int i = y; i < y + h; i++) { 375 for (int j = x; j < x + w; j++) { 376 for (int n = 0; n < numBands; n++) { 377 setSample(j, i, n, iArray[idx++], data); 378 } 379 } 380 } 381 } 382 383 @Override setSample(int x, int y, int b, double s, DataBuffer data)384 public void setSample(int x, int y, int b, double s, DataBuffer data) { 385 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 386 // awt.63=Coordinates are not in bounds 387 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 388 } 389 390 data.setElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s); 391 } 392 393 @Override setSample(int x, int y, int b, float s, DataBuffer data)394 public void setSample(int x, int y, int b, float s, DataBuffer data) { 395 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 396 // awt.63=Coordinates are not in bounds 397 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 398 } 399 400 data.setElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s); 401 } 402 403 @Override setSample(int x, int y, int b, int s, DataBuffer data)404 public void setSample(int x, int y, int b, int s, DataBuffer data) { 405 if (x < 0 || y < 0 || x >= this.width || y >= this.height) { 406 // awt.63=Coordinates are not in bounds 407 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 408 } 409 410 data.setElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s); 411 } 412 413 @Override setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data)414 public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) { 415 int idx = 0; 416 417 for (int i = y; i < y + h; i++) { 418 for (int j = x; j < x + w; j++) { 419 setSample(j, i, b, iArray[idx++], data); 420 } 421 } 422 423 } 424 425 } 426