Source for java.awt.image.Raster

   1: /* Copyright (C) 2000, 2002, 2003  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 java.awt.Point;
  41: import java.awt.Rectangle;
  42: 
  43: /**
  44:  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
  45:  */
  46: public class Raster
  47: {
  48:   protected SampleModel sampleModel;
  49:   protected DataBuffer dataBuffer;
  50:   protected int minX;
  51:   protected int minY;
  52:   protected int width;
  53:   protected int height;
  54:   protected int sampleModelTranslateX;
  55:   protected int sampleModelTranslateY;
  56:   protected int numBands;
  57:   protected int numDataElements;
  58:   protected Raster parent;
  59:   
  60:   protected Raster(SampleModel sampleModel, Point origin)
  61:   {
  62:     this(sampleModel, sampleModel.createDataBuffer(), origin);
  63:   }
  64:   
  65:   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
  66:            Point origin)
  67:   {
  68:     this(sampleModel, dataBuffer,
  69:      new Rectangle(origin.x, origin.y,
  70:                sampleModel.getWidth(), sampleModel.getHeight()),
  71:      origin, null);
  72:   }
  73: 
  74:   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
  75:            Rectangle aRegion,
  76:            Point sampleModelTranslate, Raster parent)
  77:   {
  78:     this.sampleModel = sampleModel;
  79:     this.dataBuffer = dataBuffer;
  80:     this.minX = aRegion.x;
  81:     this.minY = aRegion.y;
  82:     this.width = aRegion.width;
  83:     this.height = aRegion.height;
  84:     
  85:     // If sampleModelTranslate is null, use (0,0).  Methods such as
  86:     // Raster.createRaster are specified to allow for a null argument.
  87:     if (sampleModelTranslate != null)
  88:     {
  89:       this.sampleModelTranslateX = sampleModelTranslate.x;
  90:       this.sampleModelTranslateY = sampleModelTranslate.y;
  91:     }
  92: 
  93:     this.numBands = sampleModel.getNumBands();
  94:     this.numDataElements = sampleModel.getNumDataElements();
  95:     this.parent = parent;
  96:   }
  97:     
  98:   public static WritableRaster createInterleavedRaster(int dataType,
  99:                                int w, int h,
 100:                                int bands, 
 101:                                Point location)
 102:   {
 103:     int[] bandOffsets = new int[bands];
 104:     // TODO: Maybe not generate this every time.
 105:     for (int b=0; b<bands; b++) bandOffsets[b] = b;
 106:     
 107:     int scanlineStride = bands*w;
 108:     return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
 109:                    bandOffsets, location);
 110:   }
 111: 
 112:   public static WritableRaster createInterleavedRaster(int dataType,
 113:                                int w, int h,
 114:                                int scanlineStride,
 115:                                int pixelStride,
 116:                                int[] bandOffsets,
 117:                                Point location)
 118:   {
 119:     SampleModel sm = new ComponentSampleModel(dataType,
 120:                           w, h,
 121:                           pixelStride,
 122:                           scanlineStride,
 123:                           bandOffsets);
 124:     return createWritableRaster(sm, location);
 125:   }
 126: 
 127:   public static WritableRaster createBandedRaster(int dataType, 
 128:                           int w, int h, int bands,
 129:                           Point location)
 130:   {
 131:     SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
 132:     return createWritableRaster(sm, location);
 133:   }
 134: 
 135:   public static WritableRaster createBandedRaster(int dataType,
 136:                           int w, int h,
 137:                           int scanlineStride,
 138:                           int[] bankIndices,
 139:                           int[] bandOffsets,
 140:                           Point location)
 141:   {
 142:     SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
 143:                        bankIndices, bandOffsets);
 144:     return createWritableRaster(sm, location);
 145:   }
 146:   
 147:   public static WritableRaster createPackedRaster(int dataType,
 148:                           int w, int h,
 149:                           int[] bandMasks,
 150:                           Point location)
 151:   {
 152:     SampleModel sm = new SinglePixelPackedSampleModel(dataType,
 153:                               w, h,
 154:                               bandMasks);
 155:     return createWritableRaster(sm, location);
 156:   }
 157: 
 158:   public static WritableRaster createPackedRaster(int dataType,
 159:                           int w, int h,
 160:                           int bands, int bitsPerBand,
 161:                           Point location)
 162:   {
 163:     if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
 164:       throw new IllegalArgumentException();
 165: 
 166:     SampleModel sm;
 167: 
 168:     if (bands == 1)
 169:     sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
 170:     else
 171:       {
 172:     int[] bandMasks = new int[bands];
 173:     int mask = 0x1;
 174:     for (int bits = bitsPerBand; --bits != 0;)
 175:       mask = (mask << 1) | 0x1;
 176:     for (int i = 0; i < bands; i++)
 177:       {
 178:         bandMasks[i] = mask;
 179:         mask <<= bitsPerBand;
 180:       }
 181:       
 182:     sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
 183:       }
 184:     return createWritableRaster(sm, location);
 185:   }
 186: 
 187:   public static WritableRaster
 188:   createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
 189:               int scanlineStride, int pixelStride,
 190:               int[] bandOffsets, Point location)
 191:   {
 192:     SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
 193:                           w, h,
 194:                           scanlineStride,
 195:                           pixelStride,
 196:                           bandOffsets);
 197:     return createWritableRaster(sm, dataBuffer, location);
 198:   }
 199: 
 200:   public static
 201:   WritableRaster createBandedRaster(DataBuffer dataBuffer,
 202:                     int w, int h,
 203:                     int scanlineStride,
 204:                     int[] bankIndices,
 205:                     int[] bandOffsets,
 206:                     Point location)
 207:   {
 208:     SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
 209:                        w, h, scanlineStride,
 210:                        bankIndices, bandOffsets);
 211:     return createWritableRaster(sm, dataBuffer, location);
 212:   }
 213:   
 214:   public static WritableRaster
 215:   createPackedRaster(DataBuffer dataBuffer,
 216:              int w, int h,
 217:              int scanlineStride,
 218:              int[] bandMasks,
 219:              Point location)
 220:  {
 221:     SampleModel sm =
 222:       new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
 223:                        w, h,
 224:                        scanlineStride,
 225:                        bandMasks);
 226:     return createWritableRaster(sm, dataBuffer, location);
 227:   }
 228:   
 229:   public static WritableRaster
 230:   createPackedRaster(DataBuffer dataBuffer,
 231:              int w, int h,
 232:              int bitsPerPixel,
 233:              Point location)
 234:   {
 235:     SampleModel sm =
 236:       new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
 237:                        w, h,
 238:                        bitsPerPixel);
 239:     return createWritableRaster(sm, dataBuffer, location);
 240:   }
 241:     
 242:   public static Raster createRaster(SampleModel sm, DataBuffer db,
 243:                     Point location)
 244:   {
 245:     return new Raster(sm, db, location);
 246:   }
 247: 
 248:   public static WritableRaster createWritableRaster(SampleModel sm,
 249:                             Point location)
 250:   {
 251:     return new WritableRaster(sm, location);
 252:   }
 253: 
 254:   public static WritableRaster createWritableRaster(SampleModel sm,
 255:                             DataBuffer db,
 256:                             Point location)
 257:   {
 258:     return new WritableRaster(sm, db, location);
 259:   }
 260: 
 261:   public Raster getParent()
 262:   {
 263:     return parent;
 264:   }
 265: 
 266:   public final int getSampleModelTranslateX()
 267:   {
 268:     return sampleModelTranslateX;
 269:   }
 270: 
 271:   public final int getSampleModelTranslateY()
 272:   {
 273:     return sampleModelTranslateY;
 274:   }
 275: 
 276:   public WritableRaster createCompatibleWritableRaster()
 277:   {
 278:     return new WritableRaster(getSampleModel(), new Point(minX, minY));
 279:   }
 280: 
 281:   public WritableRaster createCompatibleWritableRaster(int w, int h)
 282:   {
 283:     return createCompatibleWritableRaster(minX, minY, w, h);
 284:   }
 285: 
 286:   public WritableRaster createCompatibleWritableRaster(Rectangle rect)
 287:   {
 288:     return createCompatibleWritableRaster(rect.x, rect.y,
 289:                       rect.width, rect.height);
 290:   }
 291: 
 292:   public WritableRaster createCompatibleWritableRaster(int x, int y,
 293:                                int w, int h)
 294:   {
 295:     SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
 296:     return new WritableRaster(sm, sm.createDataBuffer(),
 297:                   new Point(x, y));
 298:   }
 299: 
 300:   public Raster createTranslatedChild(int childMinX, int childMinY) {
 301:     int tcx = sampleModelTranslateX - minX + childMinX;
 302:     int tcy = sampleModelTranslateY - minY + childMinY;
 303:     
 304:     return new Raster(sampleModel, dataBuffer,
 305:               new Rectangle(childMinX, childMinY,
 306:                     width, height),
 307:               new Point(tcx, tcy),
 308:               this);
 309:   }
 310: 
 311:   public Raster createChild(int parentX, int parentY, int width,
 312:                 int height, int childMinX, int childMinY,
 313:                 int[] bandList)
 314:   {
 315:     /* FIXME: Throw RasterFormatException if child bounds extends
 316:        beyond the bounds of this raster. */
 317: 
 318:     SampleModel sm = (bandList == null) ?
 319:       sampleModel :
 320:       sampleModel.createSubsetSampleModel(bandList);
 321: 
 322:     /*
 323:         data origin
 324:        /
 325:       +-------------------------
 326:       |\. __ parent trans
 327:       | \`.  
 328:       |  \ `.    parent origin
 329:       |   \  `. /
 330:       |   /\   +-------- - -
 331:       |trans\ /<\-- deltaTrans
 332:       |child +-+-\---- - - 
 333:       |     /|`|  \__ parent [x, y]
 334:       |child | |`. \
 335:       |origin| :  `.\
 336:       |      |    / `\
 337:       |      :   /    +
 338:       | child [x, y] 
 339: 
 340:       parent_xy - parent_trans = child_xy - child_trans
 341: 
 342:       child_trans = parent_trans + child_xy - parent_xy
 343:     */
 344: 
 345:     return new Raster(sm, dataBuffer,
 346:               new Rectangle(childMinX, childMinY,
 347:                     width, height),
 348:               new Point(sampleModelTranslateX+childMinX-parentX,
 349:                 sampleModelTranslateY+childMinY-parentY),
 350:               this);
 351:   }
 352: 
 353:   public Rectangle getBounds()
 354:   {
 355:     return new Rectangle(minX, minY, width, height);
 356:   }
 357: 
 358:   public final int getMinX()
 359:   {
 360:     return minX;
 361:   }
 362: 
 363:   public final int getMinY()
 364:   {
 365:     return minY;
 366:   }
 367: 
 368:   public final int getWidth()
 369:   {
 370:     return width;
 371:   }
 372: 
 373:   public final int getHeight()
 374:   {
 375:     return height;
 376:   }
 377: 
 378:   public final int getNumBands()
 379:   {
 380:     return numBands;
 381:   }
 382:     
 383:   public final int getNumDataElements()
 384:   {
 385:     return numDataElements;
 386:   }
 387:     
 388:   public final int getTransferType()
 389:   {
 390:     return sampleModel.getTransferType();
 391:   }
 392: 
 393:   public DataBuffer getDataBuffer()
 394:   {
 395:     return dataBuffer;
 396:   }
 397: 
 398:   public SampleModel getSampleModel()
 399:   {
 400:     return sampleModel;
 401:   }
 402: 
 403:   public Object getDataElements(int x, int y, Object outData)
 404:   {
 405:     return sampleModel.getDataElements(x-sampleModelTranslateX,
 406:                        y-sampleModelTranslateY,
 407:                        outData, dataBuffer);
 408:   }
 409: 
 410:   public Object getDataElements(int x, int y, int w, int h,
 411:                 Object outData)
 412:   {
 413:     return sampleModel.getDataElements(x-sampleModelTranslateX,
 414:                        y-sampleModelTranslateY,
 415:                        w, h, outData, dataBuffer);
 416:   }
 417: 
 418:   public int[] getPixel(int x, int y, int[] iArray)
 419:   {
 420:     return sampleModel.getPixel(x-sampleModelTranslateX,
 421:                 y-sampleModelTranslateY,
 422:                 iArray, dataBuffer);
 423:   }
 424: 
 425:   public float[] getPixel(int x, int y, float[] fArray)
 426:   {
 427:     return sampleModel.getPixel(x-sampleModelTranslateX,
 428:                 y-sampleModelTranslateY,
 429:                 fArray, dataBuffer);
 430:   }
 431: 
 432:   public double[] getPixel(int x, int y, double[] dArray)
 433:   {
 434:     return sampleModel.getPixel(x-sampleModelTranslateX,
 435:                 y-sampleModelTranslateY,
 436:                 dArray, dataBuffer);
 437:   }
 438: 
 439:   public int[] getPixels(int x, int y, int w, int h, int[] iArray)
 440:   {
 441:     return sampleModel.getPixels(x-sampleModelTranslateX,
 442:                  y-sampleModelTranslateY,
 443:                  w, h, iArray, dataBuffer);
 444:   }
 445: 
 446:   public float[] getPixels(int x, int y, int w, int h,
 447:                float[] fArray)
 448:   {
 449:     return sampleModel.getPixels(x-sampleModelTranslateX,
 450:                  y-sampleModelTranslateY,
 451:                  w, h, fArray, dataBuffer);
 452:   }
 453: 
 454:   public double[] getPixels(int x, int y, int w, int h,
 455:                 double[] dArray)
 456:   {
 457:     return sampleModel.getPixels(x-sampleModelTranslateX,
 458:                  y-sampleModelTranslateY,
 459:                  w, h, dArray, dataBuffer);
 460:   }
 461: 
 462:   public int getSample(int x, int y, int b)
 463:   {
 464:     return sampleModel.getSample(x-sampleModelTranslateX,
 465:                  y-sampleModelTranslateY,
 466:                  b, dataBuffer);
 467:   }
 468: 
 469:   public float getSampleFloat(int x, int y, int b)
 470:   {
 471:     return sampleModel.getSampleFloat(x-sampleModelTranslateX,
 472:                       y-sampleModelTranslateY,
 473:                       b, dataBuffer);
 474:   }
 475: 
 476:   public double getSampleDouble(int x, int y, int b)
 477:   {
 478:     return sampleModel.getSampleDouble(x-sampleModelTranslateX,
 479:                        y-sampleModelTranslateY,
 480:                        b, dataBuffer);
 481:   }
 482: 
 483:   public int[] getSamples(int x, int y, int w, int h, int b,
 484:               int[] iArray)
 485:   {
 486:     return sampleModel.getSamples(x-sampleModelTranslateX,
 487:                   y-sampleModelTranslateY,
 488:                   w, h, b, iArray, dataBuffer);
 489:   }
 490: 
 491:   public float[] getSamples(int x, int y, int w, int h, int b,
 492:                 float[] fArray)
 493:   {
 494:     return sampleModel.getSamples(x-sampleModelTranslateX,
 495:                   y-sampleModelTranslateY,
 496:                   w, h, b, fArray, dataBuffer);
 497:   }
 498: 
 499:   public double[] getSamples(int x, int y, int w, int h, int b,
 500:                  double[] dArray)
 501:   {
 502:     return sampleModel.getSamples(x-sampleModelTranslateX,
 503:                   y-sampleModelTranslateY,
 504:                   w, h, b, dArray, dataBuffer);
 505:   }
 506:   
 507:   /**
 508:    * Create a String representing the stat of this Raster.
 509:    * @return A String representing the stat of this Raster.
 510:    * @see java.lang.Object#toString()
 511:    */
 512:   public String toString()
 513:   {
 514:     StringBuffer result = new StringBuffer();
 515:     
 516:     result.append(getClass().getName());
 517:     result.append("[(");
 518:     result.append(minX).append(",").append(minY).append("), ");
 519:     result.append(width).append(" x ").append(height).append(",");
 520:     result.append(sampleModel).append(",");
 521:     result.append(dataBuffer);
 522:     result.append("]");
 523:     
 524:     return result.toString();
 525:   }
 526: 
 527:   // Map from datatype to bits
 528:   private static int getTypeBits(int dataType)
 529:   {
 530:     switch (dataType)
 531:       {
 532:       case DataBuffer.TYPE_BYTE:
 533:     return 8;
 534:       case DataBuffer.TYPE_USHORT:
 535:       case DataBuffer.TYPE_SHORT:
 536:     return 16;
 537:       case DataBuffer.TYPE_INT:
 538:       case DataBuffer.TYPE_FLOAT:
 539:     return 32;
 540:       case DataBuffer.TYPE_DOUBLE:
 541:     return 64;
 542:       default:
 543:     return 0;
 544:       }
 545:   }
 546: }