Changeset 3254


Ignore:
Timestamp:
10/10/07 15:09:41 (12 years ago)
Author:
curtis
Message:

Fix getPixels implementations to never use makeType, and get rid of makeType,
since it is broken. As for WHY it is broken, I left it in the source,
commented out, in case we want to explore things further later on.

File:
1 edited

Legend:

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

    r3253 r3254  
    442442    int dataType = DataBuffer.TYPE_BYTE; 
    443443    WritableRaster r = image.getRaster(); 
    444     int tt = r.getTransferType(); 
    445     if (tt == dataType) { 
     444    if (r.getTransferType() == dataType) { 
    446445      DataBuffer buffer = r.getDataBuffer(); 
    447446      if (buffer instanceof DataBufferByte) { 
    448447        SampleModel model = r.getSampleModel(); 
     448        // NB: Could implement additional checks for ComponentSampleModel 
     449        // with particular characteristics to also use this shortcut. 
    449450        if (model instanceof BandedSampleModel) { 
    450451          // return bytes directly, with no copy 
     
    453454      } 
    454455    } 
    455  
    456     // convert to image with DataBufferByte and BandedSampleModel 
     456    //return getBytes(makeType(image, dataType)); 
    457457    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
    458     ColorModel colorModel = makeColorModel(c, dataType); 
    459     if (colorModel == null) return null; 
    460     SampleModel model = new BandedSampleModel(dataType, w, h, c); 
    461     DataBuffer buffer = new DataBufferByte(w * h, c); 
    462     WritableRaster raster = Raster.createWritableRaster(model, buffer, null); 
    463     BufferedImage target = new BufferedImage(colorModel, raster, false, null); 
    464     Graphics2D g2 = target.createGraphics(); 
    465     g2.drawRenderedImage(image, null); 
    466     g2.dispose(); 
    467     return getBytes(target); 
     458    byte[][] samples = new byte[c][w * h]; 
     459    int[] buf = new int[w * h]; 
     460    for (int i=0; i<c; i++) { 
     461      r.getSamples(0, 0, w, h, i, buf); 
     462      for (int j=0; j<buf.length; j++) samples[i][j] = (byte) buf[j]; 
     463    } 
     464    return samples; 
    468465  } 
    469466 
     
    471468  public static short[][] getShorts(BufferedImage image) { 
    472469    WritableRaster r = image.getRaster(); 
    473     int tt = r.getTransferType(); 
    474     if (tt == DataBuffer.TYPE_USHORT) { 
     470    if (r.getTransferType() == DataBuffer.TYPE_USHORT) { 
    475471      DataBuffer buffer = r.getDataBuffer(); 
    476472      if (buffer instanceof DataBufferUShort) { 
    477         return ((DataBufferUShort) buffer).getBankData(); 
    478       } 
    479     } 
    480     return getShorts(makeType(image, DataBuffer.TYPE_USHORT)); 
     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      } 
     481    } 
     482    //return getShorts(makeType(image, DataBuffer.TYPE_USHORT)); 
     483    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
     484    short[][] samples = new short[c][w * h]; 
     485    int[] buf = new int[w * h]; 
     486    for (int i=0; i<c; i++) { 
     487      r.getSamples(0, 0, w, h, i, buf); 
     488      for (int j=0; j<buf.length; j++) samples[i][j] = (short) buf[j]; 
     489    } 
     490    return samples; 
    481491  } 
    482492 
     
    489499      if (buffer instanceof DataBufferInt) { 
    490500        SampleModel model = r.getSampleModel(); 
     501        // NB: Could implement additional checks for ComponentSampleModel 
     502        // with particular characteristics to also use this shortcut. 
    491503        if (model instanceof BandedSampleModel) { 
    492504          // return ints directly, with no copy 
     
    495507      } 
    496508    } 
    497  
     509    // NB: an order of magnitude faster than the naive makeType solution 
    498510    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
    499511    int[][] samples = new int[c][w * h]; 
     
    510522      if (buffer instanceof DataBufferFloat) { 
    511523        SampleModel model = r.getSampleModel(); 
     524        // NB: Could implement additional checks for ComponentSampleModel 
     525        // with particular characteristics to also use this shortcut. 
    512526        if (model instanceof BandedSampleModel) { 
    513           // return ints directly, with no copy 
     527          // return floats directly, with no copy 
    514528          return ((DataBufferFloat) buffer).getBankData(); 
    515529        } 
    516530      } 
    517531    } 
    518     // an order of magnitude faster than the naive makeType solution 
     532    // NB: an order of magnitude faster than the naive makeType solution 
    519533    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
    520534    float[][] samples = new float[c][w * h]; 
     
    531545      if (buffer instanceof DataBufferDouble) { 
    532546        SampleModel model = r.getSampleModel(); 
     547        // NB: Could implement additional checks for ComponentSampleModel 
     548        // with particular characteristics to also use this shortcut. 
    533549        if (model instanceof BandedSampleModel) { 
    534           // return ints directly, with no copy 
     550          // return doubles directly, with no copy 
    535551          return ((DataBufferDouble) buffer).getBankData(); 
    536552        } 
    537553      } 
    538554    } 
    539     // an order of magnitude faster than the naive makeType solution 
     555    // NB: an order of magnitude faster than the naive makeType solution 
    540556    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
    541557    double[][] samples = new double[c][w * h]; 
     
    554570    Object pixels = getPixels(img); 
    555571 
    556     if (pixels instanceof byte[][]) return (byte[][]) pixels; 
     572    if (pixels instanceof byte[][]) { 
     573      byte[][] b = (byte[][]) pixels; 
     574      return (byte[][]) pixels; 
     575    } 
    557576    else if (pixels instanceof short[][]) { 
    558577      short[][] s = (short[][]) pixels; 
     
    659678  // -- Image conversion -- 
    660679 
    661   /** Copies the given image into a result with the specified data type. */ 
    662   public static BufferedImage makeType(BufferedImage image, int type) { 
    663     WritableRaster r = image.getRaster(); 
    664     int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
    665     ColorModel colorModel = makeColorModel(c, type); 
    666     if (colorModel == null) return null; 
    667  
    668     int s = w * h; 
    669     DataBuffer buf = null; 
    670     if (type == DataBuffer.TYPE_BYTE) buf = new DataBufferByte(s, c); 
    671     else if (type == DataBuffer.TYPE_USHORT) buf = new DataBufferUShort(s, c); 
    672     else if (type == DataBuffer.TYPE_INT) buf = new DataBufferInt(s, c); 
    673     else if (type == DataBuffer.TYPE_SHORT) buf = new DataBufferShort(s, c); 
    674     else if (type == DataBuffer.TYPE_FLOAT) buf = new DataBufferFloat(s, c); 
    675     else if (type == DataBuffer.TYPE_DOUBLE) buf = new DataBufferDouble(s, c); 
    676     if (buf == null) return null; 
    677  
    678     SampleModel model = new BandedSampleModel(type, w, h, c); 
    679     WritableRaster raster = Raster.createWritableRaster(model, buf, null); 
    680     BufferedImage target = new BufferedImage(colorModel, raster, false, null); 
    681     Graphics2D g2 = target.createGraphics(); 
    682     g2.drawRenderedImage(image, null); 
    683     g2.dispose(); 
    684     return target; 
    685   } 
    686  
    687   /** 
    688    * Get the bytes from an image, merging the channels as necessary. 
    689    */ 
     680  // NB: The commented out makeType method below is broken in that it results 
     681  // in rescaled data in some circumstances. We were using it for getBytes and 
     682  // getShorts, but due to this problem we implemented a different solution 
     683  // using Raster.getPixels instead. But we have left the makeType method here 
     684  // in case we decide to explore this issue any further in the future. 
     685 
     686//  /** Copies the given image into a result with the specified data type. */ 
     687//  public static BufferedImage makeType(BufferedImage image, int type) { 
     688//    WritableRaster r = image.getRaster(); 
     689//    int w = image.getWidth(), h = image.getHeight(), c = r.getNumBands(); 
     690//    ColorModel colorModel = makeColorModel(c, type); 
     691//    if (colorModel == null) return null; 
     692// 
     693//    int s = w * h; 
     694//    DataBuffer buf = null; 
     695//    if (type == DataBuffer.TYPE_BYTE) buf = new DataBufferByte(s, c); 
     696//    else if (type == DataBuffer.TYPE_USHORT) buf = new DataBufferUShort(s, c); 
     697//    else if (type == DataBuffer.TYPE_INT) buf = new DataBufferInt(s, c); 
     698//    else if (type == DataBuffer.TYPE_SHORT) buf = new DataBufferShort(s, c); 
     699//    else if (type == DataBuffer.TYPE_FLOAT) buf = new DataBufferFloat(s, c); 
     700//    else if (type == DataBuffer.TYPE_DOUBLE) buf = new DataBufferDouble(s, c); 
     701//    if (buf == null) return null; 
     702// 
     703//    SampleModel model = new BandedSampleModel(type, w, h, c); 
     704//    WritableRaster raster = Raster.createWritableRaster(model, buf, null); 
     705//    BufferedImage target = new BufferedImage(colorModel, raster, false, null); 
     706//    Graphics2D g2 = target.createGraphics(); 
     707//    g2.drawRenderedImage(image, null); 
     708//    g2.dispose(); 
     709//    return target; 
     710//  } 
     711 
     712  /** Get the bytes from an image, merging the channels as necessary. */ 
    690713  public static byte[] getBytes(BufferedImage img, boolean separated, int c) { 
    691714    byte[][] p = getBytes(img); 
Note: See TracChangeset for help on using the changeset viewer.