Raster.java 30.3 KB
Newer Older
1
/* Copyright (C) 2000, 2002, 2003, 2006,  Free Software Foundation
Tom Tromey committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.image;

40 41
import gnu.java.lang.CPStringBuilder;

Tom Tromey committed
42 43 44 45
import java.awt.Point;
import java.awt.Rectangle;

/**
46 47 48
 * A rectangular collection of pixels composed from a {@link DataBuffer} which
 * stores the pixel values, and a {@link SampleModel} which is used to retrieve
 * the pixel values.
49
 *
Tom Tromey committed
50 51 52 53
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
 */
public class Raster
{
54
  /** The sample model used to access the pixel values. */
Tom Tromey committed
55
  protected SampleModel sampleModel;
56

57
  /** The data buffer used to store the pixel values. */
Tom Tromey committed
58
  protected DataBuffer dataBuffer;
59

60
  /** The x-coordinate of the top left corner of the raster. */
Tom Tromey committed
61
  protected int minX;
62

63
  /** The y-coordinate of the top left corner of the raster. */
Tom Tromey committed
64
  protected int minY;
65

66
  /** The width of the raster. */
Tom Tromey committed
67
  protected int width;
68

69
  /** The height of the raster. */
Tom Tromey committed
70
  protected int height;
71

Tom Tromey committed
72
  protected int sampleModelTranslateX;
73

Tom Tromey committed
74
  protected int sampleModelTranslateY;
75

76
  /** The number of bands. */
Tom Tromey committed
77
  protected int numBands;
78

Tom Tromey committed
79
  protected int numDataElements;
80

81
  /** The raster's parent. */
Tom Tromey committed
82
  protected Raster parent;
83

84 85
  /**
   * Creates a new raster.
86
   *
87 88 89
   * @param sampleModel  the sample model.
   * @param origin  the origin.
   */
Tom Tromey committed
90 91 92 93
  protected Raster(SampleModel sampleModel, Point origin)
  {
    this(sampleModel, sampleModel.createDataBuffer(), origin);
  }
94

95 96
  /**
   * Creates a new raster.
97
   *
98 99 100 101
   * @param sampleModel  the sample model.
   * @param dataBuffer  the data buffer.
   * @param origin  the origin.
   */
Tom Tromey committed
102
  protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
103
                   Point origin)
Tom Tromey committed
104
  {
105 106
    this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
         sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
Tom Tromey committed
107 108
  }

109 110
  /**
   * Creates a new raster.
111
   *
112 113 114 115 116 117
   * @param sampleModel  the sample model.
   * @param dataBuffer  the data buffer.
   * @param aRegion  the raster's bounds.
   * @param sampleModelTranslate  the translation (<code>null</code> permitted).
   * @param parent  the raster's parent.
   */
Tom Tromey committed
118
  protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
119
      Rectangle aRegion, Point sampleModelTranslate, Raster parent)
Tom Tromey committed
120 121 122 123 124 125 126
  {
    this.sampleModel = sampleModel;
    this.dataBuffer = dataBuffer;
    this.minX = aRegion.x;
    this.minY = aRegion.y;
    this.width = aRegion.width;
    this.height = aRegion.height;
127

Tom Tromey committed
128 129 130 131 132 133 134 135 136 137 138 139
    // If sampleModelTranslate is null, use (0,0).  Methods such as
    // Raster.createRaster are specified to allow for a null argument.
    if (sampleModelTranslate != null)
    {
      this.sampleModelTranslateX = sampleModelTranslate.x;
      this.sampleModelTranslateY = sampleModelTranslate.y;
    }

    this.numBands = sampleModel.getNumBands();
    this.numDataElements = sampleModel.getNumDataElements();
    this.parent = parent;
  }
140

141 142
  /**
   * Creates an interleaved raster using the specified data type.
143
   *
144 145 146 147 148
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
   * @param location
149
   *
150 151
   * @return The new raster.
   */
Tom Tromey committed
152
  public static WritableRaster createInterleavedRaster(int dataType,
153
      int w, int h, int bands, Point location)
