165 protected int numDataElements; 166 167 /** The parent of this Raster, or null. */ 168 protected Raster parent; 169 170 private static native void initIDs(); 171 static { 172 ColorModel.loadLibraries(); 173 initIDs(); 174 } 175 176 /** 177 * Creates a Raster based on a PixelInterleavedSampleModel with the 178 * specified data type, width, height, and number of bands. 179 * 180 * <p> The upper left corner of the Raster is given by the 181 * location argument. If location is null, (0, 0) will be used. 182 * The dataType parameter should be one of the enumerated values 183 * defined in the DataBuffer class. 184 * 185 * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code> 186 * Rasters are not supported. To create a 1-band Raster of type 187 * <code>DataBuffer.TYPE_INT</code>, use 188 * Raster.createPackedRaster(). 189 * <p> The only dataTypes supported currently are TYPE_BYTE 190 * and TYPE_USHORT. 191 * @param dataType the data type for storing samples 192 * @param w the width in pixels of the image data 193 * @param h the height in pixels of the image data 194 * @param bands the number of bands 195 * @param location the upper-left corner of the <code>Raster</code> 196 * @return a WritableRaster object with the specified data type, 197 * width, height and number of bands. 198 * @throws RasterFormatException if <code>w</code> or <code>h</code> 199 * is less than or equal to zero, or computing either 200 * <code>location.x + w</code> or 201 * <code>location.y + h</code> results in integer 202 * overflow 203 */ 204 public static WritableRaster createInterleavedRaster(int dataType, 205 int w, int h, 206 int bands, 207 Point location) { 208 int[] bandOffsets = new int[bands]; 209 for (int i = 0; i < bands; i++) { 210 bandOffsets[i] = i; 211 } 212 return createInterleavedRaster(dataType, w, h, w*bands, bands, 213 bandOffsets, location); 214 } 215 216 /** 217 * Creates a Raster based on a PixelInterleavedSampleModel with the 218 * specified data type, width, height, scanline stride, pixel 219 * stride, and band offsets. The number of bands is inferred from 220 * bandOffsets.length. 221 * 222 * <p> The upper left corner of the Raster is given by the 223 * location argument. If location is null, (0, 0) will be used. 224 * The dataType parameter should be one of the enumerated values 225 * defined in the DataBuffer class. 226 * 227 * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code> 228 * Rasters are not supported. To create a 1-band Raster of type 229 * <code>DataBuffer.TYPE_INT</code>, use 230 * Raster.createPackedRaster(). 231 * <p> The only dataTypes supported currently are TYPE_BYTE 232 * and TYPE_USHORT. 233 * @param dataType the data type for storing samples 234 * @param w the width in pixels of the image data 235 * @param h the height in pixels of the image data 236 * @param scanlineStride the line stride of the image data 237 * @param pixelStride the pixel stride of the image data 238 * @param bandOffsets the offsets of all bands 239 * @param location the upper-left corner of the <code>Raster</code> 240 * @return a WritableRaster object with the specified data type, 241 * width, height, scanline stride, pixel stride and band 242 * offsets. 243 * @throws RasterFormatException if <code>w</code> or <code>h</code> 244 * is less than or equal to zero, or computing either 245 * <code>location.x + w</code> or 246 * <code>location.y + h</code> results in integer 247 * overflow 248 * @throws IllegalArgumentException if <code>dataType</code> is not 249 * one of the supported data types, which are 250 * <code>DataBuffer.TYPE_BYTE</code>, or 251 * <code>DataBuffer.TYPE_USHORT</code>. 252 */ 253 public static WritableRaster createInterleavedRaster(int dataType, 254 int w, int h, 255 int scanlineStride, 256 int pixelStride, 257 int bandOffsets[], 258 Point location) { 259 DataBuffer d; 260 261 int size = scanlineStride * (h - 1) + // fisrt (h - 1) scans 262 pixelStride * w; // last scan 263 264 switch(dataType) { 265 case DataBuffer.TYPE_BYTE: 266 d = new DataBufferByte(size); 267 break; 268 269 case DataBuffer.TYPE_USHORT: 270 d = new DataBufferUShort(size); 271 break; 277 278 return createInterleavedRaster(d, w, h, scanlineStride, 279 pixelStride, bandOffsets, location); 280 } 281 282 /** 283 * Creates a Raster based on a BandedSampleModel with the 284 * specified data type, width, height, and number of bands. 285 * 286 * <p> The upper left corner of the Raster is given by the 287 * location argument. If location is null, (0, 0) will be used. 288 * The dataType parameter should be one of the enumerated values 289 * defined in the DataBuffer class. 290 * 291 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 292 * and TYPE_INT. 293 * @param dataType the data type for storing samples 294 * @param w the width in pixels of the image data 295 * @param h the height in pixels of the image data 296 * @param bands the number of bands 297 * @param location the upper-left corner of the <code>Raster</code> 298 * @return a WritableRaster object with the specified data type, 299 * width, height and number of bands. 300 * @throws RasterFormatException if <code>w</code> or <code>h</code> 301 * is less than or equal to zero, or computing either 302 * <code>location.x + w</code> or 303 * <code>location.y + h</code> results in integer 304 * overflow 305 * @throws ArrayIndexOutOfBoundsException if <code>bands</code> 306 * is less than 1 307 */ 308 public static WritableRaster createBandedRaster(int dataType, 309 int w, int h, 310 int bands, 311 Point location) { 312 if (bands < 1) { 313 throw new ArrayIndexOutOfBoundsException("Number of bands ("+ 314 bands+") must"+ 315 " be greater than 0"); 316 } 317 int[] bankIndices = new int[bands]; 318 int[] bandOffsets = new int[bands]; 319 for (int i = 0; i < bands; i++) { 320 bankIndices[i] = i; 321 bandOffsets[i] = 0; 322 } 323 324 return createBandedRaster(dataType, w, h, w, 325 bankIndices, bandOffsets, 328 329 /** 330 * Creates a Raster based on a BandedSampleModel with the 331 * specified data type, width, height, scanline stride, bank 332 * indices and band offsets. The number of bands is inferred from 333 * bankIndices.length and bandOffsets.length, which must be the 334 * same. 335 * 336 * <p> The upper left corner of the Raster is given by the 337 * location argument. The dataType parameter should be one of the 338 * enumerated values defined in the DataBuffer class. 339 * 340 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 341 * and TYPE_INT. 342 * @param dataType the data type for storing samples 343 * @param w the width in pixels of the image data 344 * @param h the height in pixels of the image data 345 * @param scanlineStride the line stride of the image data 346 * @param bankIndices the bank indices for each band 347 * @param bandOffsets the offsets of all bands 348 * @param location the upper-left corner of the <code>Raster</code> 349 * @return a WritableRaster object with the specified data type, 350 * width, height, scanline stride, bank indices and band 351 * offsets. 352 * @throws RasterFormatException if <code>w</code> or <code>h</code> 353 * is less than or equal to zero, or computing either 354 * <code>location.x + w</code> or 355 * <code>location.y + h</code> results in integer 356 * overflow 357 * @throws IllegalArgumentException if <code>dataType</code> is not 358 * one of the supported data types, which are 359 * <code>DataBuffer.TYPE_BYTE</code>, 360 * <code>DataBuffer.TYPE_USHORT</code> 361 * or <code>DataBuffer.TYPE_INT</code> 362 * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code> 363 * or <code>bandOffsets</code> is <code>null</code> 364 */ 365 public static WritableRaster createBandedRaster(int dataType, 366 int w, int h, 367 int scanlineStride, 368 int bankIndices[], 369 int bandOffsets[], 370 Point location) { 371 DataBuffer d; 372 int bands = bandOffsets.length; 373 374 if (bankIndices == null) { 375 throw new 376 ArrayIndexOutOfBoundsException("Bank indices array is null"); 377 } 378 if (bandOffsets == null) { 379 throw new 380 ArrayIndexOutOfBoundsException("Band offsets array is null"); 381 } 382 383 // Figure out the #banks and the largest band offset 417 return createBandedRaster(d, w, h, scanlineStride, 418 bankIndices, bandOffsets, location); 419 } 420 421 /** 422 * Creates a Raster based on a SinglePixelPackedSampleModel with 423 * the specified data type, width, height, and band masks. 424 * The number of bands is inferred from bandMasks.length. 425 * 426 * <p> The upper left corner of the Raster is given by the 427 * location argument. If location is null, (0, 0) will be used. 428 * The dataType parameter should be one of the enumerated values 429 * defined in the DataBuffer class. 430 * 431 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 432 * and TYPE_INT. 433 * @param dataType the data type for storing samples 434 * @param w the width in pixels of the image data 435 * @param h the height in pixels of the image data 436 * @param bandMasks an array containing an entry for each band 437 * @param location the upper-left corner of the <code>Raster</code> 438 * @return a WritableRaster object with the specified data type, 439 * width, height, and band masks. 440 * @throws RasterFormatException if <code>w</code> or <code>h</code> 441 * is less than or equal to zero, or computing either 442 * <code>location.x + w</code> or 443 * <code>location.y + h</code> results in integer 444 * overflow 445 * @throws IllegalArgumentException if <code>dataType</code> is not 446 * one of the supported data types, which are 447 * <code>DataBuffer.TYPE_BYTE</code>, 448 * <code>DataBuffer.TYPE_USHORT</code> 449 * or <code>DataBuffer.TYPE_INT</code> 450 */ 451 public static WritableRaster createPackedRaster(int dataType, 452 int w, int h, 453 int bandMasks[], 454 Point location) { 455 DataBuffer d; 456 457 switch(dataType) { 458 case DataBuffer.TYPE_BYTE: 459 d = new DataBufferByte(w*h); 460 break; 461 462 case DataBuffer.TYPE_USHORT: 463 d = new DataBufferUShort(w*h); 464 break; 465 466 case DataBuffer.TYPE_INT: 467 d = new DataBufferInt(w*h); 468 break; 469 482 * be a MultiPixelPackedSampleModel. 483 * 484 * <p> If the number of bands is more than one, the SampleModel 485 * will be a SinglePixelPackedSampleModel, with each band having 486 * bitsPerBand bits. In either case, the requirements on dataType 487 * and bitsPerBand imposed by the corresponding SampleModel must 488 * be met. 489 * 490 * <p> The upper left corner of the Raster is given by the 491 * location argument. If location is null, (0, 0) will be used. 492 * The dataType parameter should be one of the enumerated values 493 * defined in the DataBuffer class. 494 * 495 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 496 * and TYPE_INT. 497 * @param dataType the data type for storing samples 498 * @param w the width in pixels of the image data 499 * @param h the height in pixels of the image data 500 * @param bands the number of bands 501 * @param bitsPerBand the number of bits per band 502 * @param location the upper-left corner of the <code>Raster</code> 503 * @return a WritableRaster object with the specified data type, 504 * width, height, number of bands, and bits per band. 505 * @throws RasterFormatException if <code>w</code> or <code>h</code> 506 * is less than or equal to zero, or computing either 507 * <code>location.x + w</code> or 508 * <code>location.y + h</code> results in integer 509 * overflow 510 * @throws IllegalArgumentException if the product of 511 * <code>bitsPerBand</code> and <code>bands</code> is 512 * greater than the number of bits held by 513 * <code>dataType</code> 514 * @throws IllegalArgumentException if <code>bitsPerBand</code> or 515 * <code>bands</code> is not greater than zero 516 * @throws IllegalArgumentException if <code>dataType</code> is not 517 * one of the supported data types, which are 518 * <code>DataBuffer.TYPE_BYTE</code>, 519 * <code>DataBuffer.TYPE_USHORT</code> 520 * or <code>DataBuffer.TYPE_INT</code> 521 */ 522 public static WritableRaster createPackedRaster(int dataType, 523 int w, int h, 524 int bands, 525 int bitsPerBand, 526 Point location) { 527 DataBuffer d; 528 529 if (bands <= 0) { 530 throw new IllegalArgumentException("Number of bands ("+bands+ 531 ") must be greater than 0"); 532 } 533 534 if (bitsPerBand <= 0) { 535 throw new IllegalArgumentException("Bits per band ("+bitsPerBand+ 536 ") must be greater than 0"); 537 } 538 539 if (bands != 1) { 540 int[] masks = new int[bands]; 579 case DataBuffer.TYPE_INT: 580 d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h); 581 break; 582 583 default: 584 throw new IllegalArgumentException("Unsupported data type " + 585 dataType); 586 } 587 588 return createPackedRaster(d, w, h, bitsPerBand, location); 589 } 590 } 591 592 /** 593 * Creates a Raster based on a PixelInterleavedSampleModel with the 594 * specified DataBuffer, width, height, scanline stride, pixel 595 * stride, and band offsets. The number of bands is inferred from 596 * bandOffsets.length. The upper left corner of the Raster 597 * is given by the location argument. If location is null, (0, 0) 598 * will be used. 599 * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code> 600 * Rasters are not supported. To create a 1-band Raster of type 601 * <code>DataBuffer.TYPE_INT</code>, use 602 * Raster.createPackedRaster(). 603 * @param dataBuffer the <code>DataBuffer</code> that contains the 604 * image data 605 * @param w the width in pixels of the image data 606 * @param h the height in pixels of the image data 607 * @param scanlineStride the line stride of the image data 608 * @param pixelStride the pixel stride of the image data 609 * @param bandOffsets the offsets of all bands 610 * @param location the upper-left corner of the <code>Raster</code> 611 * @return a WritableRaster object with the specified 612 * <code>DataBuffer</code>, width, height, scanline stride, 613 * pixel stride and band offsets. 614 * @throws RasterFormatException if <code>w</code> or <code>h</code> 615 * is less than or equal to zero, or computing either 616 * <code>location.x + w</code> or 617 * <code>location.y + h</code> results in integer 618 * overflow 619 * @throws IllegalArgumentException if <code>dataType</code> is not 620 * one of the supported data types, which are 621 * <code>DataBuffer.TYPE_BYTE</code>, 622 * <code>DataBuffer.TYPE_USHORT</code> 623 * @throws RasterFormatException if <code>dataBuffer</code> has more 624 * than one bank. 625 * @throws NullPointerException if <code>dataBuffer</code> is null 626 */ 627 public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, 628 int w, int h, 629 int scanlineStride, 630 int pixelStride, 631 int bandOffsets[], 632 Point location) { 633 if (dataBuffer == null) { 634 throw new NullPointerException("DataBuffer cannot be null"); 635 } 636 if (location == null) { 637 location = new Point(0, 0); 638 } 639 int dataType = dataBuffer.getDataType(); 640 641 PixelInterleavedSampleModel csm = 642 new PixelInterleavedSampleModel(dataType, w, h, 643 pixelStride, 644 scanlineStride, 645 bandOffsets); 646 switch(dataType) { 647 case DataBuffer.TYPE_BYTE: 648 return new ByteInterleavedRaster(csm, dataBuffer, location); 649 650 case DataBuffer.TYPE_USHORT: 651 return new ShortInterleavedRaster(csm, dataBuffer, location); 652 653 default: 654 throw new IllegalArgumentException("Unsupported data type " + 655 dataType); 656 } 657 } 658 659 /** 660 * Creates a Raster based on a BandedSampleModel with the 661 * specified DataBuffer, width, height, scanline stride, bank 662 * indices, and band offsets. The number of bands is inferred 663 * from bankIndices.length and bandOffsets.length, which must be 664 * the same. The upper left corner of the Raster is given by the 665 * location argument. If location is null, (0, 0) will be used. 666 * @param dataBuffer the <code>DataBuffer</code> that contains the 667 * image data 668 * @param w the width in pixels of the image data 669 * @param h the height in pixels of the image data 670 * @param scanlineStride the line stride of the image data 671 * @param bankIndices the bank indices for each band 672 * @param bandOffsets the offsets of all bands 673 * @param location the upper-left corner of the <code>Raster</code> 674 * @return a WritableRaster object with the specified 675 * <code>DataBuffer</code>, width, height, scanline stride, 676 * bank indices and band offsets. 677 * @throws RasterFormatException if <code>w</code> or <code>h</code> 678 * is less than or equal to zero, or computing either 679 * <code>location.x + w</code> or 680 * <code>location.y + h</code> results in integer 681 * overflow 682 * @throws IllegalArgumentException if <code>dataType</code> is not 683 * one of the supported data types, which are 684 * <code>DataBuffer.TYPE_BYTE</code>, 685 * <code>DataBuffer.TYPE_USHORT</code> 686 * or <code>DataBuffer.TYPE_INT</code> 687 * @throws NullPointerException if <code>dataBuffer</code> is null 688 */ 689 public static WritableRaster createBandedRaster(DataBuffer dataBuffer, 690 int w, int h, 691 int scanlineStride, 692 int bankIndices[], 693 int bandOffsets[], 694 Point location) { 695 if (dataBuffer == null) { 696 throw new NullPointerException("DataBuffer cannot be null"); 697 } 698 if (location == null) { 699 location = new Point(0,0); 700 } 701 int dataType = dataBuffer.getDataType(); 702 703 int bands = bankIndices.length; 704 if (bandOffsets.length != bands) { 705 throw new IllegalArgumentException( 706 "bankIndices.length != bandOffsets.length"); 707 } 716 return new ByteBandedRaster(bsm, dataBuffer, location); 717 718 case DataBuffer.TYPE_USHORT: 719 return new ShortBandedRaster(bsm, dataBuffer, location); 720 721 case DataBuffer.TYPE_INT: 722 return new SunWritableRaster(bsm, dataBuffer, location); 723 724 default: 725 throw new IllegalArgumentException("Unsupported data type " + 726 dataType); 727 } 728 } 729 730 /** 731 * Creates a Raster based on a SinglePixelPackedSampleModel with 732 * the specified DataBuffer, width, height, scanline stride, and 733 * band masks. The number of bands is inferred from bandMasks.length. 734 * The upper left corner of the Raster is given by 735 * the location argument. If location is null, (0, 0) will be used. 736 * @param dataBuffer the <code>DataBuffer</code> that contains the 737 * image data 738 * @param w the width in pixels of the image data 739 * @param h the height in pixels of the image data 740 * @param scanlineStride the line stride of the image data 741 * @param bandMasks an array containing an entry for each band 742 * @param location the upper-left corner of the <code>Raster</code> 743 * @return a WritableRaster object with the specified 744 * <code>DataBuffer</code>, width, height, scanline stride, 745 * and band masks. 746 * @throws RasterFormatException if <code>w</code> or <code>h</code> 747 * is less than or equal to zero, or computing either 748 * <code>location.x + w</code> or 749 * <code>location.y + h</code> results in integer 750 * overflow 751 * @throws IllegalArgumentException if <code>dataType</code> is not 752 * one of the supported data types, which are 753 * <code>DataBuffer.TYPE_BYTE</code>, 754 * <code>DataBuffer.TYPE_USHORT</code> 755 * or <code>DataBuffer.TYPE_INT</code> 756 * @throws RasterFormatException if <code>dataBuffer</code> has more 757 * than one bank. 758 * @throws NullPointerException if <code>dataBuffer</code> is null 759 */ 760 public static WritableRaster createPackedRaster(DataBuffer dataBuffer, 761 int w, int h, 762 int scanlineStride, 763 int bandMasks[], 764 Point location) { 765 if (dataBuffer == null) { 766 throw new NullPointerException("DataBuffer cannot be null"); 767 } 768 if (location == null) { 769 location = new Point(0,0); 770 } 771 int dataType = dataBuffer.getDataType(); 772 773 SinglePixelPackedSampleModel sppsm = 774 new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride, 775 bandMasks); 776 777 switch(dataType) { 778 case DataBuffer.TYPE_BYTE: 779 return new ByteInterleavedRaster(sppsm, dataBuffer, location); 780 781 case DataBuffer.TYPE_USHORT: 782 return new ShortInterleavedRaster(sppsm, dataBuffer, location); 783 784 case DataBuffer.TYPE_INT: 785 return new IntegerInterleavedRaster(sppsm, dataBuffer, location); 786 787 default: 788 throw new IllegalArgumentException("Unsupported data type " + 789 dataType); 790 } 791 } 792 793 /** 794 * Creates a Raster based on a MultiPixelPackedSampleModel with the 795 * specified DataBuffer, width, height, and bits per pixel. The upper 796 * left corner of the Raster is given by the location argument. If 797 * location is null, (0, 0) will be used. 798 * @param dataBuffer the <code>DataBuffer</code> that contains the 799 * image data 800 * @param w the width in pixels of the image data 801 * @param h the height in pixels of the image data 802 * @param bitsPerPixel the number of bits for each pixel 803 * @param location the upper-left corner of the <code>Raster</code> 804 * @return a WritableRaster object with the specified 805 * <code>DataBuffer</code>, width, height, and 806 * bits per pixel. 807 * @throws RasterFormatException if <code>w</code> or <code>h</code> 808 * is less than or equal to zero, or computing either 809 * <code>location.x + w</code> or 810 * <code>location.y + h</code> results in integer 811 * overflow 812 * @throws IllegalArgumentException if <code>dataType</code> is not 813 * one of the supported data types, which are 814 * <code>DataBuffer.TYPE_BYTE</code>, 815 * <code>DataBuffer.TYPE_USHORT</code> 816 * or <code>DataBuffer.TYPE_INT</code> 817 * @throws RasterFormatException if <code>dataBuffer</code> has more 818 * than one bank. 819 * @throws NullPointerException if <code>dataBuffer</code> is null 820 */ 821 public static WritableRaster createPackedRaster(DataBuffer dataBuffer, 822 int w, int h, 823 int bitsPerPixel, 824 Point location) { 825 if (dataBuffer == null) { 826 throw new NullPointerException("DataBuffer cannot be null"); 827 } 828 if (location == null) { 829 location = new Point(0,0); 830 } 831 int dataType = dataBuffer.getDataType(); 832 833 if (dataType != DataBuffer.TYPE_BYTE && 834 dataType != DataBuffer.TYPE_USHORT && 835 dataType != DataBuffer.TYPE_INT) { 836 throw new IllegalArgumentException("Unsupported data type " + 837 dataType); 838 } 839 842 RasterFormatException("DataBuffer for packed Rasters"+ 843 " must only have 1 bank."); 844 } 845 846 MultiPixelPackedSampleModel mppsm = 847 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel); 848 849 if (dataType == DataBuffer.TYPE_BYTE && 850 (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) { 851 return new BytePackedRaster(mppsm, dataBuffer, location); 852 } else { 853 return new SunWritableRaster(mppsm, dataBuffer, location); 854 } 855 } 856 857 858 /** 859 * Creates a Raster with the specified SampleModel and DataBuffer. 860 * The upper left corner of the Raster is given by the location argument. 861 * If location is null, (0, 0) will be used. 862 * @param sm the specified <code>SampleModel</code> 863 * @param db the specified <code>DataBuffer</code> 864 * @param location the upper-left corner of the <code>Raster</code> 865 * @return a <code>Raster</code> with the specified 866 * <code>SampleModel</code>, <code>DataBuffer</code>, and 867 * location. 868 * @throws RasterFormatException if computing either 869 * <code>location.x + sm.getWidth()</code> or 870 * <code>location.y + sm.getHeight()</code> results in integer 871 * overflow 872 * @throws RasterFormatException if <code>db</code> has more 873 * than one bank and <code>sm</code> is a 874 * PixelInterleavedSampleModel, SinglePixelPackedSampleModel, 875 * or MultiPixelPackedSampleModel. 876 * @throws NullPointerException if either SampleModel or DataBuffer is 877 * null 878 */ 879 public static Raster createRaster(SampleModel sm, 880 DataBuffer db, 881 Point location) { 882 if ((sm == null) || (db == null)) { 883 throw new NullPointerException("SampleModel and DataBuffer cannot be null"); 884 } 885 886 if (location == null) { 887 location = new Point(0,0); 888 } 889 int dataType = sm.getDataType(); 890 891 if (sm instanceof PixelInterleavedSampleModel) { 892 switch(dataType) { 893 case DataBuffer.TYPE_BYTE: 905 return new ShortInterleavedRaster(sm, db, location); 906 907 case DataBuffer.TYPE_INT: 908 return new IntegerInterleavedRaster(sm, db, location); 909 } 910 } else if (sm instanceof MultiPixelPackedSampleModel && 911 dataType == DataBuffer.TYPE_BYTE && 912 sm.getSampleSize(0) < 8) { 913 return new BytePackedRaster(sm, db, location); 914 } 915 916 // we couldn't do anything special - do the generic thing 917 918 return new Raster(sm,db,location); 919 } 920 921 /** 922 * Creates a WritableRaster with the specified SampleModel. 923 * The upper left corner of the Raster is given by the location argument. 924 * If location is null, (0, 0) will be used. 925 * @param sm the specified <code>SampleModel</code> 926 * @param location the upper-left corner of the 927 * <code>WritableRaster</code> 928 * @return a <code>WritableRaster</code> with the specified 929 * <code>SampleModel</code> and location. 930 * @throws RasterFormatException if computing either 931 * <code>location.x + sm.getWidth()</code> or 932 * <code>location.y + sm.getHeight()</code> results in integer 933 * overflow 934 */ 935 public static WritableRaster createWritableRaster(SampleModel sm, 936 Point location) { 937 if (location == null) { 938 location = new Point(0,0); 939 } 940 941 return createWritableRaster(sm, sm.createDataBuffer(), location); 942 } 943 944 /** 945 * Creates a WritableRaster with the specified SampleModel and DataBuffer. 946 * The upper left corner of the Raster is given by the location argument. 947 * If location is null, (0, 0) will be used. 948 * @param sm the specified <code>SampleModel</code> 949 * @param db the specified <code>DataBuffer</code> 950 * @param location the upper-left corner of the 951 * <code>WritableRaster</code> 952 * @return a <code>WritableRaster</code> with the specified 953 * <code>SampleModel</code>, <code>DataBuffer</code>, and 954 * location. 955 * @throws RasterFormatException if computing either 956 * <code>location.x + sm.getWidth()</code> or 957 * <code>location.y + sm.getHeight()</code> results in integer 958 * overflow 959 * @throws RasterFormatException if <code>db</code> has more 960 * than one bank and <code>sm</code> is a 961 * PixelInterleavedSampleModel, SinglePixelPackedSampleModel, 962 * or MultiPixelPackedSampleModel. 963 * @throws NullPointerException if either SampleModel or DataBuffer is null 964 */ 965 public static WritableRaster createWritableRaster(SampleModel sm, 966 DataBuffer db, 967 Point location) { 968 if ((sm == null) || (db == null)) { 969 throw new NullPointerException("SampleModel and DataBuffer cannot be null"); 970 } 971 if (location == null) { 972 location = new Point(0,0); 973 } 974 975 int dataType = sm.getDataType(); 976 977 if (sm instanceof PixelInterleavedSampleModel) { 978 switch(dataType) { 979 case DataBuffer.TYPE_BYTE: 980 return new ByteInterleavedRaster(sm, db, location); 995 } 996 } else if (sm instanceof MultiPixelPackedSampleModel && 997 dataType == DataBuffer.TYPE_BYTE && 998 sm.getSampleSize(0) < 8) { 999 return new BytePackedRaster(sm, db, location); 1000 } 1001 1002 // we couldn't do anything special - do the generic thing 1003 1004 return new SunWritableRaster(sm,db,location); 1005 } 1006 1007 /** 1008 * Constructs a Raster with the given SampleModel. The Raster's 1009 * upper left corner is origin and it is the same size as the 1010 * SampleModel. A DataBuffer large enough to describe the 1011 * Raster is automatically created. 1012 * @param sampleModel The SampleModel that specifies the layout 1013 * @param origin The Point that specified the origin 1014 * @throws RasterFormatException if computing either 1015 * <code>origin.x + sampleModel.getWidth()</code> or 1016 * <code>origin.y + sampleModel.getHeight()</code> results in 1017 * integer overflow 1018 * @throws NullPointerException either <code>sampleModel</code> or 1019 * <code>origin</code> is null 1020 */ 1021 protected Raster(SampleModel sampleModel, 1022 Point origin) { 1023 this(sampleModel, 1024 sampleModel.createDataBuffer(), 1025 new Rectangle(origin.x, 1026 origin.y, 1027 sampleModel.getWidth(), 1028 sampleModel.getHeight()), 1029 origin, 1030 null); 1031 } 1032 1033 /** 1034 * Constructs a Raster with the given SampleModel and DataBuffer. 1035 * The Raster's upper left corner is origin and it is the same size 1036 * as the SampleModel. The DataBuffer is not initialized and must 1037 * be compatible with SampleModel. 1038 * @param sampleModel The SampleModel that specifies the layout 1039 * @param dataBuffer The DataBuffer that contains the image data 1040 * @param origin The Point that specifies the origin 1041 * @throws RasterFormatException if computing either 1042 * <code>origin.x + sampleModel.getWidth()</code> or 1043 * <code>origin.y + sampleModel.getHeight()</code> results in 1044 * integer overflow 1045 * @throws NullPointerException either <code>sampleModel</code> or 1046 * <code>origin</code> is null 1047 */ 1048 protected Raster(SampleModel sampleModel, 1049 DataBuffer dataBuffer, 1050 Point origin) { 1051 this(sampleModel, 1052 dataBuffer, 1053 new Rectangle(origin.x, 1054 origin.y, 1055 sampleModel.getWidth(), 1056 sampleModel.getHeight()), 1057 origin, 1058 null); 1059 } 1060 1061 /** 1062 * Constructs a Raster with the given SampleModel, DataBuffer, and 1063 * parent. aRegion specifies the bounding rectangle of the new 1064 * Raster. When translated into the base Raster's coordinate 1065 * system, aRegion must be contained by the base Raster. 1066 * (The base Raster is the Raster's ancestor which has no parent.) 1067 * sampleModelTranslate specifies the sampleModelTranslateX and 1068 * sampleModelTranslateY values of the new Raster. 1069 * 1070 * Note that this constructor should generally be called by other 1071 * constructors or create methods, it should not be used directly. 1072 * @param sampleModel The SampleModel that specifies the layout 1073 * @param dataBuffer The DataBuffer that contains the image data 1074 * @param aRegion The Rectangle that specifies the image area 1075 * @param sampleModelTranslate The Point that specifies the translation 1076 * from SampleModel to Raster coordinates 1077 * @param parent The parent (if any) of this raster 1078 * @throws NullPointerException if any of <code>sampleModel</code>, 1079 * <code>dataBuffer</code>, <code>aRegion</code> or 1080 * <code>sampleModelTranslate</code> is null 1081 * @throws RasterFormatException if <code>aRegion</code> has width 1082 * or height less than or equal to zero, or computing either 1083 * <code>aRegion.x + aRegion.width</code> or 1084 * <code>aRegion.y + aRegion.height</code> results in integer 1085 * overflow 1086 */ 1087 protected Raster(SampleModel sampleModel, 1088 DataBuffer dataBuffer, 1089 Rectangle aRegion, 1090 Point sampleModelTranslate, 1091 Raster parent) { 1092 1093 if ((sampleModel == null) || (dataBuffer == null) || 1094 (aRegion == null) || (sampleModelTranslate == null)) { 1095 throw new NullPointerException("SampleModel, dataBuffer, aRegion and " + 1096 "sampleModelTranslate cannot be null"); 1097 } 1098 this.sampleModel = sampleModel; 1099 this.dataBuffer = dataBuffer; 1100 minX = aRegion.x; 1101 minY = aRegion.y; 1102 width = aRegion.width; 1103 height = aRegion.height; 1104 if (width <= 0 || height <= 0) { 1108 if ((minX + width) < minX) { 1109 throw new RasterFormatException( 1110 "overflow condition for X coordinates of Raster"); 1111 } 1112 if ((minY + height) < minY) { 1113 throw new RasterFormatException( 1114 "overflow condition for Y coordinates of Raster"); 1115 } 1116 1117 sampleModelTranslateX = sampleModelTranslate.x; 1118 sampleModelTranslateY = sampleModelTranslate.y; 1119 1120 numBands = sampleModel.getNumBands(); 1121 numDataElements = sampleModel.getNumDataElements(); 1122 this.parent = parent; 1123 } 1124 1125 1126 /** 1127 * Returns the parent Raster (if any) of this Raster or null. 1128 * @return the parent Raster or <code>null</code>. 1129 */ 1130 public Raster getParent() { 1131 return parent; 1132 } 1133 1134 /** 1135 * Returns the X translation from the coordinate system of the 1136 * SampleModel to that of the Raster. To convert a pixel's X 1137 * coordinate from the Raster coordinate system to the SampleModel 1138 * coordinate system, this value must be subtracted. 1139 * @return the X translation from the coordinate space of the 1140 * Raster's SampleModel to that of the Raster. 1141 */ 1142 public final int getSampleModelTranslateX() { 1143 return sampleModelTranslateX; 1144 } 1145 1146 /** 1147 * Returns the Y translation from the coordinate system of the 1148 * SampleModel to that of the Raster. To convert a pixel's Y 1149 * coordinate from the Raster coordinate system to the SampleModel 1150 * coordinate system, this value must be subtracted. 1151 * @return the Y translation from the coordinate space of the 1152 * Raster's SampleModel to that of the Raster. 1153 */ 1154 public final int getSampleModelTranslateY() { 1155 return sampleModelTranslateY; 1156 } 1157 1158 /** 1159 * Create a compatible WritableRaster the same size as this Raster with 1160 * the same SampleModel and a new initialized DataBuffer. 1161 * @return a compatible <code>WritableRaster</code> with the same sample 1162 * model and a new data buffer. 1163 */ 1164 public WritableRaster createCompatibleWritableRaster() { 1165 return new SunWritableRaster(sampleModel, new Point(0,0)); 1166 } 1167 1168 /** 1169 * Create a compatible WritableRaster with the specified size, a new 1170 * SampleModel, and a new initialized DataBuffer. 1171 * @param w the specified width of the new <code>WritableRaster</code> 1172 * @param h the specified height of the new <code>WritableRaster</code> 1173 * @return a compatible <code>WritableRaster</code> with the specified 1174 * size and a new sample model and data buffer. 1175 * @exception RasterFormatException if the width or height is less than 1176 * or equal to zero. 1177 */ 1178 public WritableRaster createCompatibleWritableRaster(int w, int h) { 1179 if (w <= 0 || h <=0) { 1180 throw new RasterFormatException("negative " + 1181 ((w <= 0) ? "width" : "height")); 1182 } 1183 1184 SampleModel sm = sampleModel.createCompatibleSampleModel(w,h); 1185 1186 return new SunWritableRaster(sm, new Point(0,0)); 1187 } 1188 1189 /** 1190 * Create a compatible WritableRaster with location (minX, minY) 1191 * and size (width, height) specified by rect, a 1192 * new SampleModel, and a new initialized DataBuffer. 1193 * @param rect a <code>Rectangle</code> that specifies the size and 1194 * location of the <code>WritableRaster</code> 1195 * @return a compatible <code>WritableRaster</code> with the specified 1196 * size and location and a new sample model and data buffer. 1197 * @throws RasterFormatException if <code>rect</code> has width 1198 * or height less than or equal to zero, or computing either 1199 * <code>rect.x + rect.width</code> or 1200 * <code>rect.y + rect.height</code> results in integer 1201 * overflow 1202 * @throws NullPointerException if <code>rect</code> is null 1203 */ 1204 public WritableRaster createCompatibleWritableRaster(Rectangle rect) { 1205 if (rect == null) { 1206 throw new NullPointerException("Rect cannot be null"); 1207 } 1208 return createCompatibleWritableRaster(rect.x, rect.y, 1209 rect.width, rect.height); 1210 } 1211 1212 /** 1213 * Create a compatible WritableRaster with the specified 1214 * location (minX, minY) and size (width, height), a 1215 * new SampleModel, and a new initialized DataBuffer. 1216 * @param x the X coordinate of the upper-left corner of 1217 * the <code>WritableRaster</code> 1218 * @param y the Y coordinate of the upper-left corner of 1219 * the <code>WritableRaster</code> 1220 * @param w the specified width of the <code>WritableRaster</code> 1221 * @param h the specified height of the <code>WritableRaster</code> 1222 * @return a compatible <code>WritableRaster</code> with the specified 1223 * size and location and a new sample model and data buffer. 1224 * @throws RasterFormatException if <code>w</code> or <code>h</code> 1225 * is less than or equal to zero, or computing either 1226 * <code>x + w</code> or 1227 * <code>y + h</code> results in integer 1228 * overflow 1229 */ 1230 public WritableRaster createCompatibleWritableRaster(int x, int y, 1231 int w, int h) { 1232 WritableRaster ret = createCompatibleWritableRaster(w, h); 1233 return ret.createWritableChild(0,0,w,h,x,y,null); 1234 } 1235 1236 /** 1237 * Create a Raster with the same size, SampleModel and DataBuffer 1238 * as this one, but with a different location. The new Raster 1239 * will possess a reference to the current Raster, accessible 1240 * through its getParent() method. 1241 * 1242 * @param childMinX the X coordinate of the upper-left 1243 * corner of the new <code>Raster</code> 1244 * @param childMinY the Y coordinate of the upper-left 1245 * corner of the new <code>Raster</code> 1246 * @return a new <code>Raster</code> with the same size, SampleModel, 1247 * and DataBuffer as this <code>Raster</code>, but with the 1248 * specified location. 1249 * @throws RasterFormatException if computing either 1250 * <code>childMinX + this.getWidth()</code> or 1251 * <code>childMinY + this.getHeight()</code> results in integer 1252 * overflow 1253 */ 1254 public Raster createTranslatedChild(int childMinX, int childMinY) { 1255 return createChild(minX,minY,width,height, 1256 childMinX,childMinY,null); 1257 } 1258 1259 /** 1260 * Returns a new Raster which shares all or part of this Raster's 1261 * DataBuffer. The new Raster will possess a reference to the 1262 * current Raster, accessible through its getParent() method. 1263 * 1264 * <p> The parentX, parentY, width and height parameters 1265 * form a Rectangle in this Raster's coordinate space, 1266 * indicating the area of pixels to be shared. An error will 1267 * be thrown if this Rectangle is not contained with the bounds 1268 * of the current Raster. 1269 * 1270 * <p> The new Raster may additionally be translated to a 1271 * different coordinate system for the plane than that used by the current 1280 * of the bandList parameter. If bandList is null, it is taken to 1281 * include all of the bands of the current Raster in their current 1282 * order. 1283 * 1284 * <p> To create a new Raster that contains a subregion of the current 1285 * Raster, but shares its coordinate system and bands, 1286 * this method should be called with childMinX equal to parentX, 1287 * childMinY equal to parentY, and bandList equal to null. 1288 * 1289 * @param parentX The X coordinate of the upper-left corner 1290 * in this Raster's coordinates 1291 * @param parentY The Y coordinate of the upper-left corner 1292 * in this Raster's coordinates 1293 * @param width Width of the region starting at (parentX, parentY) 1294 * @param height Height of the region starting at (parentX, parentY). 1295 * @param childMinX The X coordinate of the upper-left corner 1296 * of the returned Raster 1297 * @param childMinY The Y coordinate of the upper-left corner 1298 * of the returned Raster 1299 * @param bandList Array of band indices, or null to use all bands 1300 * @return a new <code>Raster</code>. 1301 * @exception RasterFormatException if the specified subregion is outside 1302 * of the raster bounds. 1303 * @throws RasterFormatException if <code>width</code> or 1304 * <code>height</code> 1305 * is less than or equal to zero, or computing any of 1306 * <code>parentX + width</code>, <code>parentY + height</code>, 1307 * <code>childMinX + width</code>, or 1308 * <code>childMinY + height</code> results in integer 1309 * overflow 1310 */ 1311 public Raster createChild(int parentX, int parentY, 1312 int width, int height, 1313 int childMinX, int childMinY, 1314 int bandList[]) { 1315 if (parentX < this.minX) { 1316 throw new RasterFormatException("parentX lies outside raster"); 1317 } 1318 if (parentY < this.minY) { 1319 throw new RasterFormatException("parentY lies outside raster"); 1320 } 1321 if ((parentX + width < parentX) || 1322 (parentX + width > this.width + this.minX)) { 1323 throw new RasterFormatException("(parentX + width) is outside raster"); 1324 } 1325 if ((parentY + height < parentY) || 1326 (parentY + height > this.height + this.minY)) { 1327 throw new RasterFormatException("(parentY + height) is outside raster"); 1328 } 1334 // and height represent a "virtual" view of the pixel data, so 1335 // they may be different than those of the SampleModel. 1336 if (bandList == null) { 1337 subSampleModel = sampleModel; 1338 } else { 1339 subSampleModel = sampleModel.createSubsetSampleModel(bandList); 1340 } 1341 1342 int deltaX = childMinX - parentX; 1343 int deltaY = childMinY - parentY; 1344 1345 return new Raster(subSampleModel, getDataBuffer(), 1346 new Rectangle(childMinX, childMinY, width, height), 1347 new Point(sampleModelTranslateX + deltaX, 1348 sampleModelTranslateY + deltaY), this); 1349 } 1350 1351 /** 1352 * Returns the bounding Rectangle of this Raster. This function returns 1353 * the same information as getMinX/MinY/Width/Height. 1354 * @return the bounding box of this <code>Raster</code>. 1355 */ 1356 public Rectangle getBounds() { 1357 return new Rectangle(minX, minY, width, height); 1358 } 1359 1360 /** Returns the minimum valid X coordinate of the Raster. 1361 * @return the minimum x coordinate of this <code>Raster</code>. 1362 */ 1363 public final int getMinX() { 1364 return minX; 1365 } 1366 1367 /** Returns the minimum valid Y coordinate of the Raster. 1368 * @return the minimum y coordinate of this <code>Raster</code>. 1369 */ 1370 public final int getMinY() { 1371 return minY; 1372 } 1373 1374 /** Returns the width in pixels of the Raster. 1375 * @return the width of this <code>Raster</code>. 1376 */ 1377 public final int getWidth() { 1378 return width; 1379 } 1380 1381 /** Returns the height in pixels of the Raster. 1382 * @return the height of this <code>Raster</code>. 1383 */ 1384 public final int getHeight() { 1385 return height; 1386 } 1387 1388 /** Returns the number of bands (samples per pixel) in this Raster. 1389 * @return the number of bands of this <code>Raster</code>. 1390 */ 1391 public final int getNumBands() { 1392 return numBands; 1393 } 1394 1395 /** 1396 * Returns the number of data elements needed to transfer one pixel 1397 * via the getDataElements and setDataElements methods. When pixels 1398 * are transferred via these methods, they may be transferred in a 1399 * packed or unpacked format, depending on the implementation of the 1400 * underlying SampleModel. Using these methods, pixels are transferred 1401 * as an array of getNumDataElements() elements of a primitive type given 1402 * by getTransferType(). The TransferType may or may not be the same 1403 * as the storage data type of the DataBuffer. 1404 * @return the number of data elements. 1405 */ 1406 public final int getNumDataElements() { 1407 return sampleModel.getNumDataElements(); 1408 } 1409 1410 /** 1411 * Returns the TransferType used to transfer pixels via the 1412 * getDataElements and setDataElements methods. When pixels 1413 * are transferred via these methods, they may be transferred in a 1414 * packed or unpacked format, depending on the implementation of the 1415 * underlying SampleModel. Using these methods, pixels are transferred 1416 * as an array of getNumDataElements() elements of a primitive type given 1417 * by getTransferType(). The TransferType may or may not be the same 1418 * as the storage data type of the DataBuffer. The TransferType will 1419 * be one of the types defined in DataBuffer. 1420 * @return this transfer type. 1421 */ 1422 public final int getTransferType() { 1423 return sampleModel.getTransferType(); 1424 } 1425 1426 /** Returns the DataBuffer associated with this Raster. 1427 * @return the <code>DataBuffer</code> of this <code>Raster</code>. 1428 */ 1429 public DataBuffer getDataBuffer() { 1430 return dataBuffer; 1431 } 1432 1433 /** Returns the SampleModel that describes the layout of the image data. 1434 * @return the <code>SampleModel</code> of this <code>Raster</code>. 1435 */ 1436 public SampleModel getSampleModel() { 1437 return sampleModel; 1438 } 1439 1440 /** 1441 * Returns data for a single pixel in a primitive array of type 1442 * TransferType. For image data supported by the Java 2D(tm) API, 1443 * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 1444 * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 1445 * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format, 1446 * thus increasing efficiency for data transfers. 1447 * An ArrayIndexOutOfBoundsException may be thrown 1448 * if the coordinates are not in bounds. However, explicit bounds 1449 * checking is not guaranteed. 1450 * A ClassCastException will be thrown if the input object is non null 1451 * and references anything other than an array of TransferType. 1452 * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer) 1453 * @param x The X coordinate of the pixel location 1454 * @param y The Y coordinate of the pixel location | 165 protected int numDataElements; 166 167 /** The parent of this Raster, or null. */ 168 protected Raster parent; 169 170 private static native void initIDs(); 171 static { 172 ColorModel.loadLibraries(); 173 initIDs(); 174 } 175 176 /** 177 * Creates a Raster based on a PixelInterleavedSampleModel with the 178 * specified data type, width, height, and number of bands. 179 * 180 * <p> The upper left corner of the Raster is given by the 181 * location argument. If location is null, (0, 0) will be used. 182 * The dataType parameter should be one of the enumerated values 183 * defined in the DataBuffer class. 184 * 185 * <p> Note that interleaved {@code DataBuffer.TYPE_INT} 186 * Rasters are not supported. To create a 1-band Raster of type 187 * {@code DataBuffer.TYPE_INT}, use 188 * Raster.createPackedRaster(). 189 * <p> The only dataTypes supported currently are TYPE_BYTE 190 * and TYPE_USHORT. 191 * @param dataType the data type for storing samples 192 * @param w the width in pixels of the image data 193 * @param h the height in pixels of the image data 194 * @param bands the number of bands 195 * @param location the upper-left corner of the {@code Raster} 196 * @return a WritableRaster object with the specified data type, 197 * width, height and number of bands. 198 * @throws RasterFormatException if {@code w} or {@code h} 199 * is less than or equal to zero, or computing either 200 * {@code location.x + w} or 201 * {@code location.y + h} results in integer 202 * overflow 203 */ 204 public static WritableRaster createInterleavedRaster(int dataType, 205 int w, int h, 206 int bands, 207 Point location) { 208 int[] bandOffsets = new int[bands]; 209 for (int i = 0; i < bands; i++) { 210 bandOffsets[i] = i; 211 } 212 return createInterleavedRaster(dataType, w, h, w*bands, bands, 213 bandOffsets, location); 214 } 215 216 /** 217 * Creates a Raster based on a PixelInterleavedSampleModel with the 218 * specified data type, width, height, scanline stride, pixel 219 * stride, and band offsets. The number of bands is inferred from 220 * bandOffsets.length. 221 * 222 * <p> The upper left corner of the Raster is given by the 223 * location argument. If location is null, (0, 0) will be used. 224 * The dataType parameter should be one of the enumerated values 225 * defined in the DataBuffer class. 226 * 227 * <p> Note that interleaved {@code DataBuffer.TYPE_INT} 228 * Rasters are not supported. To create a 1-band Raster of type 229 * {@code DataBuffer.TYPE_INT}, use 230 * Raster.createPackedRaster(). 231 * <p> The only dataTypes supported currently are TYPE_BYTE 232 * and TYPE_USHORT. 233 * @param dataType the data type for storing samples 234 * @param w the width in pixels of the image data 235 * @param h the height in pixels of the image data 236 * @param scanlineStride the line stride of the image data 237 * @param pixelStride the pixel stride of the image data 238 * @param bandOffsets the offsets of all bands 239 * @param location the upper-left corner of the {@code Raster} 240 * @return a WritableRaster object with the specified data type, 241 * width, height, scanline stride, pixel stride and band 242 * offsets. 243 * @throws RasterFormatException if {@code w} or {@code h} 244 * is less than or equal to zero, or computing either 245 * {@code location.x + w} or 246 * {@code location.y + h} results in integer 247 * overflow 248 * @throws IllegalArgumentException if {@code dataType} is not 249 * one of the supported data types, which are 250 * {@code DataBuffer.TYPE_BYTE}, or 251 * {@code DataBuffer.TYPE_USHORT}. 252 */ 253 public static WritableRaster createInterleavedRaster(int dataType, 254 int w, int h, 255 int scanlineStride, 256 int pixelStride, 257 int bandOffsets[], 258 Point location) { 259 DataBuffer d; 260 261 int size = scanlineStride * (h - 1) + // fisrt (h - 1) scans 262 pixelStride * w; // last scan 263 264 switch(dataType) { 265 case DataBuffer.TYPE_BYTE: 266 d = new DataBufferByte(size); 267 break; 268 269 case DataBuffer.TYPE_USHORT: 270 d = new DataBufferUShort(size); 271 break; 277 278 return createInterleavedRaster(d, w, h, scanlineStride, 279 pixelStride, bandOffsets, location); 280 } 281 282 /** 283 * Creates a Raster based on a BandedSampleModel with the 284 * specified data type, width, height, and number of bands. 285 * 286 * <p> The upper left corner of the Raster is given by the 287 * location argument. If location is null, (0, 0) will be used. 288 * The dataType parameter should be one of the enumerated values 289 * defined in the DataBuffer class. 290 * 291 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 292 * and TYPE_INT. 293 * @param dataType the data type for storing samples 294 * @param w the width in pixels of the image data 295 * @param h the height in pixels of the image data 296 * @param bands the number of bands 297 * @param location the upper-left corner of the {@code Raster} 298 * @return a WritableRaster object with the specified data type, 299 * width, height and number of bands. 300 * @throws RasterFormatException if {@code w} or {@code h} 301 * is less than or equal to zero, or computing either 302 * {@code location.x + w} or 303 * {@code location.y + h} results in integer 304 * overflow 305 * @throws ArrayIndexOutOfBoundsException if {@code bands} 306 * is less than 1 307 */ 308 public static WritableRaster createBandedRaster(int dataType, 309 int w, int h, 310 int bands, 311 Point location) { 312 if (bands < 1) { 313 throw new ArrayIndexOutOfBoundsException("Number of bands ("+ 314 bands+") must"+ 315 " be greater than 0"); 316 } 317 int[] bankIndices = new int[bands]; 318 int[] bandOffsets = new int[bands]; 319 for (int i = 0; i < bands; i++) { 320 bankIndices[i] = i; 321 bandOffsets[i] = 0; 322 } 323 324 return createBandedRaster(dataType, w, h, w, 325 bankIndices, bandOffsets, 328 329 /** 330 * Creates a Raster based on a BandedSampleModel with the 331 * specified data type, width, height, scanline stride, bank 332 * indices and band offsets. The number of bands is inferred from 333 * bankIndices.length and bandOffsets.length, which must be the 334 * same. 335 * 336 * <p> The upper left corner of the Raster is given by the 337 * location argument. The dataType parameter should be one of the 338 * enumerated values defined in the DataBuffer class. 339 * 340 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 341 * and TYPE_INT. 342 * @param dataType the data type for storing samples 343 * @param w the width in pixels of the image data 344 * @param h the height in pixels of the image data 345 * @param scanlineStride the line stride of the image data 346 * @param bankIndices the bank indices for each band 347 * @param bandOffsets the offsets of all bands 348 * @param location the upper-left corner of the {@code Raster} 349 * @return a WritableRaster object with the specified data type, 350 * width, height, scanline stride, bank indices and band 351 * offsets. 352 * @throws RasterFormatException if {@code w} or {@code h} 353 * is less than or equal to zero, or computing either 354 * {@code location.x + w} or 355 * {@code location.y + h} results in integer 356 * overflow 357 * @throws IllegalArgumentException if {@code dataType} is not 358 * one of the supported data types, which are 359 * {@code DataBuffer.TYPE_BYTE}, 360 * {@code DataBuffer.TYPE_USHORT} 361 * or {@code DataBuffer.TYPE_INT} 362 * @throws ArrayIndexOutOfBoundsException if {@code bankIndices} 363 * or {@code bandOffsets} is {@code null} 364 */ 365 public static WritableRaster createBandedRaster(int dataType, 366 int w, int h, 367 int scanlineStride, 368 int bankIndices[], 369 int bandOffsets[], 370 Point location) { 371 DataBuffer d; 372 int bands = bandOffsets.length; 373 374 if (bankIndices == null) { 375 throw new 376 ArrayIndexOutOfBoundsException("Bank indices array is null"); 377 } 378 if (bandOffsets == null) { 379 throw new 380 ArrayIndexOutOfBoundsException("Band offsets array is null"); 381 } 382 383 // Figure out the #banks and the largest band offset 417 return createBandedRaster(d, w, h, scanlineStride, 418 bankIndices, bandOffsets, location); 419 } 420 421 /** 422 * Creates a Raster based on a SinglePixelPackedSampleModel with 423 * the specified data type, width, height, and band masks. 424 * The number of bands is inferred from bandMasks.length. 425 * 426 * <p> The upper left corner of the Raster is given by the 427 * location argument. If location is null, (0, 0) will be used. 428 * The dataType parameter should be one of the enumerated values 429 * defined in the DataBuffer class. 430 * 431 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 432 * and TYPE_INT. 433 * @param dataType the data type for storing samples 434 * @param w the width in pixels of the image data 435 * @param h the height in pixels of the image data 436 * @param bandMasks an array containing an entry for each band 437 * @param location the upper-left corner of the {@code Raster} 438 * @return a WritableRaster object with the specified data type, 439 * width, height, and band masks. 440 * @throws RasterFormatException if {@code w} or {@code h} 441 * is less than or equal to zero, or computing either 442 * {@code location.x + w} or 443 * {@code location.y + h} results in integer 444 * overflow 445 * @throws IllegalArgumentException if {@code dataType} is not 446 * one of the supported data types, which are 447 * {@code DataBuffer.TYPE_BYTE}, 448 * {@code DataBuffer.TYPE_USHORT} 449 * or {@code DataBuffer.TYPE_INT} 450 */ 451 public static WritableRaster createPackedRaster(int dataType, 452 int w, int h, 453 int bandMasks[], 454 Point location) { 455 DataBuffer d; 456 457 switch(dataType) { 458 case DataBuffer.TYPE_BYTE: 459 d = new DataBufferByte(w*h); 460 break; 461 462 case DataBuffer.TYPE_USHORT: 463 d = new DataBufferUShort(w*h); 464 break; 465 466 case DataBuffer.TYPE_INT: 467 d = new DataBufferInt(w*h); 468 break; 469 482 * be a MultiPixelPackedSampleModel. 483 * 484 * <p> If the number of bands is more than one, the SampleModel 485 * will be a SinglePixelPackedSampleModel, with each band having 486 * bitsPerBand bits. In either case, the requirements on dataType 487 * and bitsPerBand imposed by the corresponding SampleModel must 488 * be met. 489 * 490 * <p> The upper left corner of the Raster is given by the 491 * location argument. If location is null, (0, 0) will be used. 492 * The dataType parameter should be one of the enumerated values 493 * defined in the DataBuffer class. 494 * 495 * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT, 496 * and TYPE_INT. 497 * @param dataType the data type for storing samples 498 * @param w the width in pixels of the image data 499 * @param h the height in pixels of the image data 500 * @param bands the number of bands 501 * @param bitsPerBand the number of bits per band 502 * @param location the upper-left corner of the {@code Raster} 503 * @return a WritableRaster object with the specified data type, 504 * width, height, number of bands, and bits per band. 505 * @throws RasterFormatException if {@code w} or {@code h} 506 * is less than or equal to zero, or computing either 507 * {@code location.x + w} or 508 * {@code location.y + h} results in integer 509 * overflow 510 * @throws IllegalArgumentException if the product of 511 * {@code bitsPerBand} and {@code bands} is 512 * greater than the number of bits held by 513 * {@code dataType} 514 * @throws IllegalArgumentException if {@code bitsPerBand} or 515 * {@code bands} is not greater than zero 516 * @throws IllegalArgumentException if {@code dataType} is not 517 * one of the supported data types, which are 518 * {@code DataBuffer.TYPE_BYTE}, 519 * {@code DataBuffer.TYPE_USHORT} 520 * or {@code DataBuffer.TYPE_INT} 521 */ 522 public static WritableRaster createPackedRaster(int dataType, 523 int w, int h, 524 int bands, 525 int bitsPerBand, 526 Point location) { 527 DataBuffer d; 528 529 if (bands <= 0) { 530 throw new IllegalArgumentException("Number of bands ("+bands+ 531 ") must be greater than 0"); 532 } 533 534 if (bitsPerBand <= 0) { 535 throw new IllegalArgumentException("Bits per band ("+bitsPerBand+ 536 ") must be greater than 0"); 537 } 538 539 if (bands != 1) { 540 int[] masks = new int[bands]; 579 case DataBuffer.TYPE_INT: 580 d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h); 581 break; 582 583 default: 584 throw new IllegalArgumentException("Unsupported data type " + 585 dataType); 586 } 587 588 return createPackedRaster(d, w, h, bitsPerBand, location); 589 } 590 } 591 592 /** 593 * Creates a Raster based on a PixelInterleavedSampleModel with the 594 * specified DataBuffer, width, height, scanline stride, pixel 595 * stride, and band offsets. The number of bands is inferred from 596 * bandOffsets.length. The upper left corner of the Raster 597 * is given by the location argument. If location is null, (0, 0) 598 * will be used. 599 * <p> Note that interleaved {@code DataBuffer.TYPE_INT} 600 * Rasters are not supported. To create a 1-band Raster of type 601 * {@code DataBuffer.TYPE_INT}, use 602 * Raster.createPackedRaster(). 603 * @param dataBuffer the {@code DataBuffer} that contains the 604 * image data 605 * @param w the width in pixels of the image data 606 * @param h the height in pixels of the image data 607 * @param scanlineStride the line stride of the image data 608 * @param pixelStride the pixel stride of the image data 609 * @param bandOffsets the offsets of all bands 610 * @param location the upper-left corner of the {@code Raster} 611 * @return a WritableRaster object with the specified 612 * {@code DataBuffer}, width, height, scanline stride, 613 * pixel stride and band offsets. 614 * @throws RasterFormatException if {@code w} or {@code h} 615 * is less than or equal to zero, or computing either 616 * {@code location.x + w} or 617 * {@code location.y + h} results in integer 618 * overflow 619 * @throws IllegalArgumentException if {@code dataType} is not 620 * one of the supported data types, which are 621 * {@code DataBuffer.TYPE_BYTE}, 622 * {@code DataBuffer.TYPE_USHORT} 623 * @throws RasterFormatException if {@code dataBuffer} has more 624 * than one bank. 625 * @throws NullPointerException if {@code dataBuffer} is null 626 */ 627 public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, 628 int w, int h, 629 int scanlineStride, 630 int pixelStride, 631 int bandOffsets[], 632 Point location) { 633 if (dataBuffer == null) { 634 throw new NullPointerException("DataBuffer cannot be null"); 635 } 636 if (location == null) { 637 location = new Point(0, 0); 638 } 639 int dataType = dataBuffer.getDataType(); 640 641 PixelInterleavedSampleModel csm = 642 new PixelInterleavedSampleModel(dataType, w, h, 643 pixelStride, 644 scanlineStride, 645 bandOffsets); 646 switch(dataType) { 647 case DataBuffer.TYPE_BYTE: 648 return new ByteInterleavedRaster(csm, dataBuffer, location); 649 650 case DataBuffer.TYPE_USHORT: 651 return new ShortInterleavedRaster(csm, dataBuffer, location); 652 653 default: 654 throw new IllegalArgumentException("Unsupported data type " + 655 dataType); 656 } 657 } 658 659 /** 660 * Creates a Raster based on a BandedSampleModel with the 661 * specified DataBuffer, width, height, scanline stride, bank 662 * indices, and band offsets. The number of bands is inferred 663 * from bankIndices.length and bandOffsets.length, which must be 664 * the same. The upper left corner of the Raster is given by the 665 * location argument. If location is null, (0, 0) will be used. 666 * @param dataBuffer the {@code DataBuffer} that contains the 667 * image data 668 * @param w the width in pixels of the image data 669 * @param h the height in pixels of the image data 670 * @param scanlineStride the line stride of the image data 671 * @param bankIndices the bank indices for each band 672 * @param bandOffsets the offsets of all bands 673 * @param location the upper-left corner of the {@code Raster} 674 * @return a WritableRaster object with the specified 675 * {@code DataBuffer}, width, height, scanline stride, 676 * bank indices and band offsets. 677 * @throws RasterFormatException if {@code w} or {@code h} 678 * is less than or equal to zero, or computing either 679 * {@code location.x + w} or 680 * {@code location.y + h} results in integer 681 * overflow 682 * @throws IllegalArgumentException if {@code dataType} is not 683 * one of the supported data types, which are 684 * {@code DataBuffer.TYPE_BYTE}, 685 * {@code DataBuffer.TYPE_USHORT} 686 * or {@code DataBuffer.TYPE_INT} 687 * @throws NullPointerException if {@code dataBuffer} is null 688 */ 689 public static WritableRaster createBandedRaster(DataBuffer dataBuffer, 690 int w, int h, 691 int scanlineStride, 692 int bankIndices[], 693 int bandOffsets[], 694 Point location) { 695 if (dataBuffer == null) { 696 throw new NullPointerException("DataBuffer cannot be null"); 697 } 698 if (location == null) { 699 location = new Point(0,0); 700 } 701 int dataType = dataBuffer.getDataType(); 702 703 int bands = bankIndices.length; 704 if (bandOffsets.length != bands) { 705 throw new IllegalArgumentException( 706 "bankIndices.length != bandOffsets.length"); 707 } 716 return new ByteBandedRaster(bsm, dataBuffer, location); 717 718 case DataBuffer.TYPE_USHORT: 719 return new ShortBandedRaster(bsm, dataBuffer, location); 720 721 case DataBuffer.TYPE_INT: 722 return new SunWritableRaster(bsm, dataBuffer, location); 723 724 default: 725 throw new IllegalArgumentException("Unsupported data type " + 726 dataType); 727 } 728 } 729 730 /** 731 * Creates a Raster based on a SinglePixelPackedSampleModel with 732 * the specified DataBuffer, width, height, scanline stride, and 733 * band masks. The number of bands is inferred from bandMasks.length. 734 * The upper left corner of the Raster is given by 735 * the location argument. If location is null, (0, 0) will be used. 736 * @param dataBuffer the {@code DataBuffer} that contains the 737 * image data 738 * @param w the width in pixels of the image data 739 * @param h the height in pixels of the image data 740 * @param scanlineStride the line stride of the image data 741 * @param bandMasks an array containing an entry for each band 742 * @param location the upper-left corner of the {@code Raster} 743 * @return a WritableRaster object with the specified 744 * {@code DataBuffer}, width, height, scanline stride, 745 * and band masks. 746 * @throws RasterFormatException if {@code w} or {@code h} 747 * is less than or equal to zero, or computing either 748 * {@code location.x + w} or 749 * {@code location.y + h} results in integer 750 * overflow 751 * @throws IllegalArgumentException if {@code dataType} is not 752 * one of the supported data types, which are 753 * {@code DataBuffer.TYPE_BYTE}, 754 * {@code DataBuffer.TYPE_USHORT} 755 * or {@code DataBuffer.TYPE_INT} 756 * @throws RasterFormatException if {@code dataBuffer} has more 757 * than one bank. 758 * @throws NullPointerException if {@code dataBuffer} is null 759 */ 760 public static WritableRaster createPackedRaster(DataBuffer dataBuffer, 761 int w, int h, 762 int scanlineStride, 763 int bandMasks[], 764 Point location) { 765 if (dataBuffer == null) { 766 throw new NullPointerException("DataBuffer cannot be null"); 767 } 768 if (location == null) { 769 location = new Point(0,0); 770 } 771 int dataType = dataBuffer.getDataType(); 772 773 SinglePixelPackedSampleModel sppsm = 774 new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride, 775 bandMasks); 776 777 switch(dataType) { 778 case DataBuffer.TYPE_BYTE: 779 return new ByteInterleavedRaster(sppsm, dataBuffer, location); 780 781 case DataBuffer.TYPE_USHORT: 782 return new ShortInterleavedRaster(sppsm, dataBuffer, location); 783 784 case DataBuffer.TYPE_INT: 785 return new IntegerInterleavedRaster(sppsm, dataBuffer, location); 786 787 default: 788 throw new IllegalArgumentException("Unsupported data type " + 789 dataType); 790 } 791 } 792 793 /** 794 * Creates a Raster based on a MultiPixelPackedSampleModel with the 795 * specified DataBuffer, width, height, and bits per pixel. The upper 796 * left corner of the Raster is given by the location argument. If 797 * location is null, (0, 0) will be used. 798 * @param dataBuffer the {@code DataBuffer} that contains the 799 * image data 800 * @param w the width in pixels of the image data 801 * @param h the height in pixels of the image data 802 * @param bitsPerPixel the number of bits for each pixel 803 * @param location the upper-left corner of the {@code Raster} 804 * @return a WritableRaster object with the specified 805 * {@code DataBuffer}, width, height, and 806 * bits per pixel. 807 * @throws RasterFormatException if {@code w} or {@code h} 808 * is less than or equal to zero, or computing either 809 * {@code location.x + w} or 810 * {@code location.y + h} results in integer 811 * overflow 812 * @throws IllegalArgumentException if {@code dataType} is not 813 * one of the supported data types, which are 814 * {@code DataBuffer.TYPE_BYTE}, 815 * {@code DataBuffer.TYPE_USHORT} 816 * or {@code DataBuffer.TYPE_INT} 817 * @throws RasterFormatException if {@code dataBuffer} has more 818 * than one bank. 819 * @throws NullPointerException if {@code dataBuffer} is null 820 */ 821 public static WritableRaster createPackedRaster(DataBuffer dataBuffer, 822 int w, int h, 823 int bitsPerPixel, 824 Point location) { 825 if (dataBuffer == null) { 826 throw new NullPointerException("DataBuffer cannot be null"); 827 } 828 if (location == null) { 829 location = new Point(0,0); 830 } 831 int dataType = dataBuffer.getDataType(); 832 833 if (dataType != DataBuffer.TYPE_BYTE && 834 dataType != DataBuffer.TYPE_USHORT && 835 dataType != DataBuffer.TYPE_INT) { 836 throw new IllegalArgumentException("Unsupported data type " + 837 dataType); 838 } 839 842 RasterFormatException("DataBuffer for packed Rasters"+ 843 " must only have 1 bank."); 844 } 845 846 MultiPixelPackedSampleModel mppsm = 847 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel); 848 849 if (dataType == DataBuffer.TYPE_BYTE && 850 (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) { 851 return new BytePackedRaster(mppsm, dataBuffer, location); 852 } else { 853 return new SunWritableRaster(mppsm, dataBuffer, location); 854 } 855 } 856 857 858 /** 859 * Creates a Raster with the specified SampleModel and DataBuffer. 860 * The upper left corner of the Raster is given by the location argument. 861 * If location is null, (0, 0) will be used. 862 * @param sm the specified {@code SampleModel} 863 * @param db the specified {@code DataBuffer} 864 * @param location the upper-left corner of the {@code Raster} 865 * @return a {@code Raster} with the specified 866 * {@code SampleModel}, {@code DataBuffer}, and 867 * location. 868 * @throws RasterFormatException if computing either 869 * {@code location.x + sm.getWidth()} or 870 * {@code location.y + sm.getHeight()} results in integer 871 * overflow 872 * @throws RasterFormatException if {@code db} has more 873 * than one bank and {@code sm} is a 874 * PixelInterleavedSampleModel, SinglePixelPackedSampleModel, 875 * or MultiPixelPackedSampleModel. 876 * @throws NullPointerException if either SampleModel or DataBuffer is 877 * null 878 */ 879 public static Raster createRaster(SampleModel sm, 880 DataBuffer db, 881 Point location) { 882 if ((sm == null) || (db == null)) { 883 throw new NullPointerException("SampleModel and DataBuffer cannot be null"); 884 } 885 886 if (location == null) { 887 location = new Point(0,0); 888 } 889 int dataType = sm.getDataType(); 890 891 if (sm instanceof PixelInterleavedSampleModel) { 892 switch(dataType) { 893 case DataBuffer.TYPE_BYTE: 905 return new ShortInterleavedRaster(sm, db, location); 906 907 case DataBuffer.TYPE_INT: 908 return new IntegerInterleavedRaster(sm, db, location); 909 } 910 } else if (sm instanceof MultiPixelPackedSampleModel && 911 dataType == DataBuffer.TYPE_BYTE && 912 sm.getSampleSize(0) < 8) { 913 return new BytePackedRaster(sm, db, location); 914 } 915 916 // we couldn't do anything special - do the generic thing 917 918 return new Raster(sm,db,location); 919 } 920 921 /** 922 * Creates a WritableRaster with the specified SampleModel. 923 * The upper left corner of the Raster is given by the location argument. 924 * If location is null, (0, 0) will be used. 925 * @param sm the specified {@code SampleModel} 926 * @param location the upper-left corner of the 927 * {@code WritableRaster} 928 * @return a {@code WritableRaster} with the specified 929 * {@code SampleModel} and location. 930 * @throws RasterFormatException if computing either 931 * {@code location.x + sm.getWidth()} or 932 * {@code location.y + sm.getHeight()} results in integer 933 * overflow 934 */ 935 public static WritableRaster createWritableRaster(SampleModel sm, 936 Point location) { 937 if (location == null) { 938 location = new Point(0,0); 939 } 940 941 return createWritableRaster(sm, sm.createDataBuffer(), location); 942 } 943 944 /** 945 * Creates a WritableRaster with the specified SampleModel and DataBuffer. 946 * The upper left corner of the Raster is given by the location argument. 947 * If location is null, (0, 0) will be used. 948 * @param sm the specified {@code SampleModel} 949 * @param db the specified {@code DataBuffer} 950 * @param location the upper-left corner of the 951 * {@code WritableRaster} 952 * @return a {@code WritableRaster} with the specified 953 * {@code SampleModel}, {@code DataBuffer}, and 954 * location. 955 * @throws RasterFormatException if computing either 956 * {@code location.x + sm.getWidth()} or 957 * {@code location.y + sm.getHeight()} results in integer 958 * overflow 959 * @throws RasterFormatException if {@code db} has more 960 * than one bank and {@code sm} is a 961 * PixelInterleavedSampleModel, SinglePixelPackedSampleModel, 962 * or MultiPixelPackedSampleModel. 963 * @throws NullPointerException if either SampleModel or DataBuffer is null 964 */ 965 public static WritableRaster createWritableRaster(SampleModel sm, 966 DataBuffer db, 967 Point location) { 968 if ((sm == null) || (db == null)) { 969 throw new NullPointerException("SampleModel and DataBuffer cannot be null"); 970 } 971 if (location == null) { 972 location = new Point(0,0); 973 } 974 975 int dataType = sm.getDataType(); 976 977 if (sm instanceof PixelInterleavedSampleModel) { 978 switch(dataType) { 979 case DataBuffer.TYPE_BYTE: 980 return new ByteInterleavedRaster(sm, db, location); 995 } 996 } else if (sm instanceof MultiPixelPackedSampleModel && 997 dataType == DataBuffer.TYPE_BYTE && 998 sm.getSampleSize(0) < 8) { 999 return new BytePackedRaster(sm, db, location); 1000 } 1001 1002 // we couldn't do anything special - do the generic thing 1003 1004 return new SunWritableRaster(sm,db,location); 1005 } 1006 1007 /** 1008 * Constructs a Raster with the given SampleModel. The Raster's 1009 * upper left corner is origin and it is the same size as the 1010 * SampleModel. A DataBuffer large enough to describe the 1011 * Raster is automatically created. 1012 * @param sampleModel The SampleModel that specifies the layout 1013 * @param origin The Point that specified the origin 1014 * @throws RasterFormatException if computing either 1015 * {@code origin.x + sampleModel.getWidth()} or 1016 * {@code origin.y + sampleModel.getHeight()} results in 1017 * integer overflow 1018 * @throws NullPointerException either {@code sampleModel} or 1019 * {@code origin} is null 1020 */ 1021 protected Raster(SampleModel sampleModel, 1022 Point origin) { 1023 this(sampleModel, 1024 sampleModel.createDataBuffer(), 1025 new Rectangle(origin.x, 1026 origin.y, 1027 sampleModel.getWidth(), 1028 sampleModel.getHeight()), 1029 origin, 1030 null); 1031 } 1032 1033 /** 1034 * Constructs a Raster with the given SampleModel and DataBuffer. 1035 * The Raster's upper left corner is origin and it is the same size 1036 * as the SampleModel. The DataBuffer is not initialized and must 1037 * be compatible with SampleModel. 1038 * @param sampleModel The SampleModel that specifies the layout 1039 * @param dataBuffer The DataBuffer that contains the image data 1040 * @param origin The Point that specifies the origin 1041 * @throws RasterFormatException if computing either 1042 * {@code origin.x + sampleModel.getWidth()} or 1043 * {@code origin.y + sampleModel.getHeight()} results in 1044 * integer overflow 1045 * @throws NullPointerException either {@code sampleModel} or 1046 * {@code origin} is null 1047 */ 1048 protected Raster(SampleModel sampleModel, 1049 DataBuffer dataBuffer, 1050 Point origin) { 1051 this(sampleModel, 1052 dataBuffer, 1053 new Rectangle(origin.x, 1054 origin.y, 1055 sampleModel.getWidth(), 1056 sampleModel.getHeight()), 1057 origin, 1058 null); 1059 } 1060 1061 /** 1062 * Constructs a Raster with the given SampleModel, DataBuffer, and 1063 * parent. aRegion specifies the bounding rectangle of the new 1064 * Raster. When translated into the base Raster's coordinate 1065 * system, aRegion must be contained by the base Raster. 1066 * (The base Raster is the Raster's ancestor which has no parent.) 1067 * sampleModelTranslate specifies the sampleModelTranslateX and 1068 * sampleModelTranslateY values of the new Raster. 1069 * 1070 * Note that this constructor should generally be called by other 1071 * constructors or create methods, it should not be used directly. 1072 * @param sampleModel The SampleModel that specifies the layout 1073 * @param dataBuffer The DataBuffer that contains the image data 1074 * @param aRegion The Rectangle that specifies the image area 1075 * @param sampleModelTranslate The Point that specifies the translation 1076 * from SampleModel to Raster coordinates 1077 * @param parent The parent (if any) of this raster 1078 * @throws NullPointerException if any of {@code sampleModel}, 1079 * {@code dataBuffer}, {@code aRegion} or 1080 * {@code sampleModelTranslate} is null 1081 * @throws RasterFormatException if {@code aRegion} has width 1082 * or height less than or equal to zero, or computing either 1083 * {@code aRegion.x + aRegion.width} or 1084 * {@code aRegion.y + aRegion.height} results in integer 1085 * overflow 1086 */ 1087 protected Raster(SampleModel sampleModel, 1088 DataBuffer dataBuffer, 1089 Rectangle aRegion, 1090 Point sampleModelTranslate, 1091 Raster parent) { 1092 1093 if ((sampleModel == null) || (dataBuffer == null) || 1094 (aRegion == null) || (sampleModelTranslate == null)) { 1095 throw new NullPointerException("SampleModel, dataBuffer, aRegion and " + 1096 "sampleModelTranslate cannot be null"); 1097 } 1098 this.sampleModel = sampleModel; 1099 this.dataBuffer = dataBuffer; 1100 minX = aRegion.x; 1101 minY = aRegion.y; 1102 width = aRegion.width; 1103 height = aRegion.height; 1104 if (width <= 0 || height <= 0) { 1108 if ((minX + width) < minX) { 1109 throw new RasterFormatException( 1110 "overflow condition for X coordinates of Raster"); 1111 } 1112 if ((minY + height) < minY) { 1113 throw new RasterFormatException( 1114 "overflow condition for Y coordinates of Raster"); 1115 } 1116 1117 sampleModelTranslateX = sampleModelTranslate.x; 1118 sampleModelTranslateY = sampleModelTranslate.y; 1119 1120 numBands = sampleModel.getNumBands(); 1121 numDataElements = sampleModel.getNumDataElements(); 1122 this.parent = parent; 1123 } 1124 1125 1126 /** 1127 * Returns the parent Raster (if any) of this Raster or null. 1128 * @return the parent Raster or {@code null}. 1129 */ 1130 public Raster getParent() { 1131 return parent; 1132 } 1133 1134 /** 1135 * Returns the X translation from the coordinate system of the 1136 * SampleModel to that of the Raster. To convert a pixel's X 1137 * coordinate from the Raster coordinate system to the SampleModel 1138 * coordinate system, this value must be subtracted. 1139 * @return the X translation from the coordinate space of the 1140 * Raster's SampleModel to that of the Raster. 1141 */ 1142 public final int getSampleModelTranslateX() { 1143 return sampleModelTranslateX; 1144 } 1145 1146 /** 1147 * Returns the Y translation from the coordinate system of the 1148 * SampleModel to that of the Raster. To convert a pixel's Y 1149 * coordinate from the Raster coordinate system to the SampleModel 1150 * coordinate system, this value must be subtracted. 1151 * @return the Y translation from the coordinate space of the 1152 * Raster's SampleModel to that of the Raster. 1153 */ 1154 public final int getSampleModelTranslateY() { 1155 return sampleModelTranslateY; 1156 } 1157 1158 /** 1159 * Create a compatible WritableRaster the same size as this Raster with 1160 * the same SampleModel and a new initialized DataBuffer. 1161 * @return a compatible {@code WritableRaster} with the same sample 1162 * model and a new data buffer. 1163 */ 1164 public WritableRaster createCompatibleWritableRaster() { 1165 return new SunWritableRaster(sampleModel, new Point(0,0)); 1166 } 1167 1168 /** 1169 * Create a compatible WritableRaster with the specified size, a new 1170 * SampleModel, and a new initialized DataBuffer. 1171 * @param w the specified width of the new {@code WritableRaster} 1172 * @param h the specified height of the new {@code WritableRaster} 1173 * @return a compatible {@code WritableRaster} with the specified 1174 * size and a new sample model and data buffer. 1175 * @exception RasterFormatException if the width or height is less than 1176 * or equal to zero. 1177 */ 1178 public WritableRaster createCompatibleWritableRaster(int w, int h) { 1179 if (w <= 0 || h <=0) { 1180 throw new RasterFormatException("negative " + 1181 ((w <= 0) ? "width" : "height")); 1182 } 1183 1184 SampleModel sm = sampleModel.createCompatibleSampleModel(w,h); 1185 1186 return new SunWritableRaster(sm, new Point(0,0)); 1187 } 1188 1189 /** 1190 * Create a compatible WritableRaster with location (minX, minY) 1191 * and size (width, height) specified by rect, a 1192 * new SampleModel, and a new initialized DataBuffer. 1193 * @param rect a {@code Rectangle} that specifies the size and 1194 * location of the {@code WritableRaster} 1195 * @return a compatible {@code WritableRaster} with the specified 1196 * size and location and a new sample model and data buffer. 1197 * @throws RasterFormatException if {@code rect} has width 1198 * or height less than or equal to zero, or computing either 1199 * {@code rect.x + rect.width} or 1200 * {@code rect.y + rect.height} results in integer 1201 * overflow 1202 * @throws NullPointerException if {@code rect} is null 1203 */ 1204 public WritableRaster createCompatibleWritableRaster(Rectangle rect) { 1205 if (rect == null) { 1206 throw new NullPointerException("Rect cannot be null"); 1207 } 1208 return createCompatibleWritableRaster(rect.x, rect.y, 1209 rect.width, rect.height); 1210 } 1211 1212 /** 1213 * Create a compatible WritableRaster with the specified 1214 * location (minX, minY) and size (width, height), a 1215 * new SampleModel, and a new initialized DataBuffer. 1216 * @param x the X coordinate of the upper-left corner of 1217 * the {@code WritableRaster} 1218 * @param y the Y coordinate of the upper-left corner of 1219 * the {@code WritableRaster} 1220 * @param w the specified width of the {@code WritableRaster} 1221 * @param h the specified height of the {@code WritableRaster} 1222 * @return a compatible {@code WritableRaster} with the specified 1223 * size and location and a new sample model and data buffer. 1224 * @throws RasterFormatException if {@code w} or {@code h} 1225 * is less than or equal to zero, or computing either 1226 * {@code x + w} or 1227 * {@code y + h} results in integer 1228 * overflow 1229 */ 1230 public WritableRaster createCompatibleWritableRaster(int x, int y, 1231 int w, int h) { 1232 WritableRaster ret = createCompatibleWritableRaster(w, h); 1233 return ret.createWritableChild(0,0,w,h,x,y,null); 1234 } 1235 1236 /** 1237 * Create a Raster with the same size, SampleModel and DataBuffer 1238 * as this one, but with a different location. The new Raster 1239 * will possess a reference to the current Raster, accessible 1240 * through its getParent() method. 1241 * 1242 * @param childMinX the X coordinate of the upper-left 1243 * corner of the new {@code Raster} 1244 * @param childMinY the Y coordinate of the upper-left 1245 * corner of the new {@code Raster} 1246 * @return a new {@code Raster} with the same size, SampleModel, 1247 * and DataBuffer as this {@code Raster}, but with the 1248 * specified location. 1249 * @throws RasterFormatException if computing either 1250 * {@code childMinX + this.getWidth()} or 1251 * {@code childMinY + this.getHeight()} results in integer 1252 * overflow 1253 */ 1254 public Raster createTranslatedChild(int childMinX, int childMinY) { 1255 return createChild(minX,minY,width,height, 1256 childMinX,childMinY,null); 1257 } 1258 1259 /** 1260 * Returns a new Raster which shares all or part of this Raster's 1261 * DataBuffer. The new Raster will possess a reference to the 1262 * current Raster, accessible through its getParent() method. 1263 * 1264 * <p> The parentX, parentY, width and height parameters 1265 * form a Rectangle in this Raster's coordinate space, 1266 * indicating the area of pixels to be shared. An error will 1267 * be thrown if this Rectangle is not contained with the bounds 1268 * of the current Raster. 1269 * 1270 * <p> The new Raster may additionally be translated to a 1271 * different coordinate system for the plane than that used by the current 1280 * of the bandList parameter. If bandList is null, it is taken to 1281 * include all of the bands of the current Raster in their current 1282 * order. 1283 * 1284 * <p> To create a new Raster that contains a subregion of the current 1285 * Raster, but shares its coordinate system and bands, 1286 * this method should be called with childMinX equal to parentX, 1287 * childMinY equal to parentY, and bandList equal to null. 1288 * 1289 * @param parentX The X coordinate of the upper-left corner 1290 * in this Raster's coordinates 1291 * @param parentY The Y coordinate of the upper-left corner 1292 * in this Raster's coordinates 1293 * @param width Width of the region starting at (parentX, parentY) 1294 * @param height Height of the region starting at (parentX, parentY). 1295 * @param childMinX The X coordinate of the upper-left corner 1296 * of the returned Raster 1297 * @param childMinY The Y coordinate of the upper-left corner 1298 * of the returned Raster 1299 * @param bandList Array of band indices, or null to use all bands 1300 * @return a new {@code Raster}. 1301 * @exception RasterFormatException if the specified subregion is outside 1302 * of the raster bounds. 1303 * @throws RasterFormatException if {@code width} or 1304 * {@code height} 1305 * is less than or equal to zero, or computing any of 1306 * {@code parentX + width}, {@code parentY + height}, 1307 * {@code childMinX + width}, or 1308 * {@code childMinY + height} results in integer 1309 * overflow 1310 */ 1311 public Raster createChild(int parentX, int parentY, 1312 int width, int height, 1313 int childMinX, int childMinY, 1314 int bandList[]) { 1315 if (parentX < this.minX) { 1316 throw new RasterFormatException("parentX lies outside raster"); 1317 } 1318 if (parentY < this.minY) { 1319 throw new RasterFormatException("parentY lies outside raster"); 1320 } 1321 if ((parentX + width < parentX) || 1322 (parentX + width > this.width + this.minX)) { 1323 throw new RasterFormatException("(parentX + width) is outside raster"); 1324 } 1325 if ((parentY + height < parentY) || 1326 (parentY + height > this.height + this.minY)) { 1327 throw new RasterFormatException("(parentY + height) is outside raster"); 1328 } 1334 // and height represent a "virtual" view of the pixel data, so 1335 // they may be different than those of the SampleModel. 1336 if (bandList == null) { 1337 subSampleModel = sampleModel; 1338 } else { 1339 subSampleModel = sampleModel.createSubsetSampleModel(bandList); 1340 } 1341 1342 int deltaX = childMinX - parentX; 1343 int deltaY = childMinY - parentY; 1344 1345 return new Raster(subSampleModel, getDataBuffer(), 1346 new Rectangle(childMinX, childMinY, width, height), 1347 new Point(sampleModelTranslateX + deltaX, 1348 sampleModelTranslateY + deltaY), this); 1349 } 1350 1351 /** 1352 * Returns the bounding Rectangle of this Raster. This function returns 1353 * the same information as getMinX/MinY/Width/Height. 1354 * @return the bounding box of this {@code Raster}. 1355 */ 1356 public Rectangle getBounds() { 1357 return new Rectangle(minX, minY, width, height); 1358 } 1359 1360 /** Returns the minimum valid X coordinate of the Raster. 1361 * @return the minimum x coordinate of this {@code Raster}. 1362 */ 1363 public final int getMinX() { 1364 return minX; 1365 } 1366 1367 /** Returns the minimum valid Y coordinate of the Raster. 1368 * @return the minimum y coordinate of this {@code Raster}. 1369 */ 1370 public final int getMinY() { 1371 return minY; 1372 } 1373 1374 /** Returns the width in pixels of the Raster. 1375 * @return the width of this {@code Raster}. 1376 */ 1377 public final int getWidth() { 1378 return width; 1379 } 1380 1381 /** Returns the height in pixels of the Raster. 1382 * @return the height of this {@code Raster}. 1383 */ 1384 public final int getHeight() { 1385 return height; 1386 } 1387 1388 /** Returns the number of bands (samples per pixel) in this Raster. 1389 * @return the number of bands of this {@code Raster}. 1390 */ 1391 public final int getNumBands() { 1392 return numBands; 1393 } 1394 1395 /** 1396 * Returns the number of data elements needed to transfer one pixel 1397 * via the getDataElements and setDataElements methods. When pixels 1398 * are transferred via these methods, they may be transferred in a 1399 * packed or unpacked format, depending on the implementation of the 1400 * underlying SampleModel. Using these methods, pixels are transferred 1401 * as an array of getNumDataElements() elements of a primitive type given 1402 * by getTransferType(). The TransferType may or may not be the same 1403 * as the storage data type of the DataBuffer. 1404 * @return the number of data elements. 1405 */ 1406 public final int getNumDataElements() { 1407 return sampleModel.getNumDataElements(); 1408 } 1409 1410 /** 1411 * Returns the TransferType used to transfer pixels via the 1412 * getDataElements and setDataElements methods. When pixels 1413 * are transferred via these methods, they may be transferred in a 1414 * packed or unpacked format, depending on the implementation of the 1415 * underlying SampleModel. Using these methods, pixels are transferred 1416 * as an array of getNumDataElements() elements of a primitive type given 1417 * by getTransferType(). The TransferType may or may not be the same 1418 * as the storage data type of the DataBuffer. The TransferType will 1419 * be one of the types defined in DataBuffer. 1420 * @return this transfer type. 1421 */ 1422 public final int getTransferType() { 1423 return sampleModel.getTransferType(); 1424 } 1425 1426 /** Returns the DataBuffer associated with this Raster. 1427 * @return the {@code DataBuffer} of this {@code Raster}. 1428 */ 1429 public DataBuffer getDataBuffer() { 1430 return dataBuffer; 1431 } 1432 1433 /** Returns the SampleModel that describes the layout of the image data. 1434 * @return the {@code SampleModel} of this {@code Raster}. 1435 */ 1436 public SampleModel getSampleModel() { 1437 return sampleModel; 1438 } 1439 1440 /** 1441 * Returns data for a single pixel in a primitive array of type 1442 * TransferType. For image data supported by the Java 2D(tm) API, 1443 * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 1444 * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 1445 * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format, 1446 * thus increasing efficiency for data transfers. 1447 * An ArrayIndexOutOfBoundsException may be thrown 1448 * if the coordinates are not in bounds. However, explicit bounds 1449 * checking is not guaranteed. 1450 * A ClassCastException will be thrown if the input object is non null 1451 * and references anything other than an array of TransferType. 1452 * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer) 1453 * @param x The X coordinate of the pixel location 1454 * @param y The Y coordinate of the pixel location |