Changeset 3257


Ignore:
Timestamp:
10/10/07 17:26:11 (12 years ago)
Author:
curtis
Message:

Standardize getPixels methods to use a single sample model checker
method for deciding whether to return the bank data directly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/ImageTools.java

    r3254 r3257  
    407407    ColorModel colorModel = makeColorModel(c, type); 
    408408    if (colorModel == null) return null; 
    409     int pixelStride = interleaved ? c : 1; 
    410     int scanlineStride = interleaved ? (c * w) : w; 
    411     if (c == 2) c++; 
    412     int[] bandOffsets = new int[c]; 
    413     for (int i=0; i<c; i++) bandOffsets[i] = interleaved ? i : (i * w * h); 
    414  
    415     SampleModel model = new ComponentSampleModel(type, w, h, pixelStride, 
    416       scanlineStride, bandOffsets); 
     409 
     410    SampleModel model; 
     411    if (interleaved) { 
     412      int[] bandOffsets = new int[c]; 
     413      for (int i=0; i<c; i++) bandOffsets[i] = i; 
     414      model = new PixelInterleavedSampleModel(type, 
     415        w, h, c, c * w, bandOffsets); 
     416    } 
     417    else model = new BandedSampleModel(type, w, h, c); 
    417418 
    418419    WritableRaster raster = Raster.createWritableRaster(model, buffer, null); 
     
    440441  /** Extracts pixel data as arrays of unsigned bytes, one per channel. */ 
    441442  public static byte[][] getBytes(BufferedImage image) { 
    442     int dataType = DataBuffer.TYPE_BYTE; 
    443443    WritableRaster r = image.getRaster(); 
    444     if (r.getTransferType() == dataType) { 
    445       DataBuffer buffer = r.getDataBuffer(); 
    446       if (buffer instanceof DataBufferByte) { 
    447         SampleModel model = r.getSampleModel(); 
    448         // NB: Could implement additional checks for ComponentSampleModel 
    449         // with particular characteristics to also use this shortcut. 
    450         if (model instanceof BandedSampleModel) { 
    451           // return bytes directly, with no copy 
    452           return ((DataBufferByte) buffer).getBankData(); 
    453         } 
    454       } 
     444    if (canUseBankDataDirectly(image, 1, 
     445      DataBuffer.TYPE_BYTE, DataBufferByte.class)) 
     446    { 
     447      return ((DataBufferByte) r.getDataBuffer()).getBankData(); 
    455448    } 
    456449    //return getBytes(makeType(image, dataType)); 
     
    468461  public static short[][] getShorts(BufferedImage image) { 
    469462    WritableRaster r = image.getRaster(); 
    470     if (r.getTransferType() == DataBuffer.TYPE_USHORT) { 
    471       DataBuffer buffer = r.getDataBuffer(); 
    472       if (buffer instanceof DataBufferUShort) { 
    473         SampleModel model = r.getSampleModel(); 
    474         // NB: Could implement additional checks for ComponentSampleModel 
    475         // with particular characteristics to also use this shortcut. 
    476         if (model instanceof BandedSampleModel) { 
    477           // return shorts directly, with no copy 
    478           return ((DataBufferUShort) buffer).getBankData(); 
    479         } 
    480       } 
     463    if (canUseBankDataDirectly(image, 2, 
     464      DataBuffer.TYPE_USHORT, DataBufferUShort.class)) 
     465    { 
     466      return ((DataBufferUShort) r.getDataBuffer()).getBankData(); 
    481467    } 
    482468    //return getShorts(makeType(image, DataBuffer.TYPE_USHORT)); 
     
    494480  public static int[][] getInts(BufferedImage image) { 
    495481    WritableRaster r = image.getRaster(); 
    496     int tt = r.getTransferType(); 
    497     if (tt == DataBuffer.TYPE_INT) { 
    498       DataBuffer buffer = r.getDataBuffer(); 
    499       if (buffer instanceof DataBufferInt) { 
    500         SampleModel model = r.getSampleModel(); 
    501         // NB: Could implement additional checks for ComponentSampleModel 
    502         // with particular characteristics to also use this shortcut. 
    503         if (model instanceof BandedSampleModel) { 
    504           // return ints directly, with no copy 
    505           return ((DataBufferInt) buffer).getBankData(); 
    506         } 
    507       } 
     482    if (canUseBankDataDirectly(image, 4, 
     483      DataBuffer.TYPE_INT, DataBufferInt.class)) 
     484    { 
     485      return ((DataBufferInt) r.getDataBuffer()).getBankData(); 
    508486    } 
    509487    // NB: an order of magnitude faster than the naive makeType solution 
     
    517495  public static float[][] getFloats(BufferedImage image) { 
    518496    WritableRaster r = image.getRaster(); 
    519     int tt = r.getTransferType(); 
    520     if (tt == DataBuffer.TYPE_FLOAT) { 
    521       DataBuffer buffer = r.getDataBuffer(); 
    522       if (buffer instanceof DataBufferFloat) { 
    523         SampleModel model = r.getSampleModel(); 
    524         // NB: Could implement additional checks for ComponentSampleModel 
    525         // with particular characteristics to also use this shortcut. 
    526         if (model instanceof BandedSampleModel) { 
    527           // return floats directly, with no copy 
    528           return ((DataBufferFloat) buffer).getBankData(); 
    529         } 
    530       } 
     497    if (canUseBankDataDirectly(image, 4, 
     498      DataBuffer.TYPE_FLOAT, DataBufferFloat.class)) 
     499    { 
     500      return ((DataBufferFloat) r.getDataBuffer()).getBankData(); 
    531501    } 
    532502    // NB: an order of magnitude faster than the naive makeType solution 
     
    540510  public static double[][] getDoubles(BufferedImage image) { 
    541511    WritableRaster r = image.getRaster(); 
    542     int tt = r.getTransferType(); 
    543     if (tt == DataBuffer.TYPE_DOUBLE) { 
    544       DataBuffer buffer = r.getDataBuffer(); 
    545       if (buffer instanceof DataBufferDouble) { 
    546         SampleModel model = r.getSampleModel(); 
    547         // NB: Could implement additional checks for ComponentSampleModel 
    548         // with particular characteristics to also use this shortcut. 
    549         if (model instanceof BandedSampleModel) { 
    550           // return doubles directly, with no copy 
    551           return ((DataBufferDouble) buffer).getBankData(); 
    552         } 
    553       } 
     512    if (canUseBankDataDirectly(image, 8, 
     513      DataBuffer.TYPE_DOUBLE, DataBufferDouble.class)) 
     514    { 
     515      return ((DataBufferDouble) r.getDataBuffer()).getBankData(); 
    554516    } 
    555517    // NB: an order of magnitude faster than the naive makeType solution 
     
    558520    for (int i=0; i<c; i++) r.getSamples(0, 0, w, h, i, samples[i]); 
    559521    return samples; 
     522  } 
     523 
     524  /** 
     525   * Whether we can return the data buffer's bank data 
     526   * without performing any copy or conversion operations. 
     527   */ 
     528  private static boolean canUseBankDataDirectly(BufferedImage image, 
     529    int bytesPerPixel, int transferType, Class dataBufferClass) 
     530  { 
     531    WritableRaster r = image.getRaster(); 
     532    int tt = r.getTransferType(); 
     533    if (tt != transferType) return false; 
     534    DataBuffer buffer = r.getDataBuffer(); 
     535    if (!dataBufferClass.isInstance(buffer)) return false; 
     536    SampleModel model = r.getSampleModel(); 
     537    if (!(model instanceof ComponentSampleModel)) return false; 
     538    ComponentSampleModel csm = (ComponentSampleModel) model; 
     539    int pixelStride = csm.getPixelStride(); 
     540    if (pixelStride != 1) return false; 
     541    int w = r.getWidth(); 
     542    int scanlineStride = csm.getScanlineStride(); 
     543    if (scanlineStride != w) return false; 
     544    int c = r.getNumBands(); 
     545    int[] bandOffsets = csm.getBandOffsets(); 
     546    if (bandOffsets.length != c) return false; 
     547    for (int i=0; i<bandOffsets.length; i++) { 
     548      if (bandOffsets[i] != 0) return false; 
     549    } 
     550    int[] bankIndices = csm.getBankIndices(); 
     551    for (int i=0; i<bandOffsets.length; i++) { 
     552      if (bandOffsets[i] != i) return false; 
     553    } 
     554    return true; 
    560555  } 
    561556 
Note: See TracChangeset for help on using the changeset viewer.