Tom Tromey committed
154 155 156
  {
    int[] bandOffsets = new int[bands];
    // TODO: Maybe not generate this every time.
157
    for (int b = 0; b < bands; b++)
158
      bandOffsets[b] = b;
159

160
    int scanlineStride = bands * w;
Tom Tromey committed
161
    return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
162
                                   bandOffsets, location);
Tom Tromey committed
163 164
  }

165 166
  /**
   * Creates an interleaved raster.
167
   *
168 169 170
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
171
   * @param scanlineStride  the number of data elements from a sample on one
172 173 174 175 176
   *     row to the corresponding sample on the next row.
   * @param pixelStride  the number of elements from a sample in one pixel to
   *     the corresponding sample in the next pixel.
   * @param bandOffsets  the band offsets.
   * @param location
177
   *
178 179
   * @return The new raster.
   */
180
  public static WritableRaster createInterleavedRaster(int dataType,
181 182 183 184 185
      int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
      Point location)
  {
    SampleModel sm = new ComponentSampleModel(dataType, w, h, pixelStride,
        scanlineStride, bandOffsets);
Tom Tromey committed
186 187 188
    return createWritableRaster(sm, location);
  }

189 190
  /**
   * Creates a new banded raster.
191
   *
192 193 194 195
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
196 197
   * @param location
   *
198 199
   * @return The new raster.
   */
200
  public static WritableRaster createBandedRaster(int dataType, int w, int h,
201
      int bands, Point location)
Tom Tromey committed
202 203 204 205 206
  {
    SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
    return createWritableRaster(sm, location);
  }

207 208
  /**
   * Creates a new banded raster.
209
   *
210 211 212
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
213
   * @param scanlineStride  the number of data elements from a sample on one
214 215 216 217
   *     row to the corresponding sample on the next row.
   * @param bankIndices  the index for each bank.
   * @param bandOffsets  the offset for each band.
   * @param location
218
   *
219 220 221 222
   * @return The new raster.
   */
  public static WritableRaster createBandedRaster(int dataType, int w, int h,
      int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)
Tom Tromey committed
223 224
  {
    SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
225
                                           bankIndices, bandOffsets);
Tom Tromey committed
226 227
    return createWritableRaster(sm, location);
  }
228

229 230
  /**
   * Creates a new packed raster.
231
   *
232 233 234 235
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bandMasks  the bit mask for each band.
236 237
   * @param location
   *
238 239 240 241
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(int dataType, int w, int h,
      int[] bandMasks, Point location)
Tom Tromey committed
242
  {
243 244
    SampleModel sm = new SinglePixelPackedSampleModel(dataType, w, h,
                                                     bandMasks);
Tom Tromey committed
245 246 247
    return createWritableRaster(sm, location);
  }

248 249
  /**
   * Creates a new raster.
250
   *
251 252 253 254 255 256
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
   * @param bitsPerBand  the number of bits per band.
   * @param location
257
   *
258 259
   * @return The new raster.
   */
Tom Tromey committed
260
  public static WritableRaster createPackedRaster(int dataType,
261
      int w, int h, int bands, int bitsPerBand, Point location)
Tom Tromey committed
262 263 264 265 266 267 268
  {
    if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
      throw new IllegalArgumentException();

    SampleModel sm;

    if (bands == 1)
269
      sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
Tom Tromey committed
270 271
    else
      {
272 273 274 275 276 277 278 279 280
        int[] bandMasks = new int[bands];
        int mask = 0x1;
        for (int bits = bitsPerBand; --bits != 0;)
          mask = (mask << 1) | 0x1;
        for (int i = 0; i < bands; i++)
          {
            bandMasks[i] = mask;
            mask <<= bitsPerBand;
          }
281

282
        sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
Tom Tromey committed
283 284 285 286
      }
    return createWritableRaster(sm, location);
  }

287 288
  /**
   * Creates a new interleaved raster.
289
   *
290 291 292
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
293
   * @param scanlineStride  the number of data elements from a sample on one
294 295 296 297 298
   *     row to the corresponding sample on the next row.
   * @param pixelStride  the number of elements from a sample in one pixel to
   *     the corresponding sample in the next pixel.
   * @param bandOffsets  the offset for each band.
   * @param location
299
   *
300 301
   * @return The new raster.
   */
