1 7 8 17 18 package java.awt.image; 19 20 import java.util.Arrays ; 21 22 47 48 public class SinglePixelPackedSampleModel extends SampleModel 49 { 50 51 private int bitMasks[]; 52 53 54 private int bitOffsets[]; 55 56 57 private int bitSizes[]; 58 59 60 private int maxBitSize; 61 62 65 private int scanlineStride; 66 67 private static native void initIDs(); 68 static { 69 ColorModel.loadLibraries(); 70 initIDs(); 71 } 72 73 89 public SinglePixelPackedSampleModel(int dataType, int w, int h, 90 int bitMasks[]) { 91 this(dataType, w, h, w, bitMasks); 92 if (dataType != DataBuffer.TYPE_BYTE && 93 dataType != DataBuffer.TYPE_USHORT && 94 dataType != DataBuffer.TYPE_INT) { 95 throw new IllegalArgumentException ("Unsupported data type "+ 96 dataType); 97 } 98 } 99 100 122 public SinglePixelPackedSampleModel(int dataType, int w, int h, 123 int scanlineStride, int bitMasks[]) { 124 super(dataType, w, h, bitMasks.length); 125 if (dataType != DataBuffer.TYPE_BYTE && 126 dataType != DataBuffer.TYPE_USHORT && 127 dataType != DataBuffer.TYPE_INT) { 128 throw new IllegalArgumentException ("Unsupported data type "+ 129 dataType); 130 } 131 this.dataType = dataType; 132 this.bitMasks = (int[]) bitMasks.clone(); 133 this.scanlineStride = scanlineStride; 134 135 this.bitOffsets = new int[numBands]; 136 this.bitSizes = new int[numBands]; 137 138 this.maxBitSize = 0; 139 for (int i=0; i<numBands; i++) { 140 int bitOffset = 0, bitSize = 0, mask; 141 mask = bitMasks[i]; 142 143 if (mask != 0) { 144 while ((mask & 1) == 0) { 145 mask = mask >>> 1; 146 bitOffset++; 147 } 148 while ((mask & 1) == 1) { 149 mask = mask >>> 1; 150 bitSize++; 151 } 152 if (mask != 0) { 153 throw new IllegalArgumentException ("Mask "+bitMasks[i]+ 154 " must be contiguous"); 155 } 156 } 157 bitOffsets[i] = bitOffset; 158 bitSizes[i] = bitSize; 159 if (bitSize > maxBitSize) { 160 maxBitSize = bitSize; 161 } 162 } 163 } 164 165 170 public int getNumDataElements() { 171 return 1; 172 } 173 174 179 private long getBufferSize() { 180 long size = scanlineStride * (height-1) + width; 181 return size; 182 } 183 184 196 public SampleModel createCompatibleSampleModel(int w, int h) { 197 SampleModel sampleModel = new SinglePixelPackedSampleModel (dataType, w, h, 198 bitMasks); 199 return sampleModel; 200 } 201 202 208 public DataBuffer createDataBuffer() { 209 DataBuffer dataBuffer = null; 210 211 int size = (int)getBufferSize(); 212 switch (dataType) { 213 case DataBuffer.TYPE_BYTE: 214 dataBuffer = new DataBufferByte (size); 215 break; 216 case DataBuffer.TYPE_USHORT: 217 dataBuffer = new DataBufferUShort (size); 218 break; 219 case DataBuffer.TYPE_INT: 220 dataBuffer = new DataBufferInt (size); 221 break; 222 } 223 return dataBuffer; 224 } 225 226 227 public int[] getSampleSize() { 228 int mask; 229 int sampleSize[] = new int [numBands]; 230 for (int i=0; i<numBands; i++) { 231 sampleSize[i] = 0; 232 mask = bitMasks[i] >>> bitOffsets[i]; 233 while ((mask & 1) != 0) { 234 sampleSize[i] ++; 235 mask = mask >>> 1; 236 } 237 } 238 239 return sampleSize; 240 } 241 242 243 public int getSampleSize(int band) { 244 int sampleSize = 0; 245 int mask = bitMasks[band] >>> bitOffsets[band]; 246 while ((mask & 1) != 0) { 247 sampleSize ++; 248 mask = mask >>> 1; 249 } 250 251 return sampleSize; 252 } 253 254 264 public int getOffset(int x, int y) { 265 int offset = y * scanlineStride + x; 266 return offset; 267 } 268 269 273 public int [] getBitOffsets() { 274 return (int[])bitOffsets.clone(); 275 } 276 277 280 public int [] getBitMasks() { 281 return (int[])bitMasks.clone(); 282 } 283 284 288 public int getScanlineStride() { 289 return scanlineStride; 290 } 291 292 304 public SampleModel createSubsetSampleModel(int bands[]) { 305 if (bands.length > numBands) 306 throw new RasterFormatException ("There are only " + 307 numBands + 308 " bands"); 309 int newBitMasks[] = new int[bands.length]; 310 for (int i=0; i<bands.length; i++) 311 newBitMasks[i] = bitMasks[bands[i]]; 312 313 return new SinglePixelPackedSampleModel (this.dataType, width, height, 314 this.scanlineStride, newBitMasks); 315 } 316 317 356 public Object getDataElements(int x, int y, Object obj, DataBuffer data) { 357 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 359 throw new ArrayIndexOutOfBoundsException 360 ("Coordinate out of bounds!"); 361 } 362 363 int type = getTransferType(); 364 365 switch(type) { 366 367 case DataBuffer.TYPE_BYTE: 368 369 byte[] bdata; 370 371 if (obj == null) 372 bdata = new byte[1]; 373 else 374 bdata = (byte[])obj; 375 376 bdata[0] = (byte)data.getElem(y * scanlineStride + x); 377 378 obj = (Object )bdata; 379 break; 380 381 case DataBuffer.TYPE_USHORT: 382 383 short[] sdata; 384 385 if (obj == null) 386 sdata = new short[1]; 387 else 388 sdata = (short[])obj; 389 390 sdata[0] = (short)data.getElem(y * scanlineStride + x); 391 392 obj = (Object )sdata; 393 break; 394 395 case DataBuffer.TYPE_INT: 396 397 int[] idata; 398 399 if (obj == null) 400 idata = new int[1]; 401 else 402 idata = (int[])obj; 403 404 idata[0] = data.getElem(y * scanlineStride + x); 405 406 obj = (Object )idata; 407 break; 408 } 409 410 return obj; 411 } 412 413 424 public int [] getPixel(int x, int y, int iArray[], DataBuffer data) { 425 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 426 throw new ArrayIndexOutOfBoundsException 427 ("Coordinate out of bounds!"); 428 } 429 int pixels[]; 430 if (iArray == null) { 431 pixels = new int [numBands]; 432 } else { 433 pixels = iArray; 434 } 435 436 int value = data.getElem(y * scanlineStride + x); 437 for (int i=0; i<numBands; i++) { 438 pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i]; 439 } 440 return pixels; 441 } 442 443 457 public int[] getPixels(int x, int y, int w, int h, 458 int iArray[], DataBuffer data) { 459 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 460 throw new ArrayIndexOutOfBoundsException 461 ("Coordinate out of bounds!"); 462 } 463 int pixels[]; 464 if (iArray != null) { 465 pixels = iArray; 466 } else { 467 pixels = new int [w*h*numBands]; 468 } 469 int lineOffset = y*scanlineStride + x; 470 int dstOffset = 0; 471 472 for (int i = 0; i < h; i++) { 473 for (int j = 0; j < w; j++) { 474 int value = data.getElem(lineOffset+j); 475 for (int k=0; k < numBands; k++) { 476 pixels[dstOffset++] = 477 ((value & bitMasks[k]) >>> bitOffsets[k]); 478 } 479 } 480 lineOffset += scanlineStride; 481 } 482 return pixels; 483 } 484 485 498 public int getSample(int x, int y, int b, DataBuffer data) { 499 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 501 throw new ArrayIndexOutOfBoundsException 502 ("Coordinate out of bounds!"); 503 } 504 int sample = data.getElem(y * scanlineStride + x); 505 return ((sample & bitMasks[b]) >>> bitOffsets[b]); 506 } 507 508 524 public int[] getSamples(int x, int y, int w, int h, int b, 525 int iArray[], DataBuffer data) { 526 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 528 throw new ArrayIndexOutOfBoundsException 529 ("Coordinate out of bounds!"); 530 } 531 int samples[]; 532 if (iArray != null) { 533 samples = iArray; 534 } else { 535 samples = new int [w*h]; 536 } 537 int lineOffset = y*scanlineStride + x; 538 int dstOffset = 0; 539 540 for (int i = 0; i < h; i++) { 541 for (int j = 0; j < w; j++) { 542 int value = data.getElem(lineOffset+j); 543 samples[dstOffset++] = 544 ((value & bitMasks[b]) >>> bitOffsets[b]); 545 } 546 lineOffset += scanlineStride; 547 } 548 return samples; 549 } 550 551 586 public void setDataElements(int x, int y, Object obj, DataBuffer data) { 587 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 588 throw new ArrayIndexOutOfBoundsException 589 ("Coordinate out of bounds!"); 590 } 591 592 int type = getTransferType(); 593 594 switch(type) { 595 596 case DataBuffer.TYPE_BYTE: 597 598 byte[] barray = (byte[])obj; 599 data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff); 600 break; 601 602 case DataBuffer.TYPE_USHORT: 603 604 short[] sarray = (short[])obj; 605 data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff); 606 break; 607 608 case DataBuffer.TYPE_INT: 609 610 int[] iarray = (int[])obj; 611 data.setElem(y*scanlineStride+x, iarray[0]); 612 break; 613 } 614 } 615 616 626 public void setPixel(int x, int y, 627 int iArray[], 628 DataBuffer data) { 629 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 630 throw new ArrayIndexOutOfBoundsException 631 ("Coordinate out of bounds!"); 632 } 633 int lineOffset = y * scanlineStride + x; 634 int value = data.getElem(lineOffset); 635 for (int i=0; i < numBands; i++) { 636 value &= ~bitMasks[i]; 637 value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]); 638 } 639 data.setElem(lineOffset, value); 640 } 641 642 655 public void setPixels(int x, int y, int w, int h, 656 int iArray[], DataBuffer data) { 657 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 658 throw new ArrayIndexOutOfBoundsException 659 ("Coordinate out of bounds!"); 660 } 661 662 int lineOffset = y*scanlineStride + x; 663 int srcOffset = 0; 664 665 for (int i = 0; i < h; i++) { 666 for (int j = 0; j < w; j++) { 667 int value = data.getElem(lineOffset+j); 668 for (int k=0; k < numBands; k++) { 669 value &= ~bitMasks[k]; 670 int srcValue = iArray[srcOffset++]; 671 value |= ((srcValue << bitOffsets[k]) 672 & bitMasks[k]); 673 } 674 data.setElem(lineOffset+j, value); 675 } 676 lineOffset += scanlineStride; 677 } 678 } 679 680 692 public void setSample(int x, int y, int b, int s, 693 DataBuffer data) { 694 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 696 throw new ArrayIndexOutOfBoundsException 697 ("Coordinate out of bounds!"); 698 } 699 int value = data.getElem(y*scanlineStride + x); 700 value &= ~bitMasks[b]; 701 value |= (s << bitOffsets[b]) & bitMasks[b]; 702 data.setElem(y*scanlineStride + x,value); 703 } 704 705 719 public void setSamples(int x, int y, int w, int h, int b, 720 int iArray[], DataBuffer data) { 721 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 723 throw new ArrayIndexOutOfBoundsException 724 ("Coordinate out of bounds!"); 725 } 726 int lineOffset = y*scanlineStride + x; 727 int srcOffset = 0; 728 729 for (int i = 0; i < h; i++) { 730 for (int j = 0; j < w; j++) { 731 int value = data.getElem(lineOffset+j); 732 value &= ~bitMasks[b]; 733 int sample = iArray[srcOffset++]; 734 value |= ((int)sample << bitOffsets[b]) & bitMasks[b]; 735 data.setElem(lineOffset+j,value); 736 } 737 lineOffset += scanlineStride; 738 } 739 } 740 741 public boolean equals(Object o) { 742 if ((o == null) || !(o instanceof SinglePixelPackedSampleModel )) { 743 return false; 744 } 745 746 SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel )o; 747 return this.width == that.width && 748 this.height == that.height && 749 this.numBands == that.numBands && 750 this.dataType == that.dataType && 751 Arrays.equals(this.bitMasks, that.bitMasks) && 752 Arrays.equals(this.bitOffsets, that.bitOffsets) && 753 Arrays.equals(this.bitSizes, that.bitSizes) && 754 this.maxBitSize == that.maxBitSize && 755 this.scanlineStride == that.scanlineStride; 756 } 757 758 public int hashCode() { 760 int hash = 0; 761 hash = width; 762 hash <<= 8; 763 hash ^= height; 764 hash <<= 8; 765 hash ^= numBands; 766 hash <<= 8; 767 hash ^= dataType; 768 hash <<= 8; 769 for (int i = 0; i < bitMasks.length; i++) { 770 hash ^= bitMasks[i]; 771 hash <<= 8; 772 } 773 for (int i = 0; i < bitOffsets.length; i++) { 774 hash ^= bitOffsets[i]; 775 hash <<= 8; 776 } 777 for (int i = 0; i < bitSizes.length; i++) { 778 hash ^= bitSizes[i]; 779 hash <<= 8; 780 } 781 hash ^= maxBitSize; 782 hash <<= 8; 783 hash ^= scanlineStride; 784 return hash; 785 } 786 } 787 | Popular Tags |