Source for java.awt.image.SampleModel

   1: /* Copyright (C) 2000, 2001, 2002, 2005  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:  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
  41:  */
  42: public abstract class SampleModel
  43: {
  44:   /** Width of image described. */
  45:   protected int width;
  46:   
  47:   /** Height of image described. */
  48:   protected int height;
  49:   
  50:   /** Number of bands in the image described. */
  51:   protected int numBands;
  52: 
  53:   /** 
  54:    * The DataBuffer type that is used to store the data of the image
  55:    * described.
  56:    */
  57:   protected int dataType;
  58: 
  59:   public SampleModel(int dataType, int w, int h, int numBands)
  60:   {
  61:     if ((w <= 0) || (h <= 0)) 
  62:       throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
  63:                                          +(h <= 0 ? " height<=0" : " height is ok"));
  64:     
  65:     // FIXME: How can an int be greater than Integer.MAX_VALUE?
  66:     // FIXME: How do we identify an unsupported data type?
  67: 
  68:     this.dataType = dataType;
  69:     this.width = w;
  70:     this.height = h;
  71:     this.numBands = numBands;  
  72:   }
  73:   
  74:   public final int getWidth()
  75:   {
  76:     return width;
  77:   }
  78: 
  79:   public final int getHeight()
  80:   {
  81:     return height;
  82:   }
  83: 
  84:   public final int getNumBands()
  85:   {
  86:     return numBands;
  87:   }
  88:     
  89:   public abstract int getNumDataElements();
  90:   
  91:   public final int getDataType()
  92:   {
  93:     return dataType;
  94:   }
  95: 
  96:   public int getTransferType()
  97:   {
  98:     // FIXME: Is this a reasonable default implementation?
  99:     return dataType;
 100:   }
 101: 
 102:   public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
 103:   {
 104:     if (iArray == null) iArray = new int[numBands];
 105:     for (int b=0; b<numBands; b++) iArray[b] = getSample(x, y, b, data);
 106:     return iArray;
 107:   }
 108:   
 109:   /**
 110:    *
 111:    * This method is provided as a faster alternative to getPixel(),
 112:    * that can be used when there is no need to decode the pixel into
 113:    * separate sample values.
 114:    *
 115:    * @param obj An array to return the pixel data in. If null, an
 116:    * array of the right type and size will be created.
 117:    *
 118:    * @return A single pixel as an array object of a primitive type,
 119:    * based on the transfer type. Eg. if transfer type is
 120:    * DataBuffer.TYPE_USHORT, then a short[] object is returned.
 121:    */
 122:   public abstract Object getDataElements(int x, int y, Object obj,
 123:                      DataBuffer data);
 124: 
 125:     
 126:   public Object getDataElements(int x, int y, int w, int h, Object obj,
 127:                 DataBuffer data)
 128:   {
 129:     int size = w*h;
 130:     int numDataElements = getNumDataElements();
 131:     int dataSize = numDataElements*size;
 132:     
 133:     if (obj == null)
 134:       {
 135:     switch (getTransferType())
 136:       {
 137:       case DataBuffer.TYPE_BYTE:
 138:         obj = new byte[dataSize];
 139:         break;
 140:       case DataBuffer.TYPE_USHORT:
 141:         obj = new short[dataSize];
 142:         break;
 143:       case DataBuffer.TYPE_INT:
 144:         obj = new int[dataSize];
 145:         break;
 146:       default:
 147:         // Seems like the only sensible thing to do.
 148:         throw new ClassCastException();
 149:       }
 150:       }
 151:     Object pixelData = null;
 152:     int outOffset = 0;
 153:     for (int yy = y; yy<(y+h); yy++)
 154:       {
 155:     for (int xx = x; xx<(x+w); xx++)
 156:       {
 157:         pixelData = getDataElements(xx, yy, pixelData, data);
 158:         System.arraycopy(pixelData, 0, obj, outOffset,
 159:                  numDataElements);
 160:         outOffset += numDataElements;
 161:       }
 162:       }
 163:     return obj;
 164:   }
 165: 
 166:   public abstract void setDataElements(int x, int y, Object obj,
 167:                        DataBuffer data);
 168: 
 169:   public void setDataElements(int x, int y, int w, int h,
 170:                   Object obj, DataBuffer data)
 171:   {
 172:     int size = w*h;
 173:     int numDataElements = getNumDataElements();
 174:     int dataSize = numDataElements*size;
 175:     
 176:     Object pixelData;
 177:     switch (getTransferType())
 178:       {
 179:       case DataBuffer.TYPE_BYTE:
 180:     pixelData = new byte[numDataElements];
 181:     break;
 182:       case DataBuffer.TYPE_USHORT:
 183:     pixelData = new short[numDataElements];
 184:     break;
 185:       case DataBuffer.TYPE_INT:
 186:     pixelData = new int[numDataElements];
 187:     break;
 188:       default:
 189:     // Seems like the only sensible thing to do.
 190:     throw new ClassCastException();
 191:       }
 192:     int inOffset = 0;
 193: 
 194:     for (int yy=y; yy<(y+h); yy++)
 195:       {
 196:     for (int xx=x; xx<(x+w); xx++)
 197:       {
 198:         System.arraycopy(obj, inOffset, pixelData, 0,
 199:                  numDataElements);
 200:         setDataElements(xx, yy, pixelData, data);
 201:         inOffset += numDataElements;
 202:       }
 203:       }
 204:   }
 205: 
 206:   public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
 207:   {
 208:     if (fArray == null) fArray = new float[numBands];
 209:     
 210:     for (int b=0; b<numBands; b++)
 211:       {
 212:         fArray[b] = getSampleFloat(x, y, b, data);
 213:       }
 214:     return fArray;
 215:   }
 216: 
 217:   public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
 218:     if (dArray == null) dArray = new double[numBands];
 219:     for (int b=0; b<numBands; b++)
 220:       {
 221:     dArray[b] = getSampleDouble(x, y, b, data);
 222:       }
 223:     return dArray;
 224:   }
 225: 
 226:   /* FIXME: Should it return a banded or pixel interleaved array of
 227:      samples? (Assume interleaved.) */
 228:   public int[] getPixels(int x, int y, int w, int h, int[] iArray,
 229:              DataBuffer data)
 230:   {
 231:     int size = w*h;
 232:     int outOffset = 0;
 233:     int[] pixel = null;
 234:     if (iArray == null) iArray = new int[w*h*numBands];
 235:     for (int yy=y; yy<(y+h); yy++)
 236:       {
 237:     for (int xx=x; xx<(x+w); xx++)
 238:       {
 239:         pixel = getPixel(xx, yy, pixel, data);
 240:         System.arraycopy(pixel, 0, iArray, outOffset, numBands);
 241:         outOffset += numBands;
 242:       }
 243:       }
 244:     return iArray;
 245:   }
 246: 
 247:   /* FIXME: Should it return a banded or pixel interleaved array of
 248:      samples? (Assume interleaved.) */
 249:   public float[] getPixels(int x, int y, int w, int h, float[] fArray,
 250:                DataBuffer data)
 251:   {
 252:     int size = w*h;
 253:     int outOffset = 0;
 254:     float[] pixel = null;
 255:     if (fArray == null) fArray = new float[w*h*numBands];
 256:     for (int yy=y; yy<(y+h); yy++)
 257:       {
 258:     for (int xx=x; xx<(x+w); xx++)
 259:       {
 260:         pixel = getPixel(xx, yy, pixel, data);
 261:         System.arraycopy(pixel, 0, fArray, outOffset, numBands);
 262:         outOffset += numBands;
 263:       }
 264:       }
 265:     return fArray;
 266:   }
 267:     
 268:   /* FIXME: Should it return a banded or pixel interleaved array of
 269:      samples? (Assume interleaved.) */
 270:   public double[] getPixels(int x, int y, int w, int h, double[] dArray,
 271:                 DataBuffer data)
 272:   {
 273:     int size = w*h;
 274:     int outOffset = 0;
 275:     double[] pixel = null;
 276:     if (dArray == null) dArray = new double[w*h*numBands];
 277:     for (int yy=y; yy<(y+h); yy++)
 278:       {
 279:     for (int xx=x; xx<(x+w); xx++)
 280:       {
 281:         pixel = getPixel(xx, yy, pixel, data);
 282:         System.arraycopy(pixel, 0, dArray, outOffset, numBands);
 283:         outOffset += numBands;
 284:       }
 285:       }
 286:     return dArray;
 287:   }
 288: 
 289:   public abstract int getSample(int x, int y, int b, DataBuffer data);
 290: 
 291:   public float getSampleFloat(int x, int y, int b, DataBuffer data)
 292:   {
 293:     return getSample(x, y, b, data);
 294:   }
 295: 
 296:   public double getSampleDouble(int x, int y, int b, DataBuffer data)
 297:   {
 298:     return getSampleFloat(x, y, b, data);
 299:   }
 300: 
 301:   public int[] getSamples(int x, int y, int w, int h, int b,
 302:               int[] iArray, DataBuffer data)
 303:   {
 304:     int size = w*h;
 305:     int outOffset = 0;
 306:     if (iArray == null) iArray = new int[size];
 307:     for (int yy=y; yy<(y+h); yy++)
 308:       {
 309:     for (int xx=x; xx<(x+w); xx++)
 310:       {
 311:         iArray[outOffset++] = getSample(xx, yy, b, data);
 312:       }
 313:       }
 314:     return iArray;
 315:   }
 316: 
 317:   public float[] getSamples(int x, int y, int w, int h, int b,
 318:                 float[] fArray, DataBuffer data)
 319:   {
 320:     int size = w*h;
 321:     int outOffset = 0;
 322:     if (fArray == null) fArray = new float[size];
 323:     for (int yy=y; yy<(y+h); yy++)
 324:       {
 325:     for (int xx=x; xx<(x+w); xx++)
 326:       {
 327:         fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
 328:       }
 329:       }
 330:     return fArray;
 331:   }
 332: 
 333:   public double[] getSamples(int x, int y, int w, int h, int b,
 334:                  double[] dArray, DataBuffer data)
 335:   {
 336:     int size = w*h;
 337:     int outOffset = 0;
 338:     if (dArray == null) dArray = new double[size];
 339:     for (int yy=y; yy<(y+h); yy++)
 340:       {
 341:     for (int xx=x; xx<(x+w); xx++)
 342:       {
 343:         dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
 344:       }
 345:       }
 346:     return dArray;
 347:   }
 348:   
 349:   public void setPixel(int x, int y, int[] iArray, DataBuffer data)
 350:   {
 351:     for (int b=0; b<numBands; b++) setSample(x, y, b, iArray[b], data);
 352:   }
 353: 
 354:   public void setPixel(int x, int y, float[] fArray, DataBuffer data)
 355:   {
 356:     for (int b=0; b<numBands; b++) setSample(x, y, b, fArray[b], data);
 357:   }
 358: 
 359:   public void setPixel(int x, int y, double[] dArray, DataBuffer data)
 360:   {
 361:     for (int b=0; b<numBands; b++) setSample(x, y, b, dArray[b], data);
 362:   }
 363: 
 364:   public void setPixels(int x, int y, int w, int h, int[] iArray,
 365:             DataBuffer data)
 366:   {
 367:     int inOffset = 0;
 368:     int[] pixel = new int[numBands];
 369:     for (int yy=y; yy<(y+h); yy++)
 370:       {
 371:     for (int xx=x; xx<(x+w); xx++)
 372:       {
 373:         System.arraycopy(iArray, inOffset, pixel, 0, numBands);
 374:         setPixel(xx, yy, pixel, data);
 375:         inOffset += numBands;
 376:       }
 377:       }
 378:   }
 379: 
 380:   public void setPixels(int x, int y, int w, int h, float[] fArray,
 381:             DataBuffer data)
 382:   {
 383:     int inOffset = 0;
 384:     float[] pixel = new float[numBands];
 385:     for (int yy=y; yy<(y+h); yy++)
 386:       {
 387:     for (int xx=x; xx<(x+w); xx++)
 388:       {
 389:         System.arraycopy(fArray, inOffset, pixel, 0, numBands);
 390:         setPixel(xx, yy, pixel, data);
 391:         inOffset += numBands;
 392:       }
 393:       }
 394:   }
 395: 
 396:   public void setPixels(int x, int y, int w, int h, double[] dArray,
 397:             DataBuffer data)
 398:   {
 399:     int inOffset = 0;
 400:     double[] pixel = new double[numBands];
 401:     for (int yy=y; yy<(y+h); yy++)
 402:       {
 403:     for (int xx=x; xx<(x+w); xx++)
 404:       {
 405:         System.arraycopy(dArray, inOffset, pixel, 0, numBands);
 406:         setPixel(xx, yy, pixel, data);
 407:         inOffset += numBands;
 408:       }
 409:       }
 410:   }
 411: 
 412:   public abstract void setSample(int x, int y, int b, int s,
 413:                  DataBuffer data);
 414: 
 415:   public void setSample(int x, int y, int b, float s,
 416:             DataBuffer data)
 417:   {
 418:     setSample(x, y, b, (int) s, data);
 419:   }
 420: 
 421:   public void setSample(int x, int y, int b, double s,
 422:             DataBuffer data)
 423:   {
 424:     setSample(x, y, b, (float) s, data);
 425:   }
 426: 
 427:   public void setSamples(int x, int y, int w, int h, int b,
 428:              int[] iArray, DataBuffer data)
 429:   {
 430:     int size = w*h;
 431:     int inOffset = 0;
 432:     for (int yy=y; yy<(y+h); yy++)
 433:       for (int xx=x; xx<(x+w); xx++)
 434:     setSample(xx, yy, b, iArray[inOffset++], data);
 435:   }
 436: 
 437:   public void setSamples(int x, int y, int w, int h, int b,
 438:              float[] fArray, DataBuffer data)
 439:   {
 440:     int size = w*h;
 441:     int inOffset = 0;
 442:     for (int yy=y; yy<(y+h); yy++)
 443:       for (int xx=x; xx<(x+w); xx++)
 444:     setSample(xx, yy, b, fArray[inOffset++], data);
 445: 
 446:     }
 447: 
 448:     public void setSamples(int x, int y, int w, int h, int b,
 449:                double[] dArray, DataBuffer data) {
 450:       int size = w*h;
 451:       int inOffset = 0;
 452:       for (int yy=y; yy<(y+h); yy++)
 453:     for (int xx=x; xx<(x+w); xx++)
 454:       setSample(xx, yy, b, dArray[inOffset++], data);
 455:     }
 456: 
 457:     public abstract SampleModel createCompatibleSampleModel(int w, int h);
 458: 
 459:     /**
 460:      * Return a SampleModel with a subset of the bands in this model.
 461:      * 
 462:      * Selects bands.length bands from this sample model.  The bands chosen
 463:      * are specified in the indices of bands[].  This also permits permuting
 464:      * the bands as well as taking a subset.  Thus, giving an array with
 465:      * 1, 2, 3, ..., numbands, will give an identical sample model.
 466:      * 
 467:      * @param bands Array with band indices to include.
 468:      * @return A new sample model
 469:      */
 470:     public abstract SampleModel createSubsetSampleModel(int[] bands);
 471: 
 472:     public abstract DataBuffer createDataBuffer();
 473: 
 474:     public abstract int[] getSampleSize();
 475: 
 476:     public abstract int getSampleSize(int band);
 477: }