302 303
  public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
      int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
304
      Point location)
Tom Tromey committed
305 306
  {
    SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
307
        w, h, pixelStride, scanlineStride, bandOffsets);
Tom Tromey committed
308 309 310
    return createWritableRaster(sm, dataBuffer, location);
  }

311 312
  /**
   * Creates a new banded raster.
313
   *
314 315 316
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
317
   * @param scanlineStride  the number of data elements from a sample on one
318 319 320 321
   *     row to the corresponding sample on the next row.
   * @param bankIndices  the index for each bank.
   * @param bandOffsets  the band offsets.
   * @param location
322
   *
323 324 325 326 327
   * @return The new raster.
   */
  public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
      int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets,
      Point location)
Tom Tromey committed
328 329
  {
    SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
330
        w, h, scanlineStride, bankIndices, bandOffsets);
Tom Tromey committed
331 332
    return createWritableRaster(sm, dataBuffer, location);
  }
333

334 335
  /**
   * Creates a new packed raster.
336
   *
337 338 339
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
340
   * @param scanlineStride  the number of data elements from a sample on one
341 342 343
   *     row to the corresponding sample on the next row.
   * @param bandMasks  the bit mask for each band.
   * @param location
344
   *
345 346 347 348
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
      int w, int h, int scanlineStride, int[] bandMasks, Point location)
Tom Tromey committed
349
 {
350 351
    SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
        w, h, scanlineStride, bandMasks);
Tom Tromey committed
352 353
    return createWritableRaster(sm, dataBuffer, location);
  }
354

355 356
  /**
   * Creates a new packed raster.
357
   *
358 359 360 361 362
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
   * @param bitsPerPixel  the number of bits per pixel.
   * @param location
363
   *
364 365 366 367 368 369 370
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
      int w, int h, int bitsPerPixel, Point location)
  {
    SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
        w, h, bitsPerPixel);
Tom Tromey committed
371 372
    return createWritableRaster(sm, dataBuffer, location);
  }
373

374 375
  /**
   * Creates a new raster.
376
   *
377 378 379
   * @param sm  the sample model.
   * @param db  the data buffer.
   * @param location
380
   *
381 382
   * @return The new raster.
   */
Tom Tromey committed
383
  public static Raster createRaster(SampleModel sm, DataBuffer db,
384
                                    Point location)
Tom Tromey committed
385 386 387 388
  {
    return new Raster(sm, db, location);
  }

389 390
  /**
   * Creates a new writable raster.
391
   *
392 393
   * @param sm  the sample model.
   * @param location
394
   *
395 396
   * @return The new writable raster.
   */
Tom Tromey committed
397
  public static WritableRaster createWritableRaster(SampleModel sm,
398
                                                    Point location)
Tom Tromey committed
399 400 401 402
  {
    return new WritableRaster(sm, location);
  }

403 404
  /**
   * Creates a new writable raster.
405
   *
406 407
   * @param sm  the sample model.
   * @param db  the data buffer.
408 409
   * @param location
   *
410 411
   * @return The new writable raster.
   */
Tom Tromey committed
412
  public static WritableRaster createWritableRaster(SampleModel sm,
413
      DataBuffer db, Point location)
Tom Tromey committed
414 415 416 417
  {
    return new WritableRaster(sm, db, location);
  }

418 419
  /**
   * Returns the raster's parent.
420
   *
421 422
   * @return The raster's parent.
   */
Tom Tromey committed
423 424 425 426 427
  public Raster getParent()
  {
    return parent;
  }

428 429
  /**
   * Returns the x-translation.
430
   *
431 432
   * @return The x-translation.
   */
Tom Tromey committed
433 434 435 436 437
  public final int getSampleModelTranslateX()
  {
    return sampleModelTranslateX;
  }

438 439
  /**
   * Returns the y-translation.
440
   *
441 442
   * @return The y-translation.
   */
Tom Tromey committed
443 444 445 446 447
  public final int getSampleModelTranslateY()
  {
    return sampleModelTranslateY;
  }

448 449
  /**
   * Creates a new writable raster that is compatible with this raster.
450
   *
451 452
   * @return A new writable raster.
   */
