Source for java.awt.image.SampleModel

   1: /* Copyright (C) 2000, 2001, 2002, 2005, 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: package java.awt.image;
  38: 
  39: /**
  40:  * A <code>SampleModel</code> is used to access pixel data from a 
  41:  * {@link DataBuffer}.  This is used by the {@link Raster} class.
  42:  * 
  43:  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
  44:  */
  45: public abstract class SampleModel
  46: {
  47:   /** Width of image described. */
  48:   protected int width;
  49:   
  50:   /** Height of image described. */
  51:   protected int height;
  52:   
  53:   /** Number of bands in the image described.  Package-private here,
  54:       shadowed by ComponentSampleModel. */
  55:   protected int numBands;
  56: 
  57:   /** 
  58:    * The DataBuffer type that is used to store the data of the image
  59:    * described.
  60:    */
  61:   protected int dataType;
  62: 
  63:   /**
  64:    * Creates a new sample model with the specified attributes.
  65:    * 
  66:    * @param dataType  the data type (one of {@link DataBuffer#TYPE_BYTE},
  67:    *   {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_SHORT},
  68:    *   {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT}, 
  69:    *   {@link DataBuffer#TYPE_DOUBLE} or {@link DataBuffer#TYPE_UNDEFINED}).
  70:    * @param w  the width in pixels (must be greater than zero).
  71:    * @param h  the height in pixels (must be greater than zero).
  72:    * @param numBands  the number of bands (must be greater than zero).
  73:    * 
  74:    * @throws IllegalArgumentException if <code>dataType</code> is not one of 
  75:    *   the listed values.
  76:    * @throws IllegalArgumentException if <code>w</code> is less than or equal
  77:    *   to zero.
  78:    * @throws IllegalArgumentException if <code>h</code> is less than or equal 
  79:    *   to zero.
  80:    * @throws IllegalArgumentException if <code>w * h</code> is greater than
  81:    *   {@link Integer#MAX_VALUE}.
  82:    */
  83:   public SampleModel(int dataType, int w, int h, int numBands)
  84:   {
  85:     if (dataType != DataBuffer.TYPE_UNDEFINED)
  86:       if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_DOUBLE)
  87:         throw new IllegalArgumentException("Unrecognised 'dataType' argument.");
  88:     
  89:     if ((w <= 0) || (h <= 0)) 
  90:       throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
  91:           + (h <= 0 ? " height<=0" : " height is ok"));
  92:         
  93:     long area = (long) w * (long) h;
  94:     if (area > Integer.MAX_VALUE)
  95:       throw new IllegalArgumentException("w * h exceeds Integer.MAX_VALUE.");
  96: 
  97:     if (numBands <= 0)
  98:       throw new IllegalArgumentException("Requires numBands > 0.");
  99:       
 100:     this.dataType = dataType;
 101:     this.width = w;
 102:     this.height = h;
 103:     this.numBands = numBands;  
 104:   }
 105:   
 106:   /**
 107:    * Returns the width of the pixel data accessible via this 
 108:    * <code>SampleModel</code>.
 109:    * 
 110:    * @return The width.
 111:    * 
 112:    * @see #getHeight()
 113:    */
 114:   public final int getWidth()
 115:   {
 116:     return width;
 117:   }
 118: 
 119:   /**
 120:    * Returns the height of the pixel data accessible via this 
 121:    * <code>SampleModel</code>.
 122:    * 
 123:    * @return The height.
 124:    * 
 125:    * @see #getWidth()
 126:    */
 127:   public final int getHeight()
 128:   {
 129:     return height;
 130:   }
 131: 
 132:   /**
 133:    * Returns the number of bands for this <code>SampleModel</code>.
 134:    * 
 135:    * @return The number of bands.
 136:    */
 137:   public final int getNumBands()
 138:   {
 139:     return numBands;
 140:   }
 141:     
 142:   public abstract int getNumDataElements();
 143:   
 144:   /**
 145:    * Returns the type of the {@link DataBuffer} that this 
 146:    * <code>SampleModel</code> accesses.
 147:    * 
 148:    * @return The data buffer type.
 149:    */
 150:   public final int getDataType()
 151:   {
 152:     return dataType;
 153:   }
 154: 
 155:   public int getTransferType()
 156:   {
 157:     // FIXME: Is this a reasonable default implementation?
 158:     return dataType;
 159:   }
 160: 
 161:   /**
 162:    * Returns an array containing the samples for the pixel at (x, y) in the
 163:    * specified data buffer.  If <code>iArray</code> is not <code>null</code>,
 164:    * it will be populated with the sample values and returned as the result of
 165:    * this function (this avoids allocating a new array instance).
 166:    * 
 167:    * @param x  the x-coordinate of the pixel.
 168:    * @param y  the y-coordinate of the pixel.
 169:    * @param iArray  an array to populate with the sample values and return as 
 170:    *     the result (if <code>null</code>, a new array will be allocated).
 171:    * @param data  the data buffer (<code>null</code> not permitted).
 172:    * 
 173:    * @return The pixel sample values.
 174:    * 
 175:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 176:    */
 177:   public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
 178:   {
 179:     if (iArray == null) 
 180:       iArray = new int[numBands];
 181:     for (int b = 0; b < numBands; b++) 
 182:       iArray[b] = getSample(x, y, b, data);
 183:     return iArray;
 184:   }
 185:   
 186:   /**
 187:    *
 188:    * This method is provided as a faster alternative to getPixel(),
 189:    * that can be used when there is no need to decode the pixel into
 190:    * separate sample values.
 191:    *
 192:    * @param obj An array to return the pixel data in. If null, an
 193:    * array of the right type and size will be created.
 194:    *
 195:    * @return A single pixel as an array object of a primitive type,
 196:    * based on the transfer type. Eg. if transfer type is
 197:    * DataBuffer.TYPE_USHORT, then a short[] object is returned.
 198:    */
 199:   public abstract Object getDataElements(int x, int y, Object obj,
 200:                                          DataBuffer data);
 201: 
 202:     
 203:   public Object getDataElements(int x, int y, int w, int h, Object obj,
 204:                                 DataBuffer data)
 205:   {
 206:     int size = w * h;
 207:     int numDataElements = getNumDataElements();
 208:     int dataSize = numDataElements * size;
 209:     
 210:     if (obj == null)
 211:       {
 212:         switch (getTransferType())
 213:           {
 214:           case DataBuffer.TYPE_BYTE:
 215:             obj = new byte[dataSize];
 216:             break;
 217:           case DataBuffer.TYPE_USHORT:
 218:             obj = new short[dataSize];
 219:             break;
 220:           case DataBuffer.TYPE_INT:
 221:             obj = new int[dataSize];
 222:             break;
 223:           default:
 224:             // Seems like the only sensible thing to do.
 225:             throw new ClassCastException();
 226:           }
 227:       }
 228:     Object pixelData = null;
 229:     int outOffset = 0;
 230:     for (int yy = y; yy < (y + h); yy++)
 231:       {
 232:         for (int xx = x; xx < (x + w); xx++)
 233:           {
 234:             pixelData = getDataElements(xx, yy, pixelData, data);
 235:             System.arraycopy(pixelData, 0, obj, outOffset,
 236:                              numDataElements);
 237:             outOffset += numDataElements;
 238:           }
 239:       }
 240:     return obj;
 241:   }
 242: 
 243:   public abstract void setDataElements(int x, int y, Object obj,
 244:                                        DataBuffer data);
 245: 
 246:   public void setDataElements(int x, int y, int w, int h,
 247:                               Object obj, DataBuffer data)
 248:   {
 249:     int numDataElements = getNumDataElements();
 250:     
 251:     Object pixelData;
 252:     switch (getTransferType())
 253:       {
 254:       case DataBuffer.TYPE_BYTE:
 255:         pixelData = new byte[numDataElements];
 256:         break;
 257:       case DataBuffer.TYPE_USHORT:
 258:       case DataBuffer.TYPE_SHORT:
 259:         pixelData = new short[numDataElements];
 260:         break;
 261:       case DataBuffer.TYPE_INT:
 262:         pixelData = new int[numDataElements];
 263:         break;
 264:       case DataBuffer.TYPE_FLOAT:
 265:         pixelData = new float[numDataElements];
 266:         break;
 267:       case DataBuffer.TYPE_DOUBLE:
 268:         pixelData = new double[numDataElements];
 269:         break;
 270:       default:
 271:         // The RI silently igores invalid types.
 272:         pixelData = null;
 273:       }
 274: 
 275:     int inOffset = 0;
 276:     if (pixelData != null)
 277:       {
 278:         for (int yy=y; yy<(y+h); yy++)
 279:           {
 280:             for (int xx=x; xx<(x+w); xx++)
 281:               {
 282:                 System.arraycopy(obj, inOffset, pixelData, 0, numDataElements);
 283:                 setDataElements(xx, yy, pixelData, data);
 284:                 inOffset += numDataElements;
 285:               }
 286:           }
 287:       }
 288:   }
 289: 
 290:   /**
 291:    * Returns an array containing the samples for the pixel at (x, y) in the
 292:    * specified data buffer.  If <code>fArray</code> is not <code>null</code>,
 293:    * it will be populated with the sample values and returned as the result of
 294:    * this function (this avoids allocating a new array instance).
 295:    * 
 296:    * @param x  the x-coordinate of the pixel.
 297:    * @param y  the y-coordinate of the pixel.
 298:    * @param fArray  an array to populate with the sample values and return as 
 299:    *     the result (if <code>null</code>, a new array will be allocated).
 300:    * @param data  the data buffer (<code>null</code> not permitted).
 301:    * 
 302:    * @return The pixel sample values.
 303:    * 
 304:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 305:    */
 306:   public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
 307:   {
 308:     if (fArray == null) 
 309:       fArray = new float[numBands];
 310:     
 311:     for (int b = 0; b < numBands; b++)
 312:       {
 313:         fArray[b] = getSampleFloat(x, y, b, data);
 314:       }
 315:     return fArray;
 316:   }
 317: 
 318:   /**
 319:    * Returns an array containing the samples for the pixel at (x, y) in the
 320:    * specified data buffer.  If <code>dArray</code> is not <code>null</code>,
 321:    * it will be populated with the sample values and returned as the result of
 322:    * this function (this avoids allocating a new array instance).
 323:    * 
 324:    * @param x  the x-coordinate of the pixel.
 325:    * @param y  the y-coordinate of the pixel.
 326:    * @param dArray  an array to populate with the sample values and return as 
 327:    *     the result (if <code>null</code>, a new array will be allocated).
 328:    * @param data  the data buffer (<code>null</code> not permitted).
 329:    * 
 330:    * @return The pixel sample values.
 331:    * 
 332:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 333:    */
 334:   public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
 335:     if (dArray == null) 
 336:       dArray = new double[numBands];
 337:     for (int b = 0; b < numBands; b++)
 338:       {
 339:         dArray[b] = getSampleDouble(x, y, b, data);
 340:       }
 341:     return dArray;
 342:   }
 343: 
 344:   /**
 345:    * Returns an array containing the samples for the pixels in the region 
 346:    * specified by (x, y, w, h) in the specified data buffer.  The array is
 347:    * ordered by pixels (that is, all the samples for the first pixel are 
 348:    * grouped together, followed by all the samples for the second pixel, and so
 349:    * on).  If <code>iArray</code> is not <code>null</code>, it will be 
 350:    * populated with the sample values and returned as the result of this 
 351:    * function (this avoids allocating a new array instance).
 352:    * 
 353:    * @param x  the x-coordinate of the top-left pixel.
 354:    * @param y  the y-coordinate of the top-left pixel.
 355:    * @param w  the width of the region of pixels.
 356:    * @param h  the height of the region of pixels.
 357:    * @param iArray  an array to populate with the sample values and return as 
 358:    *     the result (if <code>null</code>, a new array will be allocated).
 359:    * @param data  the data buffer (<code>null</code> not permitted).
 360:    * 
 361:    * @return The pixel sample values.
 362:    * 
 363:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 364:    */
 365:   public int[] getPixels(int x, int y, int w, int h, int[] iArray,
 366:                          DataBuffer data)
 367:   {
 368:     int size = w * h;
 369:     int outOffset = 0;
 370:     int[] pixel = null;
 371:     if (iArray == null) 
 372:       iArray = new int[w * h * numBands];
 373:     for (int yy = y; yy < (y + h); yy++)
 374:       {
 375:         for (int xx = x; xx < (x + w); xx++)
 376:           {
 377:             pixel = getPixel(xx, yy, pixel, data);
 378:             System.arraycopy(pixel, 0, iArray, outOffset, numBands);
 379:             outOffset += numBands;
 380:           }
 381:       }
 382:     return iArray;
 383:   }
 384: 
 385:   /**
 386:    * Returns an array containing the samples for the pixels in the region 
 387:    * specified by (x, y, w, h) in the specified data buffer.  The array is
 388:    * ordered by pixels (that is, all the samples for the first pixel are 
 389:    * grouped together, followed by all the samples for the second pixel, and so
 390:    * on).  If <code>fArray</code> is not <code>null</code>, it will be 
 391:    * populated with the sample values and returned as the result of this 
 392:    * function (this avoids allocating a new array instance).
 393:    * 
 394:    * @param x  the x-coordinate of the top-left pixel.
 395:    * @param y  the y-coordinate of the top-left pixel.
 396:    * @param w  the width of the region of pixels.
 397:    * @param h  the height of the region of pixels.
 398:    * @param fArray  an array to populate with the sample values and return as 
 399:    *     the result (if <code>null</code>, a new array will be allocated).
 400:    * @param data  the data buffer (<code>null</code> not permitted).
 401:    * 
 402:    * @return The pixel sample values.
 403:    * 
 404:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 405:    */
 406:   public float[] getPixels(int x, int y, int w, int h, float[] fArray,
 407:                            DataBuffer data)
 408:   {
 409:     int size = w * h;
 410:     int outOffset = 0;
 411:     float[] pixel = null;
 412:     if (fArray == null) fArray = new float[w * h * numBands];
 413:     for (int yy = y; yy < (y + h); yy++)
 414:       {
 415:         for (int xx = x; xx < (x + w); xx++)
 416:           {
 417:             pixel = getPixel(xx, yy, pixel, data);
 418:             System.arraycopy(pixel, 0, fArray, outOffset, numBands);
 419:             outOffset += numBands;
 420:           }
 421:       }
 422:     return fArray;
 423:   }
 424:     
 425:   /**
 426:    * Returns an array containing the samples for the pixels in the region 
 427:    * specified by (x, y, w, h) in the specified data buffer.  The array is
 428:    * ordered by pixels (that is, all the samples for the first pixel are 
 429:    * grouped together, followed by all the samples for the second pixel, and so
 430:    * on).  If <code>dArray</code> is not <code>null</code>, it will be 
 431:    * populated with the sample values and returned as the result of this 
 432:    * function (this avoids allocating a new array instance).
 433:    * 
 434:    * @param x  the x-coordinate of the top-left pixel.
 435:    * @param y  the y-coordinate of the top-left pixel.
 436:    * @param w  the width of the region of pixels.
 437:    * @param h  the height of the region of pixels.
 438:    * @param dArray  an array to populate with the sample values and return as 
 439:    *     the result (if <code>null</code>, a new array will be allocated).
 440:    * @param data  the data buffer (<code>null</code> not permitted).
 441:    * 
 442:    * @return The pixel sample values.
 443:    * 
 444:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 445:    */
 446:   public double[] getPixels(int x, int y, int w, int h, double[] dArray,
 447:                             DataBuffer data)
 448:   {
 449:     int size = w * h;
 450:     int outOffset = 0;
 451:     double[] pixel = null;
 452:     if (dArray == null) 
 453:       dArray = new double[w * h * numBands];
 454:     for (int yy = y; yy < (y + h); yy++)
 455:       {
 456:         for (int xx = x; xx < (x + w); xx++)
 457:           {
 458:             pixel = getPixel(xx, yy, pixel, data);
 459:             System.arraycopy(pixel, 0, dArray, outOffset, numBands);
 460:             outOffset += numBands;
 461:           }
 462:       }
 463:     return dArray;
 464:   }
 465: 
 466:   /**
 467:    * Returns the sample value for the pixel at (x, y) in the specified data 
 468:    * buffer.
 469:    * 
 470:    * @param x  the x-coordinate of the pixel.
 471:    * @param y  the y-coordinate of the pixel.
 472:    * @param b  the band (in the range <code>0</code> to 
 473:    *     <code>getNumBands() - 1</code>).
 474:    * @param data  the data buffer (<code>null</code> not permitted).
 475:    * 
 476:    * @return The sample value.
 477:    * 
 478:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 479:    */
 480:   public abstract int getSample(int x, int y, int b, DataBuffer data);
 481: 
 482:   /**
 483:    * Returns the sample value for the pixel at (x, y) in the specified data 
 484:    * buffer.
 485:    * 
 486:    * @param x  the x-coordinate of the pixel.
 487:    * @param y  the y-coordinate of the pixel.
 488:    * @param b  the band (in the range <code>0</code> to 
 489:    *     <code>getNumBands() - 1</code>).
 490:    * @param data  the data buffer (<code>null</code> not permitted).
 491:    * 
 492:    * @return The sample value.
 493:    * 
 494:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 495:    * 
 496:    * @see #getSample(int, int, int, DataBuffer)
 497:    */
 498:   public float getSampleFloat(int x, int y, int b, DataBuffer data)
 499:   {
 500:     return getSample(x, y, b, data);
 501:   }
 502: 
 503:   /**
 504:    * Returns the sample value for the pixel at (x, y) in the specified data 
 505:    * buffer.
 506:    * 
 507:    * @param x  the x-coordinate of the pixel.
 508:    * @param y  the y-coordinate of the pixel.
 509:    * @param b  the band (in the range <code>0</code> to 
 510:    *     <code>getNumBands() - 1</code>).
 511:    * @param data  the data buffer (<code>null</code> not permitted).
 512:    * 
 513:    * @return The sample value.
 514:    * 
 515:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 516:    * 
 517:    * @see #getSample(int, int, int, DataBuffer)
 518:    */
 519:   public double getSampleDouble(int x, int y, int b, DataBuffer data)
 520:   {
 521:     return getSampleFloat(x, y, b, data);
 522:   }
 523: 
 524:   /**
 525:    * Returns an array containing the samples from one band for the pixels in 
 526:    * the region specified by (x, y, w, h) in the specified data buffer.  If 
 527:    * <code>iArray</code> is not <code>null</code>, it will be 
 528:    * populated with the sample values and returned as the result of this 
 529:    * function (this avoids allocating a new array instance).
 530:    * 
 531:    * @param x  the x-coordinate of the top-left pixel.
 532:    * @param y  the y-coordinate of the top-left pixel.
 533:    * @param w  the width of the region of pixels.
 534:    * @param h  the height of the region of pixels.
 535:    * @param b  the band (in the range <code>0</code> to 
 536:    *     </code>getNumBands() - 1</code>).
 537:    * @param iArray  an array to populate with the sample values and return as 
 538:    *     the result (if <code>null</code>, a new array will be allocated).
 539:    * @param data  the data buffer (<code>null</code> not permitted).
 540:    * 
 541:    * @return The sample values.
 542:    * 
 543:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 544:    */
 545:   public int[] getSamples(int x, int y, int w, int h, int b,
 546:                           int[] iArray, DataBuffer data)
 547:   {
 548:     int size = w * h;
 549:     int outOffset = 0;
 550:     if (iArray == null) 
 551:       iArray = new int[size];
 552:     for (int yy = y; yy < (y + h); yy++)
 553:       {
 554:         for (int xx = x; xx < (x + w); xx++)
 555:           {
 556:             iArray[outOffset++] = getSample(xx, yy, b, data);
 557:           }
 558:       }
 559:     return iArray;
 560:   }
 561: 
 562:   /**
 563:    * Returns an array containing the samples from one band for the pixels in 
 564:    * the region specified by (x, y, w, h) in the specified data buffer.  If 
 565:    * <code>fArray</code> is not <code>null</code>, it will be 
 566:    * populated with the sample values and returned as the result of this 
 567:    * function (this avoids allocating a new array instance).
 568:    * 
 569:    * @param x  the x-coordinate of the top-left pixel.
 570:    * @param y  the y-coordinate of the top-left pixel.
 571:    * @param w  the width of the region of pixels.
 572:    * @param h  the height of the region of pixels.
 573:    * @param b  the band (in the range <code>0</code> to 
 574:    *     </code>getNumBands() - 1</code>).
 575:    * @param fArray  an array to populate with the sample values and return as 
 576:    *     the result (if <code>null</code>, a new array will be allocated).
 577:    * @param data  the data buffer (<code>null</code> not permitted).
 578:    * 
 579:    * @return The sample values.
 580:    * 
 581:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 582:    */
 583:   public float[] getSamples(int x, int y, int w, int h, int b,
 584:                             float[] fArray, DataBuffer data)
 585:   {
 586:     int size = w * h;
 587:     int outOffset = 0;
 588:     if (fArray == null) 
 589:       fArray = new float[size];
 590:     for (int yy = y; yy < (y + h); yy++)
 591:       {
 592:         for (int xx = x; xx < (x + w); xx++)
 593:           {
 594:             fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
 595:           }
 596:       }
 597:     return fArray;
 598:   }
 599: 
 600:   /**
 601:    * Returns an array containing the samples from one band for the pixels in 
 602:    * the region specified by (x, y, w, h) in the specified data buffer.  If 
 603:    * <code>dArray</code> is not <code>null</code>, it will be 
 604:    * populated with the sample values and returned as the result of this 
 605:    * function (this avoids allocating a new array instance).
 606:    * 
 607:    * @param x  the x-coordinate of the top-left pixel.
 608:    * @param y  the y-coordinate of the top-left pixel.
 609:    * @param w  the width of the region of pixels.
 610:    * @param h  the height of the region of pixels.
 611:    * @param b  the band (in the range <code>0</code> to 
 612:    *     </code>getNumBands() - 1</code>).
 613:    * @param dArray  an array to populate with the sample values and return as 
 614:    *     the result (if <code>null</code>, a new array will be allocated).
 615:    * @param data  the data buffer (<code>null</code> not permitted).
 616:    * 
 617:    * @return The sample values.
 618:    * 
 619:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 620:    */
 621:   public double[] getSamples(int x, int y, int w, int h, int b,
 622:                              double[] dArray, DataBuffer data)
 623:   {
 624:     int size = w * h;
 625:     int outOffset = 0;
 626:     if (dArray == null) 
 627:       dArray = new double[size];
 628:     for (int yy = y; yy < (y + h); yy++)
 629:       {
 630:         for (int xx = x; xx < (x + w); xx++)
 631:           {
 632:             dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
 633:           }
 634:       }
 635:     return dArray;
 636:   }
 637:   
 638:   /**
 639:    * Sets the samples for the pixel at (x, y) in the specified data buffer to
 640:    * the specified values. 
 641:    * 
 642:    * @param x  the x-coordinate of the pixel.
 643:    * @param y  the y-coordinate of the pixel.
 644:    * @param iArray  the sample values (<code>null</code> not permitted).
 645:    * @param data  the data buffer (<code>null</code> not permitted).
 646:    * 
 647:    * @throws NullPointerException if either <code>iArray</code> or 
 648:    *     <code>data</code> is <code>null</code>.
 649:    */
 650:   public void setPixel(int x, int y, int[] iArray, DataBuffer data)
 651:   {
 652:     for (int b = 0; b < numBands; b++) 
 653:       setSample(x, y, b, iArray[b], data);
 654:   }
 655: 
 656:   /**
 657:    * Sets the samples for the pixel at (x, y) in the specified data buffer to
 658:    * the specified values. 
 659:    * 
 660:    * @param x  the x-coordinate of the pixel.
 661:    * @param y  the y-coordinate of the pixel.
 662:    * @param fArray  the sample values (<code>null</code> not permitted).
 663:    * @param data  the data buffer (<code>null</code> not permitted).
 664:    * 
 665:    * @throws NullPointerException if either <code>fArray</code> or 
 666:    *     <code>data</code> is <code>null</code>.
 667:    */
 668:   public void setPixel(int x, int y, float[] fArray, DataBuffer data)
 669:   {
 670:     for (int b = 0; b < numBands; b++) 
 671:       setSample(x, y, b, fArray[b], data);
 672:   }
 673: 
 674:   /**
 675:    * Sets the samples for the pixel at (x, y) in the specified data buffer to
 676:    * the specified values. 
 677:    * 
 678:    * @param x  the x-coordinate of the pixel.
 679:    * @param y  the y-coordinate of the pixel.
 680:    * @param dArray  the sample values (<code>null</code> not permitted).
 681:    * @param data  the data buffer (<code>null</code> not permitted).
 682:    * 
 683:    * @throws NullPointerException if either <code>dArray</code> or 
 684:    *     <code>data</code> is <code>null</code>.
 685:    */
 686:   public void setPixel(int x, int y, double[] dArray, DataBuffer data)
 687:   {
 688:     for (int b = 0; b < numBands; b++) 
 689:       setSample(x, y, b, dArray[b], data);
 690:   }
 691: 
 692:   /**
 693:    * Sets the sample values for the pixels in the region specified by 
 694:    * (x, y, w, h) in the specified data buffer.  The array is
 695:    * ordered by pixels (that is, all the samples for the first pixel are 
 696:    * grouped together, followed by all the samples for the second pixel, and so
 697:    * on). 
 698:    *  
 699:    * @param x  the x-coordinate of the top-left pixel.
 700:    * @param y  the y-coordinate of the top-left pixel.
 701:    * @param w  the width of the region of pixels.
 702:    * @param h  the height of the region of pixels.
 703:    * @param iArray  the pixel sample values (<code>null</code> not permitted).
 704:    * @param data  the data buffer (<code>null</code> not permitted).
 705:    * 
 706:    * @throws NullPointerException if either <code>iArray</code> or 
 707:    *     <code>data</code> is <code>null</code>.
 708:    */
 709:   public void setPixels(int x, int y, int w, int h, int[] iArray,
 710:                         DataBuffer data)
 711:   {
 712:     int inOffset = 0;
 713:     int[] pixel = new int[numBands];
 714:     for (int yy = y; yy < (y + h); yy++)
 715:       {
 716:         for (int xx = x; xx < (x + w); xx++)
 717:           {
 718:             System.arraycopy(iArray, inOffset, pixel, 0, numBands);
 719:             setPixel(xx, yy, pixel, data);
 720:             inOffset += numBands;
 721:           }
 722:       }
 723:   }
 724: 
 725:   /**
 726:    * Sets the sample values for the pixels in the region specified by 
 727:    * (x, y, w, h) in the specified data buffer.  The array is
 728:    * ordered by pixels (that is, all the samples for the first pixel are 
 729:    * grouped together, followed by all the samples for the second pixel, and so
 730:    * on). 
 731:    *  
 732:    * @param x  the x-coordinate of the top-left pixel.
 733:    * @param y  the y-coordinate of the top-left pixel.
 734:    * @param w  the width of the region of pixels.
 735:    * @param h  the height of the region of pixels.
 736:    * @param fArray  the pixel sample values (<code>null</code> not permitted).
 737:    * @param data  the data buffer (<code>null</code> not permitted).
 738:    * 
 739:    * @throws NullPointerException if either <code>fArray</code> or 
 740:    *     <code>data</code> is <code>null</code>.
 741:    */
 742:   public void setPixels(int x, int y, int w, int h, float[] fArray,
 743:                         DataBuffer data)
 744:   {
 745:     int inOffset = 0;
 746:     float[] pixel = new float[numBands];
 747:     for (int yy = y; yy < (y + h); yy++)
 748:       {
 749:         for (int xx = x; xx < (x + w); xx++)
 750:           {
 751:             System.arraycopy(fArray, inOffset, pixel, 0, numBands);
 752:             setPixel(xx, yy, pixel, data);
 753:             inOffset += numBands;
 754:           }
 755:       }
 756:   }
 757: 
 758:   /**
 759:    * Sets the sample values for the pixels in the region specified by 
 760:    * (x, y, w, h) in the specified data buffer.  The array is
 761:    * ordered by pixels (that is, all the samples for the first pixel are 
 762:    * grouped together, followed by all the samples for the second pixel, and so
 763:    * on). 
 764:    *  
 765:    * @param x  the x-coordinate of the top-left pixel.
 766:    * @param y  the y-coordinate of the top-left pixel.
 767:    * @param w  the width of the region of pixels.
 768:    * @param h  the height of the region of pixels.
 769:    * @param dArray  the pixel sample values (<code>null</code> not permitted).
 770:    * @param data  the data buffer (<code>null</code> not permitted).
 771:    * 
 772:    * @throws NullPointerException if either <code>dArray</code> or 
 773:    *     <code>data</code> is <code>null</code>.
 774:    */
 775:   public void setPixels(int x, int y, int w, int h, double[] dArray,
 776:                         DataBuffer data)
 777:   {
 778:     int inOffset = 0;
 779:     double[] pixel = new double[numBands];
 780:     for (int yy = y; yy < (y + h); yy++)
 781:       {
 782:         for (int xx = x; xx < (x + w); xx++)
 783:           {
 784:             System.arraycopy(dArray, inOffset, pixel, 0, numBands);
 785:             setPixel(xx, yy, pixel, data);
 786:             inOffset += numBands;
 787:           }
 788:       }
 789:   }
 790: 
 791:   /**
 792:    * Sets the sample value for a band for the pixel at (x, y) in the 
 793:    * specified data buffer. 
 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:    * @param s  the sample value.
 800:    * @param data  the data buffer (<code>null</code> not permitted).
 801:    * 
 802:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 803:    */
 804:   public abstract void setSample(int x, int y, int b, int s,
 805:                                  DataBuffer data);
 806: 
 807:   /**
 808:    * Sets the sample value for a band for the pixel at (x, y) in the 
 809:    * specified data buffer. 
 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:    * @param s  the sample value.
 816:    * @param data  the data buffer (<code>null</code> not permitted).
 817:    * 
 818:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 819:    */
 820:   public void setSample(int x, int y, int b, float s,
 821:                         DataBuffer data)
 822:   {
 823:     setSample(x, y, b, (int) s, data);
 824:   }
 825: 
 826:   /**
 827:    * Sets the sample value for a band for the pixel at (x, y) in the 
 828:    * specified data buffer. 
 829:    * 
 830:    * @param x  the x-coordinate of the pixel.
 831:    * @param y  the y-coordinate of the pixel.
 832:    * @param b  the band (in the range <code>0</code> to 
 833:    *     <code>getNumBands() - 1</code>).
 834:    * @param s  the sample value.
 835:    * @param data  the data buffer (<code>null</code> not permitted).
 836:    * 
 837:    * @throws NullPointerException if <code>data</code> is <code>null</code>.
 838:    */
 839:   public void setSample(int x, int y, int b, double s,
 840:                         DataBuffer data)
 841:   {
 842:     setSample(x, y, b, (float) s, data);
 843:   }
 844: 
 845:   /**
 846:    * Sets the sample values for one band for the pixels in the region 
 847:    * specified by (x, y, w, h) in the specified data buffer. 
 848:    * 
 849:    * @param x  the x-coordinate of the top-left pixel.
 850:    * @param y  the y-coordinate of the top-left pixel.
 851:    * @param w  the width of the region of pixels.
 852:    * @param h  the height of the region of pixels.
 853:    * @param b  the band (in the range <code>0</code> to 
 854:    *     </code>getNumBands() - 1</code>).
 855:    * @param iArray  the sample values (<code>null</code> not permitted).
 856:    * @param data  the data buffer (<code>null</code> not permitted).
 857:    * 
 858:    * @throws NullPointerException if either <code>iArray</code> or 
 859:    *     <code>data</code> is <code>null</code>.
 860:    */
 861:   public void setSamples(int x, int y, int w, int h, int b,
 862:                          int[] iArray, DataBuffer data)
 863:   {
 864:     int size = w * h;
 865:     int inOffset = 0;
 866:     for (int yy = y; yy < (y + h); yy++)
 867:       for (int xx = x; xx < (x + w); xx++)
 868:         setSample(xx, yy, b, iArray[inOffset++], data);
 869:   }
 870: 
 871:   /**
 872:    * Sets the sample values for one band for the pixels in the region 
 873:    * specified by (x, y, w, h) in the specified data buffer. 
 874:    * 
 875:    * @param x  the x-coordinate of the top-left pixel.
 876:    * @param y  the y-coordinate of the top-left pixel.
 877:    * @param w  the width of the region of pixels.
 878:    * @param h  the height of the region of pixels.
 879:    * @param b  the band (in the range <code>0</code> to 
 880:    *     </code>getNumBands() - 1</code>).
 881:    * @param fArray  the sample values (<code>null</code> not permitted).
 882:    * @param data  the data buffer (<code>null</code> not permitted).
 883:    * 
 884:    * @throws NullPointerException if either <code>iArray</code> or 
 885:    *     <code>data</code> is <code>null</code>.
 886:    */
 887:   public void setSamples(int x, int y, int w, int h, int b,
 888:                          float[] fArray, DataBuffer data)
 889:   {
 890:     int size = w * h;
 891:     int inOffset = 0;
 892:     for (int yy = y; yy < (y + h); yy++)
 893:       for (int xx = x; xx < (x + w); xx++)
 894:         setSample(xx, yy, b, fArray[inOffset++], data);
 895: 
 896:   }
 897: 
 898:   /**
 899:    * Sets the sample values for one band for the pixels in the region 
 900:    * specified by (x, y, w, h) in the specified data buffer. 
 901:    * 
 902:    * @param x  the x-coordinate of the top-left pixel.
 903:    * @param y  the y-coordinate of the top-left pixel.
 904:    * @param w  the width of the region of pixels.
 905:    * @param h  the height of the region of pixels.
 906:    * @param b  the band (in the range <code>0</code> to 
 907:    *     </code>getNumBands() - 1</code>).
 908:    * @param dArray  the sample values (<code>null</code> not permitted).
 909:    * @param data  the data buffer (<code>null</code> not permitted).
 910:    * 
 911:    * @throws NullPointerException if either <code>iArray</code> or 
 912:    *     <code>data</code> is <code>null</code>.
 913:    */
 914:   public void setSamples(int x, int y, int w, int h, int b,
 915:                          double[] dArray, DataBuffer data) {
 916:     int size = w * h;
 917:     int inOffset = 0;
 918:     for (int yy = y; yy < (y + h); yy++)
 919:       for (int xx = x; xx < (x + w); xx++)
 920:         setSample(xx, yy, b, dArray[inOffset++], data);
 921:   }
 922: 
 923:   /**
 924:    * Creates a new <code>SampleModel</code> that is compatible with this
 925:    * model and has the specified width and height.
 926:    * 
 927:    * @param w  the width (in pixels).
 928:    * @param h  the height (in pixels).
 929:    * 
 930:    * @return The new sample model.
 931:    */
 932:   public abstract SampleModel createCompatibleSampleModel(int w, int h);
 933: 
 934:   /**
 935:    * Return a SampleModel with a subset of the bands in this model.
 936:    * 
 937:    * Selects bands.length bands from this sample model.  The bands chosen
 938:    * are specified in the indices of bands[].  This also permits permuting
 939:    * the bands as well as taking a subset.  Thus, giving an array with
 940:    * 1, 2, 3, ..., numbands, will give an identical sample model.
 941:    * 
 942:    * @param bands Array with band indices to include.
 943:    * @return A new sample model
 944:    */
 945:   public abstract SampleModel createSubsetSampleModel(int[] bands);
 946: 
 947:   /**
 948:    * Creates a new {@link DataBuffer} of the correct type and size for this 
 949:    * <code>SampleModel</code>.
 950:    * 
 951:    * @return The data buffer.
 952:    */
 953:   public abstract DataBuffer createDataBuffer();
 954: 
 955:   /**
 956:    * Returns an array containing the size (in bits) for each band accessed by
 957:    * the <code>SampleModel</code>.
 958:    * 
 959:    * @return An array.
 960:    * 
 961:    * @see #getSampleSize(int)
 962:    */
 963:   public abstract int[] getSampleSize();
 964: 
 965:   /**
 966:    * Returns the size (in bits) of the samples for the specified band.
 967:    * 
 968:    * @param band  the band (in the range <code>0</code> to 
 969:    *     <code>getNumBands() - 1</code>).
 970:    *     
 971:    * @return The sample size (in bits).
 972:    */
 973:   public abstract int getSampleSize(int band);
 974: }