Source for java.awt.image.Raster

   1: /* Copyright (C) 2000, 2002, 2003, 2006,  Free Software Foundation
   2: 
   3: This file is part of GNU Classpath.
   4: 
   5: GNU Classpath is free software; you can redistribute it and/or modify
   6: it under the terms of the GNU General Public License as published by
   7: the Free Software Foundation; either version 2, or (at your option)
   8: any later version.
   9: 
  10: GNU Classpath is distributed in the hope that it will be useful, but
  11: WITHOUT ANY WARRANTY; without even the implied warranty of
  12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13: General Public License for more details.
  14: 
  15: You should have received a copy of the GNU General Public License
  16: along with GNU Classpath; see the file COPYING.  If not, write to the
  17: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  18: 02110-1301 USA.
  19: 
  20: Linking this library statically or dynamically with other modules is
  21: making a combined work based on this library.  Thus, the terms and
  22: conditions of the GNU General Public License cover the whole
  23: combination.
  24: 
  25: As a special exception, the copyright holders of this library give you
  26: permission to link this library with independent modules to produce an
  27: executable, regardless of the license terms of these independent
  28: modules, and to copy and distribute the resulting executable under
  29: terms of your choice, provided that you also meet, for each linked
  30: independent module, the terms and conditions of the license of that
  31: module.  An independent module is a module which is not derived from
  32: or based on this library.  If you modify this library, you may extend
  33: this exception to your version of the library, but you are not
  34: obligated to do so.  If you do not wish to do so, delete this
  35: exception statement from your version. */
  36: 
  37: 
  38: package java.awt.image;
  39: 
  40: import gnu.java.lang.CPStringBuilder;
  41: 
  42: import java.awt.Point;
  43: import java.awt.Rectangle;
  44: 
  45: /**
  46:  * A rectangular collection of pixels composed from a {@link DataBuffer} which
  47:  * stores the pixel values, and a {@link SampleModel} which is used to retrieve
  48:  * the pixel values.
  49:  *
  50:  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
  51:  */
  52: public class Raster
  53: {
  54:   /** The sample model used to access the pixel values. */
  55:   protected SampleModel sampleModel;
  56: 
  57:   /** The data buffer used to store the pixel values. */
  58:   protected DataBuffer dataBuffer;
  59: 
  60:   /** The x-coordinate of the top left corner of the raster. */
  61:   protected int minX;
  62: 
  63:   /** The y-coordinate of the top left corner of the raster. */
  64:   protected int minY;
  65: 
  66:   /** The width of the raster. */
  67:   protected int width;
  68: 
  69:   /** The height of the raster. */
  70:   protected int height;
  71: 
  72:   protected int sampleModelTranslateX;
  73: 
  74:   protected int sampleModelTranslateY;
  75: 
  76:   /** The number of bands. */
  77:   protected int numBands;
  78: 
  79:   protected int numDataElements;
  80: 
  81:   /** The raster's parent. */
  82:   protected Raster parent;
  83: 
  84:   /**
  85:    * Creates a new raster.
  86:    *
  87:    * @param sampleModel  the sample model.
  88:    * @param origin  the origin.
  89:    */
  90:   protected Raster(SampleModel sampleModel, Point origin)
  91:   {
  92:     this(sampleModel, sampleModel.createDataBuffer(), origin);
  93:   }
  94: 
  95:   /**
  96:    * Creates a new raster.
  97:    *
  98:    * @param sampleModel  the sample model.
  99:    * @param dataBuffer  the data buffer.
 100:    * @param origin  the origin.
 101:    */
 102:   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
 103:                    Point origin)
 104:   {
 105:     this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
 106:          sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
 107:   }
 108: 
 109:   /**
 110:    * Creates a new raster.
 111:    *
 112:    * @param sampleModel  the sample model.
 113:    * @param dataBuffer  the data buffer.
 114:    * @param aRegion  the raster's bounds.
 115:    * @param sampleModelTranslate  the translation (<code>null</code> permitted).
 116:    * @param parent  the raster's parent.
 117:    */
 118:   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
 119:       Rectangle aRegion, Point sampleModelTranslate, Raster parent)
 120:   {
 121:     this.sampleModel = sampleModel;
 122:     this.dataBuffer = dataBuffer;
 123:     this.minX = aRegion.x;
 124:     this.minY = aRegion.y;
 125:     this.width = aRegion.width;
 126:     this.height = aRegion.height;
 127: 
 128:     // If sampleModelTranslate is null, use (0,0).  Methods such as
 129:     // Raster.createRaster are specified to allow for a null argument.
 130:     if (sampleModelTranslate != null)
 131:     {
 132:       this.sampleModelTranslateX = sampleModelTranslate.x;
 133:       this.sampleModelTranslateY = sampleModelTranslate.y;
 134:     }
 135: 
 136:     this.numBands = sampleModel.getNumBands();
 137:     this.numDataElements = sampleModel.getNumDataElements();
 138:     this.parent = parent;
 139:   }
 140: 
 141:   /**
 142:    * Creates an interleaved raster using the specified data type.
 143:    *
 144:    * @param dataType  the data type.
 145:    * @param w  the width.
 146:    * @param h  the height.
 147:    * @param bands  the number of bands.
 148:    * @param location
 149:    *
 150:    * @return The new raster.
 151:    */
 152:   public static WritableRaster createInterleavedRaster(int dataType,
 153:       int w, int h, int bands, Point location)
 154:   {
 155:     int[] bandOffsets = new int[bands];
 156:     // 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;
 161:     return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
 162:                                    bandOffsets, location);
 163:   }
 164: 
 165:   /**
 166:    * Creates an interleaved raster.
 167:    *
 168:    * @param dataType  the data type.
 169:    * @param w  the width.
 170:    * @param h  the height.
 171:    * @param scanlineStride  the number of data elements from a sample on one
 172:    *     row to the corresponding sample on the next row.
 173:    * @param pixelStride  the number of elements from a sample in one pixel to
 174:    *     the corresponding sample in the next pixel.
 175:    * @param bandOffsets  the band offsets.
 176:    * @param location
 177:    *
 178:    * @return The new raster.
 179:    */
 180:   public static WritableRaster createInterleavedRaster(int dataType,
 181:       int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
 182:       Point location)
 183:   {
 184:     SampleModel sm = new ComponentSampleModel(dataType, w, h, pixelStride,
 185:         scanlineStride, bandOffsets);
 186:     return createWritableRaster(sm, location);
 187:   }
 188: 
 189:   /**
 190:    * Creates a new banded raster.
 191:    *
 192:    * @param dataType  the data type.
 193:    * @param w  the width.
 194:    * @param h  the height.
 195:    * @param bands  the number of bands.
 196:    * @param location
 197:    *
 198:    * @return The new raster.
 199:    */
 200:   public static WritableRaster createBandedRaster(int dataType, int w, int h,
 201:       int bands, Point location)
 202:   {
 203:     SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
 204:     return createWritableRaster(sm, location);
 205:   }
 206: 
 207:   /**
 208:    * Creates a new banded raster.
 209:    *
 210:    * @param dataType  the data type.
 211:    * @param w  the width.
 212:    * @param h  the height.
 213:    * @param scanlineStride  the number of data elements from a sample on one
 214:    *     row to the corresponding sample on the next row.
 215:    * @param bankIndices  the index for each bank.
 216:    * @param bandOffsets  the offset for each band.
 217:    * @param location
 218:    *
 219:    * @return The new raster.
 220:    */
 221:   public static WritableRaster createBandedRaster(int dataType, int w, int h,
 222:       int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)
 223:   {
 224:     SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
 225:                                            bankIndices, bandOffsets);
 226:     return createWritableRaster(sm, location);
 227:   }
 228: 
 229:   /**
 230:    * Creates a new packed raster.
 231:    *
 232:    * @param dataType  the data type.
 233:    * @param w  the width.
 234:    * @param h  the height.
 235:    * @param bandMasks  the bit mask for each band.
 236:    * @param location
 237:    *
 238:    * @return The new raster.
 239:    */
 240:   public static WritableRaster createPackedRaster(int dataType, int w, int h,
 241:       int[] bandMasks, Point location)
 242:   {
 243:     SampleModel sm = new SinglePixelPackedSampleModel(dataType, w, h,
 244:                                                      bandMasks);
 245:     return createWritableRaster(sm, location);
 246:   }
 247: 
 248:   /**
 249:    * Creates a new raster.
 250:    *
 251:    * @param dataType  the data type.
 252:    * @param w  the width.
 253:    * @param h  the height.
 254:    * @param bands  the number of bands.
 255:    * @param bitsPerBand  the number of bits per band.
 256:    * @param location
 257:    *
 258:    * @return The new raster.
 259:    */
 260:   public static WritableRaster createPackedRaster(int dataType,
 261:       int w, int h, int bands, int bitsPerBand, Point location)
 262:   {
 263:     if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
 264:       throw new IllegalArgumentException();
 265: 
 266:     SampleModel sm;
 267: 
 268:     if (bands == 1)
 269:       sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
 270:     else
 271:       {
 272:         int[] bandMasks = new int[bands];
 273:         int mask = 0x1;
 274:         for (int bits = bitsPerBand; --bits != 0;)
 275:           mask = (mask << 1) | 0x1;
 276:         for (int i = 0; i < bands; i++)
 277:           {
 278:             bandMasks[i] = mask;
 279:             mask <<= bitsPerBand;
 280:           }
 281: 
 282:         sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
 283:       }
 284:     return createWritableRaster(sm, location);
 285:   }
 286: 
 287:   /**
 288:    * Creates a new interleaved raster.
 289:    *
 290:    * @param dataBuffer  the data buffer.
 291:    * @param w  the width.
 292:    * @param h  the height.
 293:    * @param scanlineStride  the number of data elements from a sample on one
 294:    *     row to the corresponding sample on the next row.
 295:    * @param pixelStride  the number of elements from a sample in one pixel to
 296:    *     the corresponding sample in the next pixel.
 297:    * @param bandOffsets  the offset for each band.
 298:    * @param location
 299:    *
 300:    * @return The new raster.
 301:    */
 302:   public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
 303:       int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
 304:       Point location)
 305:   {
 306:     SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
 307:         w, h, pixelStride, scanlineStride, bandOffsets);
 308:     return createWritableRaster(sm, dataBuffer, location);
 309:   }
 310: 
 311:   /**
 312:    * Creates a new banded raster.
 313:    *
 314:    * @param dataBuffer  the data buffer.
 315:    * @param w  the width.
 316:    * @param h  the height.
 317:    * @param scanlineStride  the number of data elements from a sample on one
 318:    *     row to the corresponding sample on the next row.
 319:    * @param bankIndices  the index for each bank.
 320:    * @param bandOffsets  the band offsets.
 321:    * @param location
 322:    *
 323:    * @return The new raster.
 324:    */
 325:   public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
 326:       int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets,
 327:       Point location)
 328:   {
 329:     SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
 330:         w, h, scanlineStride, bankIndices, bandOffsets);
 331:     return createWritableRaster(sm, dataBuffer, location);
 332:   }
 333: 
 334:   /**
 335:    * Creates a new packed raster.
 336:    *
 337:    * @param dataBuffer  the data buffer.
 338:    * @param w  the width.
 339:    * @param h  the height.
 340:    * @param scanlineStride  the number of data elements from a sample on one
 341:    *     row to the corresponding sample on the next row.
 342:    * @param bandMasks  the bit mask for each band.
 343:    * @param location
 344:    *
 345:    * @return The new raster.
 346:    */
 347:   public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
 348:       int w, int h, int scanlineStride, int[] bandMasks, Point location)
 349:  {
 350:     SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
 351:         w, h, scanlineStride, bandMasks);
 352:     return createWritableRaster(sm, dataBuffer, location);
 353:   }
 354: 
 355:   /**
 356:    * Creates a new packed raster.
 357:    *
 358:    * @param dataBuffer  the data buffer.
 359:    * @param w  the width.
 360:    * @param h  the height.
 361:    * @param bitsPerPixel  the number of bits per pixel.
 362:    * @param location
 363:    *
 364:    * @return The new raster.
 365:    */
 366:   public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
 367:       int w, int h, int bitsPerPixel, Point location)
 368:   {
 369:     SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
 370:         w, h, bitsPerPixel);
 371:     return createWritableRaster(sm, dataBuffer, location);
 372:   }
 373: 
 374:   /**
 375:    * Creates a new raster.
 376:    *
 377:    * @param sm  the sample model.
 378:    * @param db  the data buffer.
 379:    * @param location
 380:    *
 381:    * @return The new raster.
 382:    */
 383:   public static Raster createRaster(SampleModel sm, DataBuffer db,
 384:                                     Point location)
 385:   {
 386:     return new Raster(sm, db, location);
 387:   }
 388: 
 389:   /**
 390:    * Creates a new writable raster.
 391:    *
 392:    * @param sm  the sample model.
 393:    * @param location
 394:    *
 395:    * @return The new writable raster.
 396:    */
 397:   public static WritableRaster createWritableRaster(SampleModel sm,
 398:                                                     Point location)
 399:   {
 400:     return new WritableRaster(sm, location);
 401:   }
 402: 
 403:   /**
 404:    * Creates a new writable raster.
 405:    *
 406:    * @param sm  the sample model.
 407:    * @param db  the data buffer.
 408:    * @param location
 409:    *
 410:    * @return The new writable raster.
 411:    */
 412:   public static WritableRaster createWritableRaster(SampleModel sm,
 413:       DataBuffer db, Point location)
 414:   {
 415:     return new WritableRaster(sm, db, location);
 416:   }
 417: 
 418:   /**
 419:    * Returns the raster's parent.
 420:    *
 421:    * @return The raster's parent.
 422:    */
 423:   public Raster getParent()
 424:   {
 425:     return parent;
 426:   }
 427: 
 428:   /**
 429:    * Returns the x-translation.
 430:    *
 431:    * @return The x-translation.
 432:    */
 433:   public final int getSampleModelTranslateX()
 434:   {
 435:     return sampleModelTranslateX;
 436:   }
 437: 
 438:   /**
 439:    * Returns the y-translation.
 440:    *
 441:    * @return The y-translation.
 442:    */
 443:   public final int getSampleModelTranslateY()
 444:   {
 445:     return sampleModelTranslateY;
 446:   }
 447: 
 448:   /**
 449:    * Creates a new writable raster that is compatible with this raster.
 450:    *
 451:    * @return A new writable raster.
 452:    */
 453:   public WritableRaster createCompatibleWritableRaster()
 454:   {
 455:     return new WritableRaster(getSampleModel(), new Point(minX, minY));
 456:   }
 457: 
 458:   /**
 459:    * Creates a new writable raster that is compatible with this raster.
 460:    *
 461:    * @param w  the width.
 462:    * @param h  the height.
 463:    *
 464:    * @return A new writable raster.
 465:    */
 466:   public WritableRaster createCompatibleWritableRaster(int w, int h)
 467:   {
 468:     return createCompatibleWritableRaster(minX, minY, w, h);
 469:   }
 470: 
 471:   /**
 472:    * Creates a new writable raster that is compatible with this raster, with
 473:    * the specified bounds.
 474:    *
 475:    * @param rect  the raster bounds.
 476:    *
 477:    * @return A new writable raster.
 478:    */
 479:   public WritableRaster createCompatibleWritableRaster(Rectangle rect)
 480:   {
 481:     return createCompatibleWritableRaster(rect.x, rect.y,
 482:                                           rect.width, rect.height);
 483:   }
 484: 
 485:   /**
 486:    * Creates a new writable raster that is compatible with this raster, with
 487:    * the specified bounds.
 488:    *
 489:    * @param x  the x-coordinate of the top-left corner of the raster.
 490:    * @param y  the y-coordinate of the top-left corner of the raster.
 491:    * @param w  the raster width.
 492:    * @param h  the raster height.
 493:    *
 494:    * @return A new writable raster.
 495:    */
 496:   public WritableRaster createCompatibleWritableRaster(int x, int y,
 497:                                                        int w, int h)
 498:   {
 499:     SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
 500:     return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y));
 501:   }
 502: 
 503:   public Raster createTranslatedChild(int childMinX, int childMinY) {
 504:     int tcx = sampleModelTranslateX - minX + childMinX;
 505:     int tcy = sampleModelTranslateY - minY + childMinY;
 506: 
 507:     return new Raster(sampleModel, dataBuffer,
 508:                       new Rectangle(childMinX, childMinY, width, height),
 509:                       new Point(tcx, tcy), this);
 510:   }
 511: 
 512:   public Raster createChild(int parentX, int parentY, int width,
 513:                             int height, int childMinX, int childMinY,
 514:                             int[] bandList)
 515:   {
 516:     if (parentX < minX || parentX + width > minX + this.width
 517:         || parentY < minY || parentY + height > minY + this.height)
 518:       throw new RasterFormatException("Child raster extends beyond parent");
 519: 
 520:     SampleModel sm = (bandList == null) ?
 521:       sampleModel :
 522:       sampleModel.createSubsetSampleModel(bandList);
 523: 
 524:     /*
 525:         data origin
 526:        /
 527:       +-------------------------
 528:       |\. __ parent trans
 529:       | \`.
 530:       |  \ `.    parent origin
 531:       |   \  `. /
 532:       |   /\   +-------- - -
 533:       |trans\ /<\-- deltaTrans
 534:       |child +-+-\---- - -
 535:       |     /|`|  \__ parent [x, y]
 536:       |child | |`. \
 537:       |origin| :  `.\
 538:       |      |    / `\
 539:       |      :   /    +
 540:       | child [x, y]
 541: 
 542:       parent_xy - parent_trans = child_xy - child_trans
 543: 
 544:       child_trans = parent_trans + child_xy - parent_xy
 545:     */
 546: 
 547:     return new Raster(sm, dataBuffer,
 548:         new Rectangle(childMinX, childMinY, width, height),
 549:         new Point(sampleModelTranslateX + childMinX - parentX,
 550:                   sampleModelTranslateY + childMinY - parentY),
 551:         this);
 552:   }
 553: 
 554:   /**
 555:    * Returns a new rectangle containing the bounds of this raster.
 556:    *
 557:    * @return A new rectangle containing the bounds of this raster.
 558:    */
 559:   public Rectangle getBounds()
 560:   {
 561:     return new Rectangle(minX, minY, width, height);
 562:   }
 563: 
 564:   /**
 565:    * Returns the x-coordinate of the top left corner of the raster.
 566:    *
 567:    * @return The x-coordinate of the top left corner of the raster.
 568:    */
 569:   public final int getMinX()
 570:   {
 571:     return minX;
 572:   }
 573: 
 574:   /**
 575:    * Returns the t-coordinate of the top left corner of the raster.
 576:    *
 577:    * @return The t-coordinate of the top left corner of the raster.
 578:    */
 579:   public final int getMinY()
 580:   {
 581:     return minY;
 582:   }
 583: 
 584:   /**
 585:    * Returns the width of the raster.
 586:    *
 587:    * @return The width of the raster.
 588:    */
 589:   public final int getWidth()
 590:   {
 591:     return width;
 592:   }
 593: 
 594:   /**
 595:    * Returns the height of the raster.
 596:    *
 597:    * @return The height of the raster.
 598:    */
 599:   public final int getHeight()
 600:   {
 601:     return height;
 602:   }
 603: 
 604:   /**
 605:    * Returns the number of bands for this raster.
 606:    *
 607:    * @return The number of bands.
 608:    */
 609:   public final int getNumBands()
 610:   {
 611:     return numBands;
 612:   }
 613: 
 614:   public final int getNumDataElements()
 615:   {
 616:     return numDataElements;
 617:   }
 618: 
 619:   /**
 620:    * Returns the transfer type for the raster (this is determined by the
 621:    * raster's sample model).
 622:    *
 623:    * @return The transfer type.
 624:    */
 625:   public final int getTransferType()
 626:   {
 627:     return sampleModel.getTransferType();
 628:   }
 629: 
 630:   /**
 631:    * Returns the data buffer that stores the pixel data for this raster.
 632:    *
 633:    * @return The data buffer.
 634:    */
 635:   public DataBuffer getDataBuffer()
 636:   {
 637:     return dataBuffer;
 638:   }
 639: 
 640:   /**
 641:    * Returns the sample model that accesses the data buffer (to extract pixel
 642:    * data) for this raster.
 643:    *
 644:    * @return The sample model.
 645:    */
 646:   public SampleModel getSampleModel()
 647:   {
 648:     return sampleModel;
 649:   }
 650: 
 651:   public Object getDataElements(int x, int y, Object outData)
 652:   {
 653:     return sampleModel.getDataElements(x - sampleModelTranslateX,
 654:         y - sampleModelTranslateY, outData, dataBuffer);
 655:   }
 656: 
 657:   public Object getDataElements(int x, int y, int w, int h, Object outData)
 658:   {
 659:     return sampleModel.getDataElements(x - sampleModelTranslateX,
 660:         y - sampleModelTranslateY, w, h, outData, dataBuffer);
 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:    * populated with the sample values and returned as the result of
 667:    * this function (this avoids allocating a new array instance).
 668:    *
 669:    * @param x  the x-coordinate of the pixel.
 670:    * @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:    * @return The pixel sample values.
 675:    */
 676:   public int[] getPixel(int x, int y, int[] iArray)
 677:   {
 678:     return sampleModel.getPixel(x - sampleModelTranslateX,
 679:         y - sampleModelTranslateY, iArray, dataBuffer);
 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:    * populated with the sample values and returned as the result of
 686:    * this function (this avoids allocating a new array instance).
 687:    *
 688:    * @param x  the x-coordinate of the pixel.
 689:    * @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:    * @return The pixel sample values.
 694:    */
 695:   public float[] getPixel(int x, int y, float[] fArray)
 696:   {
 697:     return sampleModel.getPixel(x - sampleModelTranslateX,
 698:         y - sampleModelTranslateY, fArray, dataBuffer);
 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:    * populated with the sample values and returned as the result of
 705:    * this function (this avoids allocating a new array instance).
 706:    *
 707:    * @param x  the x-coordinate of the pixel.
 708:    * @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:    * @return The pixel sample values.
 713:    */
 714:   public double[] getPixel(int x, int y, double[] dArray)
 715:   {
 716:     return sampleModel.getPixel(x - sampleModelTranslateX,
 717:         y - sampleModelTranslateY, dArray, dataBuffer);
 718:   }
 719: 
 720:   /**
 721:    * Returns an array containing the samples for the pixels in the region
 722:    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
 723:    * (that is, all the samples for the first pixel are grouped together,
 724:    * followed by all the samples for the second pixel, and so on).
 725:    * If <code>iArray</code> is not <code>null</code>, it will be populated
 726:    * with the sample values and returned as the result of this function (this
 727:    * avoids allocating a new array instance).
 728:    *
 729:    * @param x  the x-coordinate of the top-left pixel.
 730:    * @param y  the y-coordinate of the top-left pixel.
 731:    * @param w  the width of the region of pixels.
 732:    * @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:    * @return The pixel sample values.
 737:    */
 738:   public int[] getPixels(int x, int y, int w, int h, int[] iArray)
 739:   {
 740:     return sampleModel.getPixels(x - sampleModelTranslateX,
 741:         y - sampleModelTranslateY, w, h, iArray, dataBuffer);
 742:   }
 743: 
 744:   /**
 745:    * Returns an array containing the samples for the pixels in the region
 746:    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
 747:    * (that is, all the samples for the first pixel are grouped together,
 748:    * followed by all the samples for the second pixel, and so on).
 749:    * If <code>fArray</code> is not <code>null</code>, it will be populated
 750:    * with the sample values and returned as the result of this function (this
 751:    * avoids allocating a new array instance).
 752:    *
 753:    * @param x  the x-coordinate of the top-left pixel.
 754:    * @param y  the y-coordinate of the top-left pixel.
 755:    * @param w  the width of the region of pixels.
 756:    * @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:    * @return The pixel sample values.
 761:    */
 762:   public float[] getPixels(int x, int y, int w, int h, float[] fArray)
 763:   {
 764:     return sampleModel.getPixels(x - sampleModelTranslateX,
 765:         y - sampleModelTranslateY, w, h, fArray, dataBuffer);
 766:   }
 767: 
 768:   /**
 769:    * Returns an array containing the samples for the pixels in the region
 770:    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels
 771:    * (that is, all the samples for the first pixel are grouped together,
 772:    * followed by all the samples for the second pixel, and so on).
 773:    * If <code>dArray</code> is not <code>null</code>, it will be populated
 774:    * with the sample values and returned as the result of this function (this
 775:    * avoids allocating a new array instance).
 776:    *
 777:    * @param x  the x-coordinate of the top-left pixel.
 778:    * @param y  the y-coordinate of the top-left pixel.
 779:    * @param w  the width of the region of pixels.
 780:    * @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:    * @return The pixel sample values.
 785:    */
 786:   public double[] getPixels(int x, int y, int w, int h, double[] dArray)
 787:   {
 788:     return sampleModel.getPixels(x - sampleModelTranslateX,
 789:         y - sampleModelTranslateY, w, h, dArray, dataBuffer);
 790:   }
 791: 
 792:   /**
 793:    * Returns the sample value for the pixel at (x, y) in the raster.
 794:    *
 795:    * @param x  the x-coordinate of the pixel.
 796:    * @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:    * @return The sample value.
 801:    */
 802:   public int getSample(int x, int y, int b)
 803:   {
 804:     return sampleModel.getSample(x - sampleModelTranslateX,
 805:         y - sampleModelTranslateY, b, dataBuffer);
 806:   }
 807: 
 808:   /**
 809:    * Returns the sample value for the pixel at (x, y) in the raster.
 810:    *
 811:    * @param x  the x-coordinate of the pixel.
 812:    * @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:    * @see #getSample(int, int, int)
 819:    */
 820:   public float getSampleFloat(int x, int y, int b)
 821:   {
 822:     return sampleModel.getSampleFloat(x - sampleModelTranslateX,
 823:         y - sampleModelTranslateY, b, dataBuffer);
 824:   }
 825: 
 826:   /**
 827:    * Returns the sample value for the pixel at (x, y) in the raster.
 828:    *
 829:    * @param x  the x-coordinate of the pixel.
 830:    * @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:    * @see #getSample(int, int, int)
 837:    */
 838:   public double getSampleDouble(int x, int y, int b)
 839:   {
 840:     return sampleModel.getSampleDouble(x - sampleModelTranslateX,
 841:         y - sampleModelTranslateY, b, dataBuffer);
 842:   }
 843: 
 844:   /**
 845:    * Returns an array containing the samples from one band for the pixels in
 846:    * the region specified by (x, y, w, h) in the raster.  If
 847:    * <code>iArray</code> is not <code>null</code>, it will be
 848:    * populated with the sample values and returned as the result of this
 849:    * function (this avoids allocating a new array instance).
 850:    *
 851:    * @param x  the x-coordinate of the top-left pixel.
 852:    * @param y  the y-coordinate of the top-left pixel.
 853:    * @param w  the width of the region of pixels.
 854:    * @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:    * @return The sample values.
 861:    */
 862:   public int[] getSamples(int x, int y, int w, int h, int b,
 863:                           int[] iArray)
 864:   {
 865:     return sampleModel.getSamples(x - sampleModelTranslateX,
 866:         y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
 867:   }
 868: 
 869:   /**
 870:    * Returns an array containing the samples from one band for the pixels in
 871:    * the region specified by (x, y, w, h) in the raster.  If
 872:    * <code>fArray</code> is not <code>null</code>, it will be
 873:    * populated with the sample values and returned as the result of this
 874:    * function (this avoids allocating a new array instance).
 875:    *
 876:    * @param x  the x-coordinate of the top-left pixel.
 877:    * @param y  the y-coordinate of the top-left pixel.
 878:    * @param w  the width of the region of pixels.
 879:    * @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:   public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray)
 888:   {
 889:     return sampleModel.getSamples(x - sampleModelTranslateX,
 890:         y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
 891:   }
 892: 
 893:   /**
 894:    * Returns an array containing the samples from one band for the pixels in
 895:    * the region specified by (x, y, w, h) in the raster.  If
 896:    * <code>dArray</code> is not <code>null</code>, it will be
 897:    * populated with the sample values and returned as the result of this
 898:    * function (this avoids allocating a new array instance).
 899:    *
 900:    * @param x  the x-coordinate of the top-left pixel.
 901:    * @param y  the y-coordinate of the top-left pixel.
 902:    * @param w  the width of the region of pixels.
 903:    * @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:    * @return The sample values.
 910:    */
 911:   public double[] getSamples(int x, int y, int w, int h, int b,
 912:                              double[] dArray)
 913:   {
 914:     return sampleModel.getSamples(x - sampleModelTranslateX,
 915:         y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
 916:   }
 917: 
 918:   /**
 919:    * Create a String representing the state of this Raster.
 920:    *
 921:    * @return A String representing the stat of this Raster.
 922:    */
 923:   public String toString()
 924:   {
 925:     CPStringBuilder result = new CPStringBuilder();
 926: 
 927:     result.append(getClass().getName());
 928:     result.append("[(");
 929:     result.append(minX).append(",").append(minY).append("), ");
 930:     result.append(width).append(" x ").append(height).append(",");
 931:     result.append(sampleModel).append(",");
 932:     result.append(dataBuffer);
 933:     result.append("]");
 934: 
 935:     return result.toString();
 936:   }
 937: 
 938:   /**
 939:    * Returns the number of bits used to represent the specified data type.
 940:    * Valid types are:
 941:    * <ul>
 942:    *   <li>{@link DataBuffer#TYPE_BYTE};</li>
 943:    *   <li>{@link DataBuffer#TYPE_USHORT};</li>
 944:    *   <li>{@link DataBuffer#TYPE_SHORT};</li>
 945:    *   <li>{@link DataBuffer#TYPE_INT};</li>
 946:    *   <li>{@link DataBuffer#TYPE_FLOAT};</li>
 947:    *   <li>{@link DataBuffer#TYPE_DOUBLE};</li>
 948:    * </ul>
 949:    * This method returns 0 for invalid data types.
 950:    *
 951:    * @param dataType  the data type.
 952:    *
 953:    * @return The number of bits used to represent the specified data type.
 954:    */
 955:   private static int getTypeBits(int dataType)
 956:   {
 957:     switch (dataType)
 958:       {
 959:       case DataBuffer.TYPE_BYTE:
 960:         return 8;
 961:       case DataBuffer.TYPE_USHORT:
 962:       case DataBuffer.TYPE_SHORT:
 963:         return 16;
 964:       case DataBuffer.TYPE_INT:
 965:       case DataBuffer.TYPE_FLOAT:
 966:         return 32;
 967:       case DataBuffer.TYPE_DOUBLE:
 968:         return 64;
 969:       default:
 970:         return 0;
 971:       }
 972:   }
 973: }