Tom Tromey committed
453 454 455 456 457
  public WritableRaster createCompatibleWritableRaster()
  {
    return new WritableRaster(getSampleModel(), new Point(minX, minY));
  }

458 459
  /**
   * Creates a new writable raster that is compatible with this raster.
460
   *
461 462
   * @param w  the width.
   * @param h  the height.
463
   *
464 465
   * @return A new writable raster.
   */
Tom Tromey committed
466 467 468 469 470
  public WritableRaster createCompatibleWritableRaster(int w, int h)
  {
    return createCompatibleWritableRaster(minX, minY, w, h);
  }

471 472 473
  /**
   * Creates a new writable raster that is compatible with this raster, with
   * the specified bounds.
474
   *
475
   * @param rect  the raster bounds.
476
   *
477 478
   * @return A new writable raster.
   */
Tom Tromey committed
479 480 481
  public WritableRaster createCompatibleWritableRaster(Rectangle rect)
  {
    return createCompatibleWritableRaster(rect.x, rect.y,
482
                                          rect.width, rect.height);
Tom Tromey committed
483 484
  }

485 486 487
  /**
   * Creates a new writable raster that is compatible with this raster, with
   * the specified bounds.
488
   *
489 490 491 492
   * @param x  the x-coordinate of the top-left corner of the raster.
   * @param y  the y-coordinate of the top-left corner of the raster.
   * @param w  the raster width.
   * @param h  the raster height.
493
   *
494 495
   * @return A new writable raster.
   */
Tom Tromey committed
496
  public WritableRaster createCompatibleWritableRaster(int x, int y,
497
                                                       int w, int h)
Tom Tromey committed
498 499
  {
    SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
500
    return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y));
Tom Tromey committed
501 502 503 504 505
  }

  public Raster createTranslatedChild(int childMinX, int childMinY) {
    int tcx = sampleModelTranslateX - minX + childMinX;
    int tcy = sampleModelTranslateY - minY + childMinY;
506

Tom Tromey committed
507
    return new Raster(sampleModel, dataBuffer,
508 509
                      new Rectangle(childMinX, childMinY, width, height),
                      new Point(tcx, tcy), this);
Tom Tromey committed
510 511 512
  }

  public Raster createChild(int parentX, int parentY, int width,
513 514
                            int height, int childMinX, int childMinY,
                            int[] bandList)
Tom Tromey committed
515
  {
516 517 518
    if (parentX < minX || parentX + width > minX + this.width
        || parentY < minY || parentY + height > minY + this.height)
      throw new RasterFormatException("Child raster extends beyond parent");
519

Tom Tromey committed
520 521 522 523 524 525 526 527 528
    SampleModel sm = (bandList == null) ?
      sampleModel :
      sampleModel.createSubsetSampleModel(bandList);

    /*
        data origin
       /
      +-------------------------
      |\. __ parent trans
529
      | \`.
Tom Tromey committed
530 531 532 533
      |  \ `.    parent origin
      |   \  `. /
      |   /\   +-------- - -
      |trans\ /<\-- deltaTrans
534
      |child +-+-\---- - -
Tom Tromey committed
535 536 537 538 539
      |     /|`|  \__ parent [x, y]
      |child | |`. \
      |origin| :  `.\
      |      |    / `\
      |      :   /    +
540
      | child [x, y]
Tom Tromey committed
541 542 543 544 545 546 547

      parent_xy - parent_trans = child_xy - child_trans

      child_trans = parent_trans + child_xy - parent_xy
    */

    return new Raster(sm, dataBuffer,
548 549 550 551
        new Rectangle(childMinX, childMinY, width, height),
        new Point(sampleModelTranslateX + childMinX - parentX,
                  sampleModelTranslateY + childMinY - parentY),
        this);
Tom Tromey committed
552 553
  }

554 555
  /**
   * Returns a new rectangle containing the bounds of this raster.
556
   *
557 558
   * @return A new rectangle containing the bounds of this raster.
   */
Tom Tromey committed
559 560 561 562 563
  public Rectangle getBounds()
  {
    return new Rectangle(minX, minY, width, height);
  }

