1 7 8 17 18 package java.awt.image; 19 20 import java.util.Arrays ; 21 22 57 58 public class ComponentSampleModel extends SampleModel 59 { 60 61 protected int bandOffsets[]; 62 63 64 protected int[] bankIndices; 65 66 70 protected int numBands = 1; 71 72 76 protected int numBanks = 1; 77 78 82 protected int scanlineStride; 83 84 87 protected int pixelStride; 88 89 static private native void initIDs(); 90 static { 91 ColorModel.loadLibraries(); 92 initIDs(); 93 } 94 95 123 public ComponentSampleModel(int dataType, 124 int w, int h, 125 int pixelStride, 126 int scanlineStride, 127 int bandOffsets[]) { 128 super(dataType, w, h, bandOffsets.length); 129 this.dataType = dataType; 130 this.pixelStride = pixelStride; 131 this.scanlineStride = scanlineStride; 132 this.bandOffsets = (int[])bandOffsets.clone(); 133 numBands = bandOffsets.length; 134 if (pixelStride < 0) { 135 throw new IllegalArgumentException ("Pixel stride must be >= 0"); 136 } 137 if (scanlineStride < 0) { 139 throw new IllegalArgumentException ("Scanline stride must be >= 0"); 140 } 141 if (numBands < 1) { 142 throw new IllegalArgumentException ("Must have at least one band."); 143 } 144 if ((dataType < DataBuffer.TYPE_BYTE) || 145 (dataType > DataBuffer.TYPE_DOUBLE)) { 146 throw new IllegalArgumentException ("Unsupported dataType."); 147 } 148 bankIndices = new int[numBands]; 149 for (int i=0; i<numBands; i++) { 150 bankIndices[i] = 0; 151 } 152 } 153 154 155 185 public ComponentSampleModel(int dataType, 186 int w, int h, 187 int pixelStride, 188 int scanlineStride, 189 int bankIndices[], 190 int bandOffsets[]) { 191 super(dataType, w, h, bandOffsets.length); 192 this.dataType = dataType; 193 this.pixelStride = pixelStride; 194 this.scanlineStride = scanlineStride; 195 this.bandOffsets = (int[])bandOffsets.clone(); 196 this.bankIndices = (int[]) bankIndices.clone(); 197 if (pixelStride < 0) { 198 throw new IllegalArgumentException ("Pixel stride must be >= 0"); 199 } 200 if (scanlineStride < 0) { 202 throw new IllegalArgumentException ("Scanline stride must be >= 0"); 203 } 204 if ((dataType < DataBuffer.TYPE_BYTE) || 205 (dataType > DataBuffer.TYPE_DOUBLE)) { 206 throw new IllegalArgumentException ("Unsupported dataType."); 207 } 208 int maxBank = bankIndices[0]; 209 if (maxBank < 0) { 210 throw new IllegalArgumentException ("Index of bank 0 is less than "+ 211 "0 ("+maxBank+")"); 212 } 213 for (int i=1; i < bankIndices.length; i++) { 214 if (bankIndices[i] > maxBank) { 215 maxBank = bankIndices[i]; 216 } 217 else if (bankIndices[i] < 0) { 218 throw new IllegalArgumentException ("Index of bank "+i+ 219 " is less than 0 ("+ 220 maxBank+")"); 221 } 222 } 223 numBanks = maxBank+1; 224 numBands = bandOffsets.length; 225 if (bandOffsets.length != bankIndices.length) { 226 throw new IllegalArgumentException ("Length of bandOffsets must "+ 227 "equal length of bankIndices."); 228 } 229 } 230 231 235 private long getBufferSize() { 236 int maxBandOff=bandOffsets[0]; 237 for (int i=1; i<bandOffsets.length; i++) 238 maxBandOff = Math.max(maxBandOff,bandOffsets[i]); 239 240 long size = 0; 241 if (maxBandOff >= 0) 242 size += maxBandOff+1; 243 if (pixelStride > 0) 244 size += pixelStride * (width-1); 245 if (scanlineStride > 0) 246 size += scanlineStride*(height-1); 247 return size; 248 } 249 250 253 int []orderBands(int orig[], int step) { 254 int map[] = new int[orig.length]; 255 int ret[] = new int[orig.length]; 256 257 for (int i=0; i<map.length; i++) map[i] = i; 258 259 for (int i = 0; i < ret.length; i++) { 260 int index = i; 261 for (int j = i+1; j < ret.length; j++) { 262 if (orig[map[index]] > orig[map[j]]) { 263 index = j; 264 } 265 } 266 ret[map[index]] = i*step; 267 map[index] = map[i]; 268 } 269 return ret; 270 } 271 272 283 public SampleModel createCompatibleSampleModel(int w, int h) { 284 SampleModel ret=null; 285 long size; 286 int minBandOff=bandOffsets[0]; 287 int maxBandOff=bandOffsets[0]; 288 for (int i=1; i<bandOffsets.length; i++) { 289 minBandOff = Math.min(minBandOff,bandOffsets[i]); 290 maxBandOff = Math.max(maxBandOff,bandOffsets[i]); 291 } 292 maxBandOff -= minBandOff; 293 294 int bands = bandOffsets.length; 295 int bandOff[]; 296 int pStride = Math.abs(pixelStride); 297 int lStride = Math.abs(scanlineStride); 298 int bStride = Math.abs(maxBandOff); 299 300 if (pStride > lStride) { 301 if (pStride > bStride) { 302 if (lStride > bStride) { bandOff = new int[bandOffsets.length]; 304 for (int i=0; i<bands; i++) 305 bandOff[i] = bandOffsets[i]-minBandOff; 306 lStride = bStride+1; 307 pStride = lStride*h; 308 } else { bandOff = orderBands(bandOffsets,lStride*h); 310 pStride = bands*lStride*h; 311 } 312 } else { pStride = lStride*h; 314 bandOff = orderBands(bandOffsets,pStride*w); 315 } 316 } else { 317 if (pStride > bStride) { bandOff = new int[bandOffsets.length]; 319 for (int i=0; i<bands; i++) 320 bandOff[i] = bandOffsets[i]-minBandOff; 321 pStride = bStride+1; 322 lStride = pStride*w; 323 } else { 324 if (lStride > bStride) { bandOff = orderBands(bandOffsets,pStride*w); 326 lStride = bands*pStride*w; 327 } else { lStride = pStride*w; 329 bandOff = orderBands(bandOffsets,lStride*h); 330 } 331 } 332 } 333 334 int base = 0; 336 if (scanlineStride < 0) { 337 base += lStride*h; 338 lStride *= -1; 339 } 340 if (pixelStride < 0) { 341 base += pStride*w; 342 pStride *= -1; 343 } 344 345 for (int i=0; i<bands; i++) 346 bandOff[i] += base; 347 return new ComponentSampleModel (dataType, w, h, pStride, 348 lStride, bankIndices, bandOff); 349 } 350 351 363 public SampleModel createSubsetSampleModel(int bands[]) { 364 if (bands.length > bankIndices.length) 365 throw new RasterFormatException ("There are only " + 366 bankIndices.length + 367 " bands"); 368 int newBankIndices[] = new int[bands.length]; 369 int newBandOffsets[] = new int[bands.length]; 370 371 for (int i=0; i<bands.length; i++) { 372 newBankIndices[i] = bankIndices[bands[i]]; 373 newBandOffsets[i] = bandOffsets[bands[i]]; 374 } 375 376 return new ComponentSampleModel (this.dataType, width, height, 377 this.pixelStride, 378 this.scanlineStride, 379 newBankIndices, newBandOffsets); 380 } 381 382 391 public DataBuffer createDataBuffer() { 392 DataBuffer dataBuffer = null; 393 394 int size = (int)getBufferSize(); 395 switch (dataType) { 396 case DataBuffer.TYPE_BYTE: 397 dataBuffer = new DataBufferByte (size, numBanks); 398 break; 399 case DataBuffer.TYPE_USHORT: 400 dataBuffer = new DataBufferUShort (size, numBanks); 401 break; 402 case DataBuffer.TYPE_SHORT: 403 dataBuffer = new DataBufferShort (size, numBanks); 404 break; 405 case DataBuffer.TYPE_INT: 406 dataBuffer = new DataBufferInt (size, numBanks); 407 break; 408 case DataBuffer.TYPE_FLOAT: 409 dataBuffer = new DataBufferFloat (size, numBanks); 410 break; 411 case DataBuffer.TYPE_DOUBLE: 412 dataBuffer = new DataBufferDouble (size, numBanks); 413 break; 414 } 415 416 return dataBuffer; 417 } 418 419 420 431 public int getOffset(int x, int y) { 432 int offset = y*scanlineStride + x*pixelStride + bandOffsets[0]; 433 return offset; 434 } 435 436 447 public int getOffset(int x, int y, int b) { 448 int offset = y*scanlineStride + x*pixelStride + bandOffsets[b]; 449 return offset; 450 } 451 452 457 public final int[] getSampleSize() { 458 int sampleSize[] = new int [numBands]; 459 int sizeInBits = getSampleSize(0); 460 461 for (int i=0; i<numBands; i++) 462 sampleSize[i] = sizeInBits; 463 464 return sampleSize; 465 } 466 467 471 public final int getSampleSize(int band) { 472 return DataBuffer.getDataTypeSize(dataType); 473 } 474 475 478 public final int [] getBankIndices() { 479 return (int[]) bankIndices.clone(); 480 } 481 482 485 public final int [] getBandOffsets() { 486 return (int[])bandOffsets.clone(); 487 } 488 489 492 public final int getScanlineStride() { 493 return scanlineStride; 494 } 495 496 499 public final int getPixelStride() { 500 return pixelStride; 501 } 502 503 517 public final int getNumDataElements() { 518 return getNumBands(); 519 } 520 521 568 public Object getDataElements(int x, int y, Object obj, DataBuffer data) { 569 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 570 throw new ArrayIndexOutOfBoundsException 571 ("Coordinate out of bounds!"); 572 } 573 574 int type = getTransferType(); 575 int numDataElems = getNumDataElements(); 576 int pixelOffset = y*scanlineStride + x*pixelStride; 577 578 switch(type) { 579 580 case DataBuffer.TYPE_BYTE: 581 582 byte[] bdata; 583 584 if (obj == null) 585 bdata = new byte[numDataElems]; 586 else 587 bdata = (byte[])obj; 588 589 for (int i=0; i<numDataElems; i++) { 590 bdata[i] = (byte)data.getElem(bankIndices[i], 591 pixelOffset + bandOffsets[i]); 592 } 593 594 obj = (Object )bdata; 595 break; 596 597 case DataBuffer.TYPE_USHORT: 598 case DataBuffer.TYPE_SHORT: 599 600 short[] sdata; 601 602 if (obj == null) 603 sdata = new short[numDataElems]; 604 else 605 sdata = (short[])obj; 606 607 for (int i=0; i<numDataElems; i++) { 608 sdata[i] = (short)data.getElem(bankIndices[i], 609 pixelOffset + bandOffsets[i]); 610 } 611 612 obj = (Object )sdata; 613 break; 614 615 case DataBuffer.TYPE_INT: 616 617 int[] idata; 618 619 if (obj == null) 620 idata = new int[numDataElems]; 621 else 622 idata = (int[])obj; 623 624 for (int i=0; i<numDataElems; i++) { 625 idata[i] = data.getElem(bankIndices[i], 626 pixelOffset + bandOffsets[i]); 627 } 628 629 obj = (Object )idata; 630 break; 631 632 case DataBuffer.TYPE_FLOAT: 633 634 float[] fdata; 635 636 if (obj == null) 637 fdata = new float[numDataElems]; 638 else 639 fdata = (float[])obj; 640 641 for (int i=0; i<numDataElems; i++) { 642 fdata[i] = data.getElemFloat(bankIndices[i], 643 pixelOffset + bandOffsets[i]); 644 } 645 646 obj = (Object )fdata; 647 break; 648 649 case DataBuffer.TYPE_DOUBLE: 650 651 double[] ddata; 652 653 if (obj == null) 654 ddata = new double[numDataElems]; 655 else 656 ddata = (double[])obj; 657 658 for (int i=0; i<numDataElems; i++) { 659 ddata[i] = data.getElemDouble(bankIndices[i], 660 pixelOffset + bandOffsets[i]); 661 } 662 663 obj = (Object )ddata; 664 break; 665 } 666 667 return obj; 668 } 669 670 685 public int[] getPixel(int x, int y, int iArray[], DataBuffer data) { 686 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 687 throw new ArrayIndexOutOfBoundsException 688 ("Coordinate out of bounds!"); 689 } 690 int pixels[]; 691 if (iArray != null) { 692 pixels = iArray; 693 } else { 694 pixels = new int [numBands]; 695 } 696 int pixelOffset = y*scanlineStride + x*pixelStride; 697 for (int i=0; i<numBands; i++) { 698 pixels[i] = data.getElem(bankIndices[i], 699 pixelOffset + bandOffsets[i]); 700 } 701 return pixels; 702 } 703 704 717 public int[] getPixels(int x, int y, int w, int h, 718 int iArray[], DataBuffer data) { 719 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 720 throw new ArrayIndexOutOfBoundsException 721 ("Coordinate out of bounds!"); 722 } 723 int pixels[]; 724 if (iArray != null) { 725 pixels = iArray; 726 } else { 727 pixels = new int [w*h*numBands]; 728 } 729 int lineOffset = y*scanlineStride + x*pixelStride; 730 int srcOffset = 0; 731 732 for (int i = 0; i < h; i++) { 733 int pixelOffset = lineOffset; 734 for (int j = 0; j < w; j++) { 735 for (int k=0; k < numBands; k++) { 736 pixels[srcOffset++] = 737 data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]); 738 } 739 pixelOffset += pixelStride; 740 } 741 lineOffset += scanlineStride; 742 } 743 return pixels; 744 } 745 746 757 public int getSample(int x, int y, int b, DataBuffer data) { 758 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 760 throw new ArrayIndexOutOfBoundsException 761 ("Coordinate out of bounds!"); 762 } 763 int sample = data.getElem(bankIndices[b], 764 y*scanlineStride + x*pixelStride + 765 bandOffsets[b]); 766 return sample; 767 } 768 769 780 public float getSampleFloat(int x, int y, int b, DataBuffer data) { 781 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 783 throw new ArrayIndexOutOfBoundsException 784 ("Coordinate out of bounds!"); 785 } 786 787 float sample = data.getElemFloat(bankIndices[b], 788 y*scanlineStride + x*pixelStride + 789 bandOffsets[b]); 790 return sample; 791 } 792 793 804 public double getSampleDouble(int x, int y, int b, DataBuffer data) { 805 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 807 throw new ArrayIndexOutOfBoundsException 808 ("Coordinate out of bounds!"); 809 } 810 811 double sample = data.getElemDouble(bankIndices[b], 812 y*scanlineStride + x*pixelStride + 813 bandOffsets[b]); 814 return sample; 815 } 816 817 832 public int[] getSamples(int x, int y, int w, int h, int b, 833 int iArray[], DataBuffer data) { 834 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 836 throw new ArrayIndexOutOfBoundsException 837 ("Coordinate out of bounds!"); 838 } 839 int samples[]; 840 if (iArray != null) { 841 samples = iArray; 842 } else { 843 samples = new int [w*h]; 844 } 845 int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b]; 846 int srcOffset = 0; 847 848 for (int i = 0; i < h; i++) { 849 int sampleOffset = lineOffset; 850 for (int j = 0; j < w; j++) { 851 samples[srcOffset++] = data.getElem(bankIndices[b], 852 sampleOffset); 853 sampleOffset += pixelStride; 854 } 855 lineOffset += scanlineStride; 856 } 857 return samples; 858 } 859 860 896 public void setDataElements(int x, int y, Object obj, DataBuffer data) { 897 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 898 throw new ArrayIndexOutOfBoundsException 899 ("Coordinate out of bounds!"); 900 } 901 902 int type = getTransferType(); 903 int numDataElems = getNumDataElements(); 904 int pixelOffset = y*scanlineStride + x*pixelStride; 905 906 switch(type) { 907 908 case DataBuffer.TYPE_BYTE: 909 910 byte[] barray = (byte[])obj; 911 912 for (int i=0; i<numDataElems; i++) { 913 data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], 914 ((int)barray[i])&0xff); 915 } 916 break; 917 918 case DataBuffer.TYPE_USHORT: 919 case DataBuffer.TYPE_SHORT: 920 921 short[] sarray = (short[])obj; 922 923 for (int i=0; i<numDataElems; i++) { 924 data.setElem(bankIndices[i], pixelOffset + bandOffsets[i], 925 ((int)sarray[i])&0xffff); 926 } 927 break; 928 929 case DataBuffer.TYPE_INT: 930 931 int[] iarray = (int[])obj; 932 933 for (int i=0; i<numDataElems; i++) { 934 data.setElem(bankIndices[i], 935 pixelOffset + bandOffsets[i], iarray[i]); 936 } 937 break; 938 939 case DataBuffer.TYPE_FLOAT: 940 941 float[] farray = (float[])obj; 942 943 for (int i=0; i<numDataElems; i++) { 944 data.setElemFloat(bankIndices[i], 945 pixelOffset + bandOffsets[i], farray[i]); 946 } 947 break; 948 949 case DataBuffer.TYPE_DOUBLE: 950 951 double[] darray = (double[])obj; 952 953 for (int i=0; i<numDataElems; i++) { 954 data.setElemDouble(bankIndices[i], 955 pixelOffset + bandOffsets[i], darray[i]); 956 } 957 break; 958 959 } 960 } 961 962 972 public void setPixel(int x, int y, int iArray[], DataBuffer data) { 973 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 974 throw new ArrayIndexOutOfBoundsException 975 ("Coordinate out of bounds!"); 976 } 977 int pixelOffset = y*scanlineStride + x*pixelStride; 978 for (int i=0; i<numBands; i++) { 979 data.setElem(bankIndices[i], 980 pixelOffset + bandOffsets[i],iArray[i]); 981 } 982 } 983 984 996 public void setPixels(int x, int y, int w, int h, 997 int iArray[], DataBuffer data) { 998 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 999 throw new ArrayIndexOutOfBoundsException 1000 ("Coordinate out of bounds!"); 1001 } 1002 1003 int lineOffset = y*scanlineStride + x*pixelStride; 1004 int srcOffset = 0; 1005 1006 for (int i = 0; i < h; i++) { 1007 int pixelOffset = lineOffset; 1008 for (int j = 0; j < w; j++) { 1009 for (int k=0; k < numBands; k++) { 1010 data.setElem(bankIndices[k], pixelOffset + bandOffsets[k], 1011 iArray[srcOffset++]); 1012 } 1013 pixelOffset += pixelStride; 1014 } 1015 lineOffset += scanlineStride; 1016 } 1017 } 1018 1019 1030 public void setSample(int x, int y, int b, int s, 1031 DataBuffer data) { 1032 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 1034 throw new ArrayIndexOutOfBoundsException 1035 ("Coordinate out of bounds!"); 1036 } 1037 data.setElem(bankIndices[b], 1038 y*scanlineStride + x*pixelStride + bandOffsets[b], s); 1039 } 1040 1041 1052 public void setSample(int x, int y, int b, 1053 float s , 1054 DataBuffer data) { 1055 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 1057 throw new ArrayIndexOutOfBoundsException 1058 ("Coordinate out of bounds!"); 1059 } 1060 data.setElemFloat(bankIndices[b], 1061 y*scanlineStride + x*pixelStride + bandOffsets[b], 1062 s); 1063 } 1064 1065 1076 public void setSample(int x, int y, int b, 1077 double s, 1078 DataBuffer data) { 1079 if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) { 1081 throw new ArrayIndexOutOfBoundsException 1082 ("Coordinate out of bounds!"); 1083 } 1084 data.setElemDouble(bankIndices[b], 1085 y*scanlineStride + x*pixelStride + bandOffsets[b], 1086 s); 1087 } 1088 1089 1102 public void setSamples(int x, int y, int w, int h, int b, 1103 int iArray[], DataBuffer data) { 1104 if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) { 1106 throw new ArrayIndexOutOfBoundsException 1107 ("Coordinate out of bounds!"); 1108 } 1109 int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b]; 1110 int srcOffset = 0; 1111 1112 for (int i = 0; i < h; i++) { 1113 int sampleOffset = lineOffset; 1114 for (int j = 0; j < w; j++) { 1115 data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]); 1116 sampleOffset += pixelStride; 1117 } 1118 lineOffset += scanlineStride; 1119 } 1120 } 1121 1122 public boolean equals(Object o) { 1123 if ((o == null) || !(o instanceof ComponentSampleModel )) { 1124 return false; 1125 } 1126 1127 ComponentSampleModel that = (ComponentSampleModel )o; 1128 return this.width == that.width && 1129 this.height == that.height && 1130 this.numBands == that.numBands && 1131 this.dataType == that.dataType && 1132 Arrays.equals(this.bandOffsets, that.bandOffsets) && 1133 Arrays.equals(this.bankIndices, that.bankIndices) && 1134 this.numBands == that.numBands && 1135 this.numBanks == that.numBanks && 1136 this.scanlineStride == that.scanlineStride && 1137 this.pixelStride == that.pixelStride; 1138 } 1139 1140 public int hashCode() { 1142 int hash = 0; 1143 hash = width; 1144 hash <<= 8; 1145 hash ^= height; 1146 hash <<= 8; 1147 hash ^= numBands; 1148 hash <<= 8; 1149 hash ^= dataType; 1150 hash <<= 8; 1151 for (int i = 0; i < bandOffsets.length; i++) { 1152 hash ^= bandOffsets[i]; 1153 hash <<= 8; 1154 } 1155 for (int i = 0; i < bankIndices.length; i++) { 1156 hash ^= bankIndices[i]; 1157 hash <<= 8; 1158 } 1159 hash ^= numBands; 1160 hash <<= 8; 1161 hash ^= numBanks; 1162 hash <<= 8; 1163 hash ^= scanlineStride; 1164 hash <<= 8; 1165 hash ^= pixelStride; 1166 return hash; 1167 } 1168} 1169 | Popular Tags |