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