564 565
  /**
   * Returns the x-coordinate of the top left corner of the raster.
566
   *
567 568
   * @return The x-coordinate of the top left corner of the raster.
   */
Tom Tromey committed
569 570 571 572 573
  public final int getMinX()
  {
    return minX;
  }

574 575
  /**
   * Returns the t-coordinate of the top left corner of the raster.
576
   *
577 578
   * @return The t-coordinate of the top left corner of the raster.
   */
Tom Tromey committed
579 580 581 582 583
  public final int getMinY()
  {
    return minY;
  }

584 585
  /**
   * Returns the width of the raster.
586
   *
587 588
   * @return The width of the raster.
   */
Tom Tromey committed
589 590 591 592 593
  public final int getWidth()
  {
    return width;
  }

594 595
  /**
   * Returns the height of the raster.
596
   *
597 598
   * @return The height of the raster.
   */
Tom Tromey committed
599 600 601 602 603
  public final int getHeight()
  {
    return height;
  }

604 605
  /**
   * Returns the number of bands for this raster.
606
   *
607 608
   * @return The number of bands.
   */
Tom Tromey committed
609 610 611 612
  public final int getNumBands()
  {
    return numBands;
  }
613

Tom Tromey committed
614 615 616 617
  public final int getNumDataElements()
  {
    return numDataElements;
  }
618

619
  /**
620
   * Returns the transfer type for the raster (this is determined by the
621
   * raster's sample model).
622
   *
623 624
   * @return The transfer type.
   */
Tom Tromey committed
625 626 627 628 629
  public final int getTransferType()
  {
    return sampleModel.getTransferType();
  }

630 631
  /**
   * Returns the data buffer that stores the pixel data for this raster.
632
   *
633 634
   * @return The data buffer.
   */
Tom Tromey committed
635 636 637 638 639
  public DataBuffer getDataBuffer()
  {
    return dataBuffer;
  }

640 641 642
  /**
   * Returns the sample model that accesses the data buffer (to extract pixel
   * data) for this raster.
643
   *
644 645
   * @return The sample model.
   */
Tom Tromey committed
646 647 648 649 650 651 652
  public SampleModel getSampleModel()
  {
    return sampleModel;
  }

  public Object getDataElements(int x, int y, Object outData)
  {
653 654
    return sampleModel.getDataElements(x - sampleModelTranslateX,
        y - sampleModelTranslateY, outData, dataBuffer);
Tom Tromey committed
655 656
  }

657
  public Object getDataElements(int x, int y, int w, int h, Object outData)
Tom Tromey committed
658
  {
659 660
    return sampleModel.getDataElements(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, outData, dataBuffer);
Tom Tromey committed
661 662
  }

663 664
  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
665
   * raster.  If <code>iArray</code> is not <code>null</code>, it will be
666 667
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
668
   *
669 670
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
671
   * @param iArray  an array to populate with the sample values and return as
672
   *     the result (if <code>null</code>, a new array will be allocated).
673
   *
674 675
   * @return The pixel sample values.
   */
Tom Tromey committed
676 677
  public int[] getPixel(int x, int y, int[] iArray)
  {
678 679
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, iArray, dataBuffer);
Tom Tromey committed
680 681
  }

682 683
  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
684
   * raster.  If <code>fArray</code> is not <code>null</code>, it will be
685 686
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
687
   *
688 689
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
690
   * @param fArray  an array to populate with the sample values and return as
691
   *     the result (if <code>null</code>, a new array will be allocated).
692
   *
693 694
   * @return The pixel sample values.
   */
Tom Tromey committed
695 696
  public float[] getPixel(int x, int y, float[] fArray)
  {
697 698
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, fArray, dataBuffer);
Tom Tromey committed
699 700
  }

701 702
  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
703
   * raster.  If <code>dArray</code> is not <code>null</code>, it will be
704 705
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
706
   *
707 708
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
709
   * @param dArray  an array to populate with the sample values and return as
710
   *     the result (if <code>null</code>, a new array will be allocated).
711
   *
712 713
   * @return The pixel sample values.
   */
Tom Tromey committed
714 715
  public double[] getPixel(int x, int y, double[] dArray)
  {
716 717
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, dArray, dataBuffer);
Tom Tromey committed
718 719
  }

