1 /* 2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt.image; 27 import java.awt.image.Raster; 28 import java.awt.image.WritableRaster; 29 import java.awt.image.RasterFormatException; 30 import java.awt.image.SampleModel; 31 import java.awt.image.ComponentSampleModel; 32 import java.awt.image.PixelInterleavedSampleModel; 33 import java.awt.image.SinglePixelPackedSampleModel; 34 import java.awt.image.DataBuffer; 35 import java.awt.image.DataBufferByte; 36 import java.awt.Rectangle; 37 import java.awt.Point; 38 39 /** 40 * This class defines a Raster with pixels consisting of one or more 41 * 8-bit data elements stored in close proximity to each other in a 42 * single byte array. 43 * <p> 44 * The bit precision per data element is that of the data type (that 45 * is, the bit precision for this Raster is 8). There is only one 46 * pixel stride and one scanline stride for all bands. This type of 47 * Raster can be used with a ComponentColorModel if there are multiple 48 * bands, or an IndexColorModel if there is only one band. 49 * 50 */ 51 public class ByteInterleavedRaster extends ByteComponentRaster { 52 53 /** True if the data offsets range from 0 to (pixelStride - 1) in order. */ 54 boolean inOrder; 55 56 /** 57 * The DataBuffer offset, minus sampleModelTranslateX*pixelStride, 58 * minus sampleModelTranslateY*scanlineStride, used to calculate 59 * pixel offsets. 60 */ 61 int dbOffset; 62 int dbOffsetPacked; 63 64 /** True if a SinglePixelPackedSampleModel is being used. */ 65 boolean packed = false; 66 67 /** If packed == true, the SampleModel's bit masks. */ 68 int[] bitMasks; 69 70 /** If packed == true, the SampleModel's bit offsets. */ 71 int[] bitOffsets; 72 73 /** A cached copy of minX + width for use in bounds checks. */ 74 private int maxX; 75 76 /** A cached copy of minY + height for use in bounds checks. */ 77 private int maxY; 78 79 /** 80 * Constructs a ByteInterleavedRaster with the given SampleModel. 81 * The Raster's upper left corner is origin and it is the same 82 * size as the SampleModel. A DataBuffer large enough to describe the 83 * Raster is automatically created. SampleModel must be of type 84 * SinglePixelPackedSampleModel or InterleavedSampleModel. 85 * @param sampleModel The SampleModel that specifies the layout. 86 * @param origin The Point that specified the origin. 87 */ 88 public ByteInterleavedRaster(SampleModel sampleModel, Point origin) { 89 this(sampleModel, 90 sampleModel.createDataBuffer(), 91 new Rectangle(origin.x, 92 origin.y, 93 sampleModel.getWidth(), 94 sampleModel.getHeight()), 95 origin, 96 null); 97 } 98 99 /** 100 * Constructs a ByteInterleavedRaster with the given SampleModel 101 * and DataBuffer. The Raster's upper left corner is origin and 102 * it is the same size as the SampleModel. The DataBuffer is not 103 * initialized and must be a DataBufferByte compatible with SampleModel. 104 * SampleModel must be of type SinglePixelPackedSampleModel 105 * or InterleavedSampleModel. 106 * @param sampleModel The SampleModel that specifies the layout. 107 * @param dataBuffer The DataBufferShort that contains the image data. 108 * @param origin The Point that specifies the origin. 109 */ 110 public ByteInterleavedRaster(SampleModel sampleModel, 111 DataBuffer dataBuffer, 112 Point origin) { 113 this(sampleModel, 114 dataBuffer, 115 new Rectangle(origin.x, 116 origin.y, 117 sampleModel.getWidth(), 118 sampleModel.getHeight()), 119 origin, 120 null); 121 } 122 123 /*** Analyzes a ComponentSampleModel to determine if it can function 124 * as a PixelInterleavedSampleModel. In order to do so, it must use 125 * only bank 0 of its DataBuffer, and the data offsets must span a range 126 * of less than pixelStride. 127 * 128 * <p> These properties are trivially true for a 1-banded SampleModel. 129 */ 130 private boolean isInterleaved(ComponentSampleModel sm) { 131 // Analyze ComponentSampleModel to determine if it has the 132 // properties of a PixelInterleavedSampleModel 133 134 int numBands = sampleModel.getNumBands(); 135 if (numBands == 1) { 136 return true; 137 } 138 139 // Determine banks used 140 int[] bankIndices = sm.getBankIndices(); 141 for (int i = 0; i < numBands; i++) { 142 if (bankIndices[i] != 0) { 143 return false; 144 } 145 } 146 147 // Determine range of band offsets 148 int[] bandOffsets = sm.getBandOffsets(); 149 int minOffset = bandOffsets[0]; 150 int maxOffset = minOffset; 151 for (int i = 1; i < numBands; i++) { 152 int offset = bandOffsets[i]; 153 if (offset < minOffset) { 154 minOffset = offset; 155 } 156 if (offset > maxOffset) { 157 maxOffset = offset; 158 } 159 } 160 if (maxOffset - minOffset >= sm.getPixelStride()) { 161 return false; 162 } 163 164 return true; 165 } 166 167 /** 168 * Constructs a ByteInterleavedRaster with the given SampleModel, 169 * DataBuffer, and parent. DataBuffer must be a DataBufferByte and 170 * SampleModel must be of type SinglePixelPackedSampleModel 171 * or InterleavedSampleModel. 172 * When translated into the base Raster's 173 * coordinate system, aRegion must be contained by the base Raster. 174 * Origin is the coordinate in the new Raster's coordinate system of 175 * the origin of the base Raster. (The base Raster is the Raster's 176 * ancestor which has no parent.) 177 * 178 * Note that this constructor should generally be called by other 179 * constructors or create methods, it should not be used directly. 180 * @param sampleModel The SampleModel that specifies the layout. 181 * @param dataBuffer The DataBufferShort that contains the image data. 182 * @param aRegion The Rectangle that specifies the image area. 183 * @param origin The Point that specifies the origin. 184 * @param parent The parent (if any) of this raster. 185 */ 186 public ByteInterleavedRaster(SampleModel sampleModel, 187 DataBuffer dataBuffer, 188 Rectangle aRegion, 189 Point origin, 190 ByteInterleavedRaster parent) { 191 super(sampleModel, dataBuffer, aRegion, origin, parent); 192 this.maxX = minX + width; 193 this.maxY = minY + height; 194 195 if (!(dataBuffer instanceof DataBufferByte)) { 196 throw new RasterFormatException("ByteInterleavedRasters must have " + 197 "byte DataBuffers"); 198 } 199 200 DataBufferByte dbb = (DataBufferByte)dataBuffer; 201 this.data = stealData(dbb, 0); 202 203 int xOffset = aRegion.x - origin.x; 204 int yOffset = aRegion.y - origin.y; 205 if (sampleModel instanceof PixelInterleavedSampleModel || 206 (sampleModel instanceof ComponentSampleModel && 207 isInterleaved((ComponentSampleModel)sampleModel))) { 208 ComponentSampleModel csm = (ComponentSampleModel)sampleModel; 209 this.scanlineStride = csm.getScanlineStride(); 210 this.pixelStride = csm.getPixelStride(); 211 this.dataOffsets = csm.getBandOffsets(); 212 for (int i = 0; i < getNumDataElements(); i++) { 213 dataOffsets[i] += xOffset*pixelStride+yOffset*scanlineStride; 214 } 215 } else if (sampleModel instanceof SinglePixelPackedSampleModel) { 216 SinglePixelPackedSampleModel sppsm = 217 (SinglePixelPackedSampleModel)sampleModel; 218 this.packed = true; 219 this.bitMasks = sppsm.getBitMasks(); 220 this.bitOffsets = sppsm.getBitOffsets(); 221 this.scanlineStride = sppsm.getScanlineStride(); 222 this.pixelStride = 1; 223 this.dataOffsets = new int[1]; 224 this.dataOffsets[0] = dbb.getOffset(); 225 dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride; 226 } else { 227 throw new RasterFormatException("ByteInterleavedRasters must " + 228 "have PixelInterleavedSampleModel, SinglePixelPackedSampleModel"+ 229 " or interleaved ComponentSampleModel. Sample model is " + 230 sampleModel); 231 } 232 this.bandOffset = this.dataOffsets[0]; 233 234 this.dbOffsetPacked = dataBuffer.getOffset() - 235 sampleModelTranslateY*scanlineStride - 236 sampleModelTranslateX*pixelStride; 237 this.dbOffset = dbOffsetPacked - 238 (xOffset*pixelStride+yOffset*scanlineStride); 239 240 // Set inOrder to true if the data elements are in order and 241 // have no gaps between them 242 this.inOrder = false; 243 if (numDataElements == pixelStride) { 244 inOrder = true; 245 for (int i = 1; i < numDataElements; i++) { 246 if (dataOffsets[i] - dataOffsets[0] != i) { 247 inOrder = false; 248 break; 249 } 250 } 251 } 252 253 verify(); 254 } 255 256 /** 257 * Returns a copy of the data offsets array. For each band the data offset 258 * is the index into the band's data array, of the first sample of the 259 * band. 260 */ 261 public int[] getDataOffsets() { 262 return dataOffsets.clone(); 263 } 264 265 /** 266 * Returns the data offset for the specified band. The data offset 267 * is the index into the data array 268 * in which the first sample of the first scanline is stored. 269 * @param band The band whose offset is returned. 270 */ 271 public int getDataOffset(int band) { 272 return dataOffsets[band]; 273 } 274 275 /** 276 * Returns the scanline stride -- the number of data array elements between 277 * a given sample and the sample in the same column of the next row in the 278 * same band. 279 */ 280 public int getScanlineStride() { 281 return scanlineStride; 282 } 283 284 /** 285 * Returns pixel stride -- the number of data array elements between two 286 * samples for the same band on the same scanline. 287 */ 288 public int getPixelStride() { 289 return pixelStride; 290 } 291 292 /** 293 * Returns a reference to the data array. 294 */ 295 public byte[] getDataStorage() { 296 return data; 297 } 298 299 /** 300 * Returns the data elements for all bands at the specified 301 * location. 302 * An ArrayIndexOutOfBounds exception will be thrown at runtime 303 * if the pixel coordinate is out of bounds. 304 * A ClassCastException will be thrown if the input object is non null 305 * and references anything other than an array of transferType. 306 * @param x The X coordinate of the pixel location. 307 * @param y The Y coordinate of the pixel location. 308 * @param outData An object reference to an array of type defined by 309 * getTransferType() and length getNumDataElements(). 310 * If null an array of appropriate type and size will be 311 * allocated. 312 * @return An object reference to an array of type defined by 313 * getTransferType() with the request pixel data. 314 */ 315 public Object getDataElements(int x, int y, Object obj) { 316 if ((x < this.minX) || (y < this.minY) || 317 (x >= this.maxX) || (y >= this.maxY)) { 318 throw new ArrayIndexOutOfBoundsException 319 ("Coordinate out of bounds!"); 320 } 321 byte outData[]; 322 if (obj == null) { 323 outData = new byte[numDataElements]; 324 } else { 325 outData = (byte[])obj; 326 } 327 int off = (y-minY)*scanlineStride + 328 (x-minX)*pixelStride; 329 330 for (int band = 0; band < numDataElements; band++) { 331 outData[band] = data[dataOffsets[band] + off]; 332 } 333 334 return outData; 335 } 336 337 /** 338 * Returns an array of data elements from the specified rectangular 339 * region. 340 * An ArrayIndexOutOfBounds exception will be thrown at runtime 341 * if the pixel coordinates are out of bounds. 342 * A ClassCastException will be thrown if the input object is non null 343 * and references anything other than an array of transferType. 344 * <pre> 345 * byte[] bandData = (byte[])raster.getDataElements(x, y, w, h, null); 346 * int numDataElements = raster.getNumDataElements(); 347 * byte[] pixel = new byte[numDataElements]; 348 * // To find a data element at location (x2, y2) 349 * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, 350 * pixel, 0, numDataElements); 351 * </pre> 352 * @param x The X coordinate of the upper left pixel location. 353 * @param y The Y coordinate of the upper left pixel location. 354 * @param width Width of the pixel rectangle. 355 * @param height Height of the pixel rectangle. 356 * @param outData An object reference to an array of type defined by 357 * getTransferType() and length w*h*getNumDataElements(). 358 * If null an array of appropriate type and size will be 359 * allocated. 360 * @return An object reference to an array of type defined by 361 * getTransferType() with the request pixel data. 362 */ 363 public Object getDataElements(int x, int y, int w, int h, Object obj) { 364 return getByteData(x, y, w, h, (byte[])obj); 365 } 366 367 /** 368 * Returns a byte array of data elements from the specified rectangular 369 * region for the specified band. 370 * An ArrayIndexOutOfBounds exception will be thrown at runtime 371 * if the pixel coordinates are out of bounds. 372 * <pre> 373 * byte[] bandData = raster.getByteData(x, y, w, h, null); 374 * // To find the data element at location (x2, y2) 375 * byte bandElement = bandData[((y2-y)*w + (x2-x))]; 376 * </pre> 377 * @param x The X coordinate of the upper left pixel location. 378 * @param y The Y coordinate of the upper left pixel location. 379 * @param width Width of the pixel rectangle. 380 * @param height Height of the pixel rectangle. 381 * @param band The band to return. 382 * @param outData If non-null, data elements for all bands 383 * at the specified location are returned in this array. 384 * @return Data array with data elements for all bands. 385 */ 386 public byte[] getByteData(int x, int y, int w, int h, 387 int band, byte[] outData) { 388 // Bounds check for 'band' will be performed automatically 389 if ((x < this.minX) || (y < this.minY) || 390 (x + w > this.maxX) || (y + h > this.maxY)) { 391 throw new ArrayIndexOutOfBoundsException 392 ("Coordinate out of bounds!"); 393 } 394 if (outData == null) { 395 outData = new byte[w*h]; 396 } 397 int yoff = (y-minY)*scanlineStride + 398 (x-minX)*pixelStride + dataOffsets[band]; 399 int xoff; 400 int off = 0; 401 int xstart; 402 int ystart; 403 404 if (pixelStride == 1) { 405 if (scanlineStride == w) { 406 System.arraycopy(data, yoff, outData, 0, w*h); 407 } else { 408 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 409 System.arraycopy(data, yoff, outData, off, w); 410 off += w; 411 } 412 } 413 } else { 414 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 415 xoff = yoff; 416 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 417 outData[off++] = data[xoff]; 418 } 419 } 420 } 421 422 return outData; 423 } 424 425 /** 426 * Returns a byte array of data elements from the specified rectangular 427 * region. 428 * An ArrayIndexOutOfBounds exception will be thrown at runtime 429 * if the pixel coordinates are out of bounds. 430 * <pre> 431 * byte[] bandData = raster.getByteData(x, y, w, h, null); 432 * int numDataElements = raster.getnumDataElements(); 433 * byte[] pixel = new byte[numDataElements]; 434 * // To find a data element at location (x2, y2) 435 * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, 436 * pixel, 0, numDataElements); 437 * </pre> 438 * @param x The X coordinate of the upper left pixel location. 439 * @param y The Y coordinate of the upper left pixel location. 440 * @param width Width of the pixel rectangle. 441 * @param height Height of the pixel rectangle. 442 * @param outData If non-null, data elements for all bands 443 * at the specified location are returned in this array. 444 * @return Data array with data elements for all bands. 445 */ 446 public byte[] getByteData(int x, int y, int w, int h, byte[] outData) { 447 if ((x < this.minX) || (y < this.minY) || 448 (x + w > this.maxX) || (y + h > this.maxY)) { 449 throw new ArrayIndexOutOfBoundsException 450 ("Coordinate out of bounds!"); 451 } 452 if (outData == null) { 453 outData = new byte[numDataElements*w*h]; 454 } 455 int yoff = (y-minY)*scanlineStride + 456 (x-minX)*pixelStride; 457 int xoff; 458 int off = 0; 459 int xstart; 460 int ystart; 461 462 if (inOrder) { 463 yoff += dataOffsets[0]; 464 int rowBytes = w*pixelStride; 465 if (scanlineStride == rowBytes) { 466 System.arraycopy(data, yoff, outData, off, rowBytes*h); 467 } else { 468 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 469 System.arraycopy(data, yoff, outData, off, rowBytes); 470 off += rowBytes; 471 } 472 } 473 } else if (numDataElements == 1) { 474 yoff += dataOffsets[0]; 475 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 476 xoff = yoff; 477 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 478 outData[off++] = data[xoff]; 479 } 480 } 481 } else if (numDataElements == 2) { 482 yoff += dataOffsets[0]; 483 int d1 = dataOffsets[1] - dataOffsets[0]; 484 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 485 xoff = yoff; 486 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 487 outData[off++] = data[xoff]; 488 outData[off++] = data[xoff + d1]; 489 } 490 } 491 } else if (numDataElements == 3) { 492 yoff += dataOffsets[0]; 493 int d1 = dataOffsets[1] - dataOffsets[0]; 494 int d2 = dataOffsets[2] - dataOffsets[0]; 495 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 496 xoff = yoff; 497 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 498 outData[off++] = data[xoff]; 499 outData[off++] = data[xoff + d1]; 500 outData[off++] = data[xoff + d2]; 501 } 502 } 503 } else if (numDataElements == 4) { 504 yoff += dataOffsets[0]; 505 int d1 = dataOffsets[1] - dataOffsets[0]; 506 int d2 = dataOffsets[2] - dataOffsets[0]; 507 int d3 = dataOffsets[3] - dataOffsets[0]; 508 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 509 xoff = yoff; 510 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 511 outData[off++] = data[xoff]; 512 outData[off++] = data[xoff + d1]; 513 outData[off++] = data[xoff + d2]; 514 outData[off++] = data[xoff + d3]; 515 } 516 } 517 } else { 518 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 519 xoff = yoff; 520 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 521 for (int c = 0; c < numDataElements; c++) { 522 outData[off++] = data[dataOffsets[c] + xoff]; 523 } 524 } 525 } 526 } 527 528 return outData; 529 } 530 531 /** 532 * Stores the data elements for all bands at the specified location. 533 * An ArrayIndexOutOfBounds exception will be thrown at runtime 534 * if the pixel coordinate is out of bounds. 535 * A ClassCastException will be thrown if the input object is non null 536 * and references anything other than an array of transferType. 537 * @param x The X coordinate of the pixel location. 538 * @param y The Y coordinate of the pixel location. 539 * @param inData An object reference to an array of type defined by 540 * getTransferType() and length getNumDataElements() 541 * containing the pixel data to place at x,y. 542 */ 543 public void setDataElements(int x, int y, Object obj) { 544 if ((x < this.minX) || (y < this.minY) || 545 (x >= this.maxX) || (y >= this.maxY)) { 546 throw new ArrayIndexOutOfBoundsException 547 ("Coordinate out of bounds!"); 548 } 549 byte inData[] = (byte[])obj; 550 int off = (y-minY)*scanlineStride + 551 (x-minX)*pixelStride; 552 553 for (int i = 0; i < numDataElements; i++) { 554 data[dataOffsets[i] + off] = inData[i]; 555 } 556 557 markDirty(); 558 } 559 560 /** 561 * Stores the Raster data at the specified location. 562 * An ArrayIndexOutOfBounds exception will be thrown at runtime 563 * if the pixel coordinates are out of bounds. 564 * @param x The X coordinate of the pixel location. 565 * @param y The Y coordinate of the pixel location. 566 * @param inRaster Raster of data to place at x,y location. 567 */ 568 public void setDataElements(int x, int y, Raster inRaster) { 569 int srcOffX = inRaster.getMinX(); 570 int srcOffY = inRaster.getMinY(); 571 int dstOffX = x + srcOffX; 572 int dstOffY = y + srcOffY; 573 int width = inRaster.getWidth(); 574 int height = inRaster.getHeight(); 575 if ((dstOffX < this.minX) || (dstOffY < this.minY) || 576 (dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) { 577 throw new ArrayIndexOutOfBoundsException 578 ("Coordinate out of bounds!"); 579 } 580 581 setDataElements(dstOffX, dstOffY, srcOffX, srcOffY, 582 width, height, inRaster); 583 } 584 585 /** 586 * Stores the Raster data at the specified location. 587 * @param dstX The absolute X coordinate of the destination pixel 588 * that will receive a copy of the upper-left pixel of the 589 * inRaster 590 * @param dstY The absolute Y coordinate of the destination pixel 591 * that will receive a copy of the upper-left pixel of the 592 * inRaster 593 * @param srcX The absolute X coordinate of the upper-left source 594 * pixel that will be copied into this Raster 595 * @param srcY The absolute Y coordinate of the upper-left source 596 * pixel that will be copied into this Raster 597 * @param width The number of pixels to store horizontally 598 * @param height The number of pixels to store vertically 599 * @param inRaster Raster of data to place at x,y location. 600 */ 601 private void setDataElements(int dstX, int dstY, 602 int srcX, int srcY, 603 int width, int height, 604 Raster inRaster) { 605 // Assume bounds checking has been performed previously 606 if (width <= 0 || height <= 0) { 607 return; 608 } 609 610 // Write inRaster (minX, minY) to (dstX, dstY) 611 612 int srcOffX = inRaster.getMinX(); 613 int srcOffY = inRaster.getMinY(); 614 Object tdata = null; 615 616 if (inRaster instanceof ByteInterleavedRaster) { 617 ByteInterleavedRaster bct = (ByteInterleavedRaster) inRaster; 618 byte[] bdata = bct.getDataStorage(); 619 // copy whole scanlines 620 if (inOrder && bct.inOrder && pixelStride == bct.pixelStride) { 621 int toff = bct.getDataOffset(0); 622 int tss = bct.getScanlineStride(); 623 int tps = bct.getPixelStride(); 624 625 int srcOffset = toff + 626 (srcY - srcOffY) * tss + 627 (srcX - srcOffX) * tps; 628 int dstOffset = dataOffsets[0] + 629 (dstY - minY) * scanlineStride + 630 (dstX - minX) * pixelStride; 631 632 int nbytes = width*pixelStride; 633 for (int tmpY=0; tmpY < height; tmpY++) { 634 System.arraycopy(bdata, srcOffset, 635 data, dstOffset, nbytes); 636 srcOffset += tss; 637 dstOffset += scanlineStride; 638 } 639 markDirty(); 640 return; 641 } 642 } 643 644 for (int startY=0; startY < height; startY++) { 645 // Grab one scanline at a time 646 tdata = inRaster.getDataElements(srcOffX, srcOffY+startY, 647 width, 1, tdata); 648 setDataElements(dstX, dstY + startY, width, 1, tdata); 649 } 650 } 651 652 /** 653 * Stores an array of data elements into the specified rectangular 654 * region. 655 * An ArrayIndexOutOfBounds exception will be thrown at runtime 656 * if the pixel coordinates are out of bounds. 657 * A ClassCastException will be thrown if the input object is non null 658 * and references anything other than an array of transferType. 659 * The data elements in the 660 * data array are assumed to be packed. That is, a data element 661 * for the nth band at location (x2, y2) would be found at: 662 * <pre> 663 * inData[((y2-y)*w + (x2-x))*numDataElements + n] 664 * </pre> 665 * @param x The X coordinate of the upper left pixel location. 666 * @param y The Y coordinate of the upper left pixel location. 667 * @param w Width of the pixel rectangle. 668 * @param h Height of the pixel rectangle. 669 * @param inData An object reference to an array of type defined by 670 * getTransferType() and length w*h*getNumDataElements() 671 * containing the pixel data to place between x,y and 672 * x+h, y+h. 673 */ 674 public void setDataElements(int x, int y, int w, int h, Object obj) { 675 putByteData(x, y, w, h, (byte[])obj); 676 } 677 678 /** 679 * Stores a byte array of data elements into the specified rectangular 680 * region for the specified band. 681 * An ArrayIndexOutOfBounds exception will be thrown at runtime 682 * if the pixel coordinates are out of bounds. 683 * The data elements in the 684 * data array are assumed to be packed. That is, a data element 685 * at location (x2, y2) would be found at: 686 * <pre> 687 * inData[((y2-y)*w + (x2-x)) + n] 688 * </pre> 689 * @param x The X coordinate of the upper left pixel location. 690 * @param y The Y coordinate of the upper left pixel location. 691 * @param w Width of the pixel rectangle. 692 * @param h Height of the pixel rectangle. 693 * @param band The band to set. 694 * @param inData The data elements to be stored. 695 */ 696 public void putByteData(int x, int y, int w, int h, 697 int band, byte[] inData) { 698 // Bounds check for 'band' will be performed automatically 699 if ((x < this.minX) || (y < this.minY) || 700 (x + w > this.maxX) || (y + h > this.maxY)) { 701 throw new ArrayIndexOutOfBoundsException 702 ("Coordinate out of bounds!"); 703 } 704 int yoff = (y-minY)*scanlineStride + 705 (x-minX)*pixelStride + dataOffsets[band]; 706 int xoff; 707 int off = 0; 708 int xstart; 709 int ystart; 710 711 if (pixelStride == 1) { 712 if (scanlineStride == w) { 713 System.arraycopy(inData, 0, data, yoff, w*h); 714 } 715 else { 716 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 717 System.arraycopy(inData, off, data, yoff, w); 718 off += w; 719 } 720 } 721 } 722 else { 723 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 724 xoff = yoff; 725 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 726 data[xoff] = inData[off++]; 727 } 728 } 729 } 730 731 markDirty(); 732 } 733 734 /** 735 * Stores a byte array of data elements into the specified rectangular 736 * region. 737 * An ArrayIndexOutOfBounds exception will be thrown at runtime 738 * if the pixel coordinates are out of bounds. 739 * The data elements in the 740 * data array are assumed to be packed. That is, a data element 741 * for the nth band at location (x2, y2) would be found at: 742 * <pre> 743 * inData[((y2-y)*w + (x2-x))*numDataElements + n] 744 * </pre> 745 * @param x The X coordinate of the upper left pixel location. 746 * @param y The Y coordinate of the upper left pixel location. 747 * @param w Width of the pixel rectangle. 748 * @param h Height of the pixel rectangle. 749 * @param inData The data elements to be stored. 750 */ 751 public void putByteData(int x, int y, int w, int h, byte[] inData) { 752 if ((x < this.minX) || (y < this.minY) || 753 (x + w > this.maxX) || (y + h > this.maxY)) { 754 throw new ArrayIndexOutOfBoundsException 755 ("Coordinate out of bounds!"); 756 } 757 int yoff = (y-minY)*scanlineStride + 758 (x-minX)*pixelStride; 759 760 int xoff; 761 int off = 0; 762 int xstart; 763 int ystart; 764 765 if (inOrder) { 766 yoff += dataOffsets[0]; 767 int rowBytes = w*pixelStride; 768 if (rowBytes == scanlineStride) { 769 System.arraycopy(inData, 0, data, yoff, rowBytes*h); 770 } else { 771 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 772 System.arraycopy(inData, off, data, yoff, rowBytes); 773 off += rowBytes; 774 } 775 } 776 } else if (numDataElements == 1) { 777 yoff += dataOffsets[0]; 778 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 779 xoff = yoff; 780 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 781 data[xoff] = inData[off++]; 782 } 783 } 784 } else if (numDataElements == 2) { 785 yoff += dataOffsets[0]; 786 int d1 = dataOffsets[1] - dataOffsets[0]; 787 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 788 xoff = yoff; 789 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 790 data[xoff] = inData[off++]; 791 data[xoff + d1] = inData[off++]; 792 } 793 } 794 } else if (numDataElements == 3) { 795 yoff += dataOffsets[0]; 796 int d1 = dataOffsets[1] - dataOffsets[0]; 797 int d2 = dataOffsets[2] - dataOffsets[0]; 798 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 799 xoff = yoff; 800 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 801 data[xoff] = inData[off++]; 802 data[xoff + d1] = inData[off++]; 803 data[xoff + d2] = inData[off++]; 804 } 805 } 806 } else if (numDataElements == 4) { 807 yoff += dataOffsets[0]; 808 int d1 = dataOffsets[1] - dataOffsets[0]; 809 int d2 = dataOffsets[2] - dataOffsets[0]; 810 int d3 = dataOffsets[3] - dataOffsets[0]; 811 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 812 xoff = yoff; 813 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 814 data[xoff] = inData[off++]; 815 data[xoff + d1] = inData[off++]; 816 data[xoff + d2] = inData[off++]; 817 data[xoff + d3] = inData[off++]; 818 } 819 } 820 } else { 821 for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { 822 xoff = yoff; 823 for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { 824 for (int c = 0; c < numDataElements; c++) { 825 data[dataOffsets[c] + xoff] = inData[off++]; 826 } 827 } 828 } 829 } 830 831 markDirty(); 832 } 833 834 public int getSample(int x, int y, int b) { 835 if ((x < this.minX) || (y < this.minY) || 836 (x >= this.maxX) || (y >= this.maxY)) { 837 throw new ArrayIndexOutOfBoundsException 838 ("Coordinate out of bounds!"); 839 } 840 if (packed) { 841 int offset = y*scanlineStride + x + dbOffsetPacked; 842 byte sample = data[offset]; 843 return (sample & bitMasks[b]) >>> bitOffsets[b]; 844 } else { 845 int offset = y*scanlineStride + x*pixelStride + dbOffset; 846 return data[offset + dataOffsets[b]] & 0xff; 847 } 848 } 849 850 public void setSample(int x, int y, int b, int s) { 851 if ((x < this.minX) || (y < this.minY) || 852 (x >= this.maxX) || (y >= this.maxY)) { 853 throw new ArrayIndexOutOfBoundsException 854 ("Coordinate out of bounds!"); 855 } 856 if (packed) { 857 int offset = y*scanlineStride + x + dbOffsetPacked; 858 int bitMask = bitMasks[b]; 859 860 byte value = data[offset]; 861 value &= ~bitMask; 862 value |= (s << bitOffsets[b]) & bitMask; 863 data[offset] = value; 864 } else { 865 int offset = y*scanlineStride + x*pixelStride + dbOffset; 866 data[offset + dataOffsets[b]] = (byte)s; 867 } 868 869 markDirty(); 870 } 871 872 public int[] getSamples(int x, int y, int w, int h, int b, 873 int[] iArray) { 874 if ((x < this.minX) || (y < this.minY) || 875 (x + w > this.maxX) || (y + h > this.maxY)) { 876 throw new ArrayIndexOutOfBoundsException 877 ("Coordinate out of bounds!"); 878 } 879 int samples[]; 880 if (iArray != null) { 881 samples = iArray; 882 } else { 883 samples = new int [w*h]; 884 } 885 886 int lineOffset = y*scanlineStride + x*pixelStride; 887 int dstOffset = 0; 888 889 if (packed) { 890 lineOffset += dbOffsetPacked; 891 int bitMask = bitMasks[b]; 892 int bitOffset = bitOffsets[b]; 893 894 for (int j = 0; j < h; j++) { 895 int sampleOffset = lineOffset; 896 for (int i = 0; i < w; i++) { 897 int value = data[sampleOffset++]; 898 samples[dstOffset++] = ((value & bitMask) >>> bitOffset); 899 } 900 lineOffset += scanlineStride; 901 } 902 } else { 903 lineOffset += dbOffset + dataOffsets[b]; 904 for (int j = 0; j < h; j++) { 905 int sampleOffset = lineOffset; 906 for (int i = 0; i < w; i++) { 907 samples[dstOffset++] = data[sampleOffset] & 0xff; 908 sampleOffset += pixelStride; 909 } 910 lineOffset += scanlineStride; 911 } 912 } 913 914 return samples; 915 } 916 917 public void setSamples(int x, int y, int w, int h, int b, int iArray[]) { 918 if ((x < this.minX) || (y < this.minY) || 919 (x + w > this.maxX) || (y + h > this.maxY)) { 920 throw new ArrayIndexOutOfBoundsException 921 ("Coordinate out of bounds!"); 922 } 923 int lineOffset = y*scanlineStride + x*pixelStride; 924 int srcOffset = 0; 925 926 if (packed) { 927 lineOffset += dbOffsetPacked; 928 int bitMask = bitMasks[b]; 929 930 for (int j = 0; j < h; j++) { 931 int sampleOffset = lineOffset; 932 for (int i = 0; i < w; i++) { 933 byte value = data[sampleOffset]; 934 value &= ~bitMask; 935 int sample = iArray[srcOffset++]; 936 value |= (sample << bitOffsets[b]) & bitMask; 937 data[sampleOffset++] = value; 938 } 939 lineOffset += scanlineStride; 940 } 941 } else { 942 lineOffset += dbOffset + dataOffsets[b]; 943 for (int i = 0; i < h; i++) { 944 int sampleOffset = lineOffset; 945 for (int j = 0; j < w; j++) { 946 data[sampleOffset] = (byte)iArray[srcOffset++]; 947 sampleOffset += pixelStride; 948 } 949 lineOffset += scanlineStride; 950 } 951 } 952 953 markDirty(); 954 } 955 956 public int[] getPixels(int x, int y, int w, int h, int[] iArray) { 957 if ((x < this.minX) || (y < this.minY) || 958 (x + w > this.maxX) || (y + h > this.maxY)) { 959 throw new ArrayIndexOutOfBoundsException 960 ("Coordinate out of bounds!"); 961 } 962 int pixels[]; 963 if (iArray != null) { 964 pixels = iArray; 965 } else { 966 pixels = new int[w*h*numBands]; 967 } 968 969 int lineOffset = y*scanlineStride + x*pixelStride; 970 int dstOffset = 0; 971 972 if (packed) { 973 lineOffset += dbOffsetPacked; 974 for (int j = 0; j < h; j++) { 975 for (int i = 0; i < w; i++) { 976 int value = data[lineOffset + i]; 977 for (int k = 0; k < numBands; k++) { 978 pixels[dstOffset++] = 979 (value & bitMasks[k]) >>> bitOffsets[k]; 980 } 981 } 982 lineOffset += scanlineStride; 983 } 984 } else { 985 lineOffset += dbOffset; 986 int d0 = dataOffsets[0]; 987 988 if (numBands == 1) { 989 for (int j = 0; j < h; j++) { 990 int pixelOffset = lineOffset + d0; 991 for (int i = 0; i < w; i++) { 992 pixels[dstOffset++] = data[pixelOffset] & 0xff; 993 pixelOffset += pixelStride; 994 } 995 lineOffset += scanlineStride; 996 } 997 } else if (numBands == 2) { 998 int d1 = dataOffsets[1] - d0; 999 for (int j = 0; j < h; j++) { 1000 int pixelOffset = lineOffset + d0; 1001 for (int i = 0; i < w; i++) { 1002 pixels[dstOffset++] = data[pixelOffset] & 0xff; 1003 pixels[dstOffset++] = data[pixelOffset + d1] & 0xff; 1004 pixelOffset += pixelStride; 1005 } 1006 lineOffset += scanlineStride; 1007 } 1008 } else if (numBands == 3) { 1009 int d1 = dataOffsets[1] - d0; 1010 int d2 = dataOffsets[2] - d0; 1011 for (int j = 0; j < h; j++) { 1012 int pixelOffset = lineOffset + d0; 1013 for (int i = 0; i < w; i++) { 1014 pixels[dstOffset++] = data[pixelOffset] & 0xff; 1015 pixels[dstOffset++] = data[pixelOffset + d1] & 0xff; 1016 pixels[dstOffset++] = data[pixelOffset + d2] & 0xff; 1017 pixelOffset += pixelStride; 1018 } 1019 lineOffset += scanlineStride; 1020 } 1021 } else if (numBands == 4) { 1022 int d1 = dataOffsets[1] - d0; 1023 int d2 = dataOffsets[2] - d0; 1024 int d3 = dataOffsets[3] - d0; 1025 for (int j = 0; j < h; j++) { 1026 int pixelOffset = lineOffset + d0; 1027 for (int i = 0; i < w; i++) { 1028 pixels[dstOffset++] = data[pixelOffset] & 0xff; 1029 pixels[dstOffset++] = data[pixelOffset + d1] & 0xff; 1030 pixels[dstOffset++] = data[pixelOffset + d2] & 0xff; 1031 pixels[dstOffset++] = data[pixelOffset + d3] & 0xff; 1032 pixelOffset += pixelStride; 1033 } 1034 lineOffset += scanlineStride; 1035 } 1036 } else { 1037 for (int j = 0; j < h; j++) { 1038 int pixelOffset = lineOffset; 1039 for (int i = 0; i < w; i++) { 1040 for (int k = 0; k < numBands; k++) { 1041 pixels[dstOffset++] = 1042 data[pixelOffset + dataOffsets[k]] & 0xff; 1043 } 1044 pixelOffset += pixelStride; 1045 } 1046 lineOffset += scanlineStride; 1047 } 1048 } 1049 } 1050 1051 return pixels; 1052 } 1053 1054 public void setPixels(int x, int y, int w, int h, int[] iArray) { 1055 if ((x < this.minX) || (y < this.minY) || 1056 (x + w > this.maxX) || (y + h > this.maxY)) { 1057 throw new ArrayIndexOutOfBoundsException 1058 ("Coordinate out of bounds!"); 1059 } 1060 int lineOffset = y*scanlineStride + x*pixelStride; 1061 int srcOffset = 0; 1062 1063 if (packed) { 1064 lineOffset += dbOffsetPacked; 1065 for (int j = 0; j < h; j++) { 1066 for (int i = 0; i < w; i++) { 1067 int value = 0; 1068 for (int k = 0; k < numBands; k++) { 1069 int srcValue = iArray[srcOffset++]; 1070 value |= ((srcValue << bitOffsets[k]) 1071 & bitMasks[k]); 1072 } 1073 data[lineOffset + i] = (byte)value; 1074 } 1075 lineOffset += scanlineStride; 1076 } 1077 } else { 1078 lineOffset += dbOffset; 1079 int d0 = dataOffsets[0]; 1080 1081 if (numBands == 1) { 1082 for (int j = 0; j < h; j++) { 1083 int pixelOffset = lineOffset + d0; 1084 for (int i = 0; i < w; i++) { 1085 data[pixelOffset] = (byte)iArray[srcOffset++]; 1086 pixelOffset += pixelStride; 1087 } 1088 lineOffset += scanlineStride; 1089 } 1090 } else if (numBands == 2) { 1091 int d1 = dataOffsets[1] - d0; 1092 for (int j = 0; j < h; j++) { 1093 int pixelOffset = lineOffset + d0; 1094 for (int i = 0; i < w; i++) { 1095 data[pixelOffset] = (byte)iArray[srcOffset++]; 1096 data[pixelOffset + d1] = (byte)iArray[srcOffset++]; 1097 pixelOffset += pixelStride; 1098 } 1099 lineOffset += scanlineStride; 1100 } 1101 } else if (numBands == 3) { 1102 int d1 = dataOffsets[1] - d0; 1103 int d2 = dataOffsets[2] - d0; 1104 for (int j = 0; j < h; j++) { 1105 int pixelOffset = lineOffset + d0; 1106 for (int i = 0; i < w; i++) { 1107 data[pixelOffset] = (byte)iArray[srcOffset++]; 1108 data[pixelOffset + d1] = (byte)iArray[srcOffset++]; 1109 data[pixelOffset + d2] = (byte)iArray[srcOffset++]; 1110 pixelOffset += pixelStride; 1111 } 1112 lineOffset += scanlineStride; 1113 } 1114 } else if (numBands == 4) { 1115 int d1 = dataOffsets[1] - d0; 1116 int d2 = dataOffsets[2] - d0; 1117 int d3 = dataOffsets[3] - d0; 1118 for (int j = 0; j < h; j++) { 1119 int pixelOffset = lineOffset + d0; 1120 for (int i = 0; i < w; i++) { 1121 data[pixelOffset] = (byte)iArray[srcOffset++]; 1122 data[pixelOffset + d1] = (byte)iArray[srcOffset++]; 1123 data[pixelOffset + d2] = (byte)iArray[srcOffset++]; 1124 data[pixelOffset + d3] = (byte)iArray[srcOffset++]; 1125 pixelOffset += pixelStride; 1126 } 1127 lineOffset += scanlineStride; 1128 } 1129 } else { 1130 for (int j = 0; j < h; j++) { 1131 int pixelOffset = lineOffset; 1132 for (int i = 0; i < w; i++) { 1133 for (int k = 0; k < numBands; k++) { 1134 data[pixelOffset + dataOffsets[k]] = 1135 (byte)iArray[srcOffset++]; 1136 } 1137 pixelOffset += pixelStride; 1138 } 1139 lineOffset += scanlineStride; 1140 } 1141 } 1142 } 1143 1144 markDirty(); 1145 } 1146 1147 public void setRect(int dx, int dy, Raster srcRaster) { 1148 if (!(srcRaster instanceof ByteInterleavedRaster)) { 1149 super.setRect(dx, dy, srcRaster); 1150 return; 1151 } 1152 1153 int width = srcRaster.getWidth(); 1154 int height = srcRaster.getHeight(); 1155 int srcOffX = srcRaster.getMinX(); 1156 int srcOffY = srcRaster.getMinY(); 1157 int dstOffX = dx+srcOffX; 1158 int dstOffY = dy+srcOffY; 1159 1160 // Clip to this raster 1161 if (dstOffX < this.minX) { 1162 int skipX = minX - dstOffX; 1163 width -= skipX; 1164 srcOffX += skipX; 1165 dstOffX = this.minX; 1166 } 1167 if (dstOffY < this.minY) { 1168 int skipY = this.minY - dstOffY; 1169 height -= skipY; 1170 srcOffY += skipY; 1171 dstOffY = this.minY; 1172 } 1173 if (dstOffX+width > this.maxX) { 1174 width = this.maxX - dstOffX; 1175 } 1176 if (dstOffY+height > this.maxY) { 1177 height = this.maxY - dstOffY; 1178 } 1179 1180 setDataElements(dstOffX, dstOffY, 1181 srcOffX, srcOffY, 1182 width, height, srcRaster); 1183 } 1184 1185 1186 /** 1187 * Creates a subraster given a region of the raster. The x and y 1188 * coordinates specify the horizontal and vertical offsets 1189 * from the upper-left corner of this raster to the upper-left corner 1190 * of the subraster. A subset of the bands of the parent Raster may 1191 * be specified. If this is null, then all the bands are present in the 1192 * subRaster. A translation to the subRaster may also be specified. 1193 * Note that the subraster will reference the same 1194 * DataBuffer as the parent raster, but using different offsets. 1195 * @param x X offset. 1196 * @param y Y offset. 1197 * @param width Width (in pixels) of the subraster. 1198 * @param height Height (in pixels) of the subraster. 1199 * @param x0 Translated X origin of the subraster. 1200 * @param y0 Translated Y origin of the subraster. 1201 * @param bandList Array of band indices. 1202 * @exception RasterFormatException 1203 * if the specified bounding box is outside of the parent raster. 1204 */ 1205 public Raster createChild(int x, int y, 1206 int width, int height, 1207 int x0, int y0, int[] bandList) { 1208 WritableRaster newRaster = createWritableChild(x, y, 1209 width, height, 1210 x0, y0, 1211 bandList); 1212 return (Raster) newRaster; 1213 } 1214 1215 /** 1216 * Creates a Writable subRaster given a region of the Raster. The x and y 1217 * coordinates specify the horizontal and vertical offsets 1218 * from the upper-left corner of this Raster to the upper-left corner 1219 * of the subRaster. A subset of the bands of the parent Raster may 1220 * be specified. If this is null, then all the bands are present in the 1221 * subRaster. A translation to the subRaster may also be specified. 1222 * Note that the subRaster will reference the same 1223 * DataBuffer as the parent Raster, but using different offsets. 1224 * @param x X offset. 1225 * @param y Y offset. 1226 * @param width Width (in pixels) of the subraster. 1227 * @param height Height (in pixels) of the subraster. 1228 * @param x0 Translated X origin of the subraster. 1229 * @param y0 Translated Y origin of the subraster. 1230 * @param bandList Array of band indices. 1231 * @exception RasterFormatException 1232 * if the specified bounding box is outside of the parent Raster. 1233 */ 1234 public WritableRaster createWritableChild(int x, int y, 1235 int width, int height, 1236 int x0, int y0, 1237 int[] bandList) { 1238 if (x < this.minX) { 1239 throw new RasterFormatException("x lies outside the raster"); 1240 } 1241 if (y < this.minY) { 1242 throw new RasterFormatException("y lies outside the raster"); 1243 } 1244 if ((x+width < x) || (x+width > this.minX + this.width)) { 1245 throw new RasterFormatException("(x + width) is outside of Raster"); 1246 } 1247 if ((y+height < y) || (y+height > this.minY + this.height)) { 1248 throw new RasterFormatException("(y + height) is outside of Raster"); 1249 } 1250 1251 SampleModel sm; 1252 1253 if (bandList != null) 1254 sm = sampleModel.createSubsetSampleModel(bandList); 1255 else 1256 sm = sampleModel; 1257 1258 int deltaX = x0 - x; 1259 int deltaY = y0 - y; 1260 1261 return new ByteInterleavedRaster(sm, 1262 dataBuffer, 1263 new Rectangle(x0, y0, width, height), 1264 new Point(sampleModelTranslateX+deltaX, 1265 sampleModelTranslateY+deltaY), 1266 this); 1267 } 1268 1269 /** 1270 * Creates a Raster with the same layout but using a different 1271 * width and height, and with new zeroed data arrays. 1272 */ 1273 public WritableRaster createCompatibleWritableRaster(int w, int h) { 1274 if (w <= 0 || h <=0) { 1275 throw new RasterFormatException("negative "+ 1276 ((w <= 0) ? "width" : "height")); 1277 } 1278 1279 SampleModel sm = sampleModel.createCompatibleSampleModel(w, h); 1280 1281 return new ByteInterleavedRaster(sm, new Point(0,0)); 1282 1283 } 1284 1285 /** 1286 * Creates a Raster with the same layout and the same 1287 * width and height, and with new zeroed data arrays. If 1288 * the Raster is a subRaster, this will call 1289 * createCompatibleRaster(width, height). 1290 */ 1291 public WritableRaster createCompatibleWritableRaster() { 1292 return createCompatibleWritableRaster(width,height); 1293 } 1294 1295 public String toString() { 1296 return new String ("ByteInterleavedRaster: width = "+width+" height = " 1297 + height 1298 +" #numDataElements "+numDataElements 1299 // +" xOff = "+xOffset+" yOff = "+yOffset 1300 +" dataOff[0] = "+dataOffsets[0]); 1301 } 1302 1303 // /** 1304 // * For debugging... prints a region of a one-band ByteInterleavedRaster 1305 // */ 1306 // public void print(int x, int y, int w, int h) { 1307 // // REMIND: Only works for 1 band! 1308 // System.out.println(this); 1309 // int offset = dataOffsets[0] + y*scanlineStride + x*pixelStride; 1310 // int off; 1311 // for (int yoff=0; yoff < h; yoff++, offset += scanlineStride) { 1312 // off = offset; 1313 // System.out.print("Line "+(y+yoff)+": "); 1314 // for (int xoff = 0; xoff < w; xoff++, off+= pixelStride) { 1315 // String s = Integer.toHexString(data[off]); 1316 // if (s.length() == 8) { 1317 // s = s.substring(6,8); 1318 // } 1319 // System.out.print(s+" "); 1320 // } 1321 // System.out.println(""); 1322 // } 1323 // } 1324 }