720
  /**
721 722 723 724 725 726
   * Returns an array containing the samples for the pixels in the region
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
   * (that is, all the samples for the first pixel are grouped together,
   * followed by all the samples for the second pixel, and so on).
   * If <code>iArray</code> is not <code>null</code>, it will be populated
   * with the sample values and returned as the result of this function (this
727
   * avoids allocating a new array instance).
728
   *
729 730 731 732
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
733
   * @param iArray  an array to populate with the sample values and return as
734
   *     the result (if <code>null</code>, a new array will be allocated).
735
   *
736 737
   * @return The pixel sample values.
   */
Tom Tromey committed
738 739
  public int[] getPixels(int x, int y, int w, int h, int[] iArray)
  {
740 741
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, iArray, dataBuffer);
Tom Tromey committed
742 743
  }

744
  /**
745 746 747 748 749 750
   * Returns an array containing the samples for the pixels in the region
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
   * (that is, all the samples for the first pixel are grouped together,
   * followed by all the samples for the second pixel, and so on).
   * If <code>fArray</code> is not <code>null</code>, it will be populated
   * with the sample values and returned as the result of this function (this
751
   * avoids allocating a new array instance).
752
   *
753 754 755 756
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
757
   * @param fArray  an array to populate with the sample values and return as
758
   *     the result (if <code>null</code>, a new array will be allocated).
759
   *
760 761 762
   * @return The pixel sample values.
   */
  public float[] getPixels(int x, int y, int w, int h, float[] fArray)
Tom Tromey committed
763
  {
764 765
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, fArray, dataBuffer);
Tom Tromey committed
766 767
  }

768
  /**
769 770 771 772 773 774
   * Returns an array containing the samples for the pixels in the region
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
   * (that is, all the samples for the first pixel are grouped together,
   * followed by all the samples for the second pixel, and so on).
   * If <code>dArray</code> is not <code>null</code>, it will be populated
   * with the sample values and returned as the result of this function (this
775
   * avoids allocating a new array instance).
776
   *
777 778 779 780
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
781
   * @param dArray  an array to populate with the sample values and return as
782
   *     the result (if <code>null</code>, a new array will be allocated).
783
   *
784 785 786
   * @return The pixel sample values.
   */
  public double[] getPixels(int x, int y, int w, int h, double[] dArray)
Tom Tromey committed
787
  {
788 789
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, dArray, dataBuffer);
Tom Tromey committed
790 791
  }

792 793
  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
794
   *
795 796
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
797
   * @param b  the band (in the range <code>0</code> to
798
   *     <code>getNumBands() - 1</code>).
799
   *
800 801
   * @return The sample value.
   */
Tom Tromey committed
802 803
  public int getSample(int x, int y, int b)
  {
804 805
    return sampleModel.getSample(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
Tom Tromey committed
806 807
  }

808 809
  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
810
   *
811 812
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
813
   * @param b  the band (in the range <code>0</code> to
814
   *     <code>getNumBands() - 1</code>).
815
   *
816
   * @return The sample value.
817
   *
818 819
   * @see #getSample(int, int, int)
   */
Tom Tromey committed
820 821
  public float getSampleFloat(int x, int y, int b)
  {
822 823
    return sampleModel.getSampleFloat(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
Tom Tromey committed
824 825
  }

826 827
  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
828
   *
829 830
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
831
   * @param b  the band (in the range <code>0</code> to
832
   *     <code>getNumBands() - 1</code>).
833
   *
834
   * @return The sample value.
835
   *
836 837
   * @see #getSample(int, int, int)
   */
Tom Tromey committed
838 839
  public double getSampleDouble(int x, int y, int b)
  {
840 841
    return sampleModel.getSampleDouble(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
Tom Tromey committed
842 843
  }

844
  /**
845 846 847 848
   * Returns an array containing the samples from one band for the pixels in
   * the region specified by (x, y, w, h) in the raster.  If
   * <code>iArray</code> is not <code>null</code>, it will be
   * populated with the sample values and returned as the result of this
849
   * function (this avoids allocating a new array instance).
850
   *
851 852 853 854
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
855
   * @param b  the band (in the range <code>0</code> to
856
   *     </code>getNumBands() - 1</code>).
857
   * @param iArray  an array to populate with the sample values and return as
858
   *     the result (if <code>null</code>, a new array will be allocated).
859
   *
860 861
   * @return The sample values.
   */
Tom Tromey committed
862
  public int[] getSamples(int x, int y, int w, int h, int b,
863
                          int[] iArray)
Tom Tromey committed
864
  {
865 866
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
Tom Tromey committed
867 868
  }

869
  /**
870 871 872 873
   * Returns an array containing the samples from one band for the pixels in
   * the region specified by (x, y, w, h) in the raster.  If
   * <code>fArray</code> is not <code>null</code>, it will be
   * populated with the sample values and returned as the result of this
874 875 876 877 878 879
   * function (this avoids allocating a new array instance).
   *
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
880
   * @param b  the band (in the range <code>0</code> to
881
   *     </code>getNumBands() - 1</code>).
882
   * @param fArray  an array to populate with the sample values and return as
883
   *     the result (if <code>null</code>, a new array will be allocated).
884
   *
885
   * @return The sample values.
886
   */
887 888 889 890
  public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray)
  {
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
Tom Tromey committed
891 892
  }

893
  /**
894 895 896 897
   * Returns an array containing the samples from one band for the pixels in
   * the region specified by (x, y, w, h) in the raster.  If
   * <code>dArray</code> is not <code>null</code>, it will be
   * populated with the sample values and returned as the result of this
898
   * function (this avoids allocating a new array instance).
899
   *
900 901 902 903
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
904
   * @param b  the band (in the range <code>0</code> to
905
   *     </code>getNumBands() - 1</code>).
906
   * @param dArray  an array to populate with the sample values and return as
907
   *     the result (if <code>null</code>, a new array will be allocated).
908
   *
909 910
   * @return The sample values.
   */
911
  public double[] getSamples(int x, int y, int w, int h, int b,
912
                             double[] dArray)
Tom Tromey committed
913
  {
914 915
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
Tom Tromey committed
916
  }
917

Tom Tromey committed
918
  /**
919
   * Create a String representing the state of this Raster.
920
   *
Tom Tromey committed
921 922 923 924
   * @return A String representing the stat of this Raster.
   */
  public String toString()
  {
925
    CPStringBuilder result = new CPStringBuilder();
926

Tom Tromey committed
927 928 929 930 931 932 933
    result.append(getClass().getName());
    result.append("[(");
    result.append(minX).append(",").append(minY).append("), ");
    result.append(width).append(" x ").append(height).append(",");
    result.append(sampleModel).append(",");
    result.append(dataBuffer);
    result.append("]");
934

Tom Tromey committed
935 936 937
    return result.toString();
  }

938
  /**
939
   * Returns the number of bits used to represent the specified data type.
940 941 942 943 944 945 946 947 948 949
   * Valid types are:
   * <ul>
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
   *   <li>{@link DataBuffer#TYPE_SHORT};</li>
   *   <li>{@link DataBuffer#TYPE_INT};</li>
   *   <li>{@link DataBuffer#TYPE_FLOAT};</li>
   *   <li>{@link DataBuffer#TYPE_DOUBLE};</li>
   * </ul>
   * This method returns 0 for invalid data types.
950
   *
951
   * @param dataType  the data type.
952
   *
953 954
   * @return The number of bits used to represent the specified data type.
   */
Tom Tromey committed
955 956 957 958 959
  private static int getTypeBits(int dataType)
  {
    switch (dataType)
      {
      case DataBuffer.TYPE_BYTE:
960
        return 8;
Tom Tromey committed
961 962
      case DataBuffer.TYPE_USHORT:
      case DataBuffer.TYPE_SHORT:
963
        return 16;
Tom Tromey committed
964 965
      case DataBuffer.TYPE_INT:
      case DataBuffer.TYPE_FLOAT:
966
        return 32;
Tom Tromey committed
967
      case DataBuffer.TYPE_DOUBLE:
968
        return 64;
Tom Tromey committed
969
      default:
970
        return 0;
Tom Tromey committed
971 972 973
      }
  }
}