Changeset 1393


Ignore:
Timestamp:
08/31/06 11:27:56 (14 years ago)
Author:
melissa
Message:

added support for multiple series to OME-XML reader

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/in/OMEXMLReader.java

    r1389 r1393  
    4545 
    4646  /** Flag indicating whether current file is little endian. */ 
    47   protected boolean littleEndian; 
     47  protected boolean[] littleEndian; 
    4848 
    4949  /** Number of image planes in the file. */ 
    50   protected int numImages = 0; 
     50  protected int[] numImages; 
    5151 
    5252  /** Number of bits per pixel. */ 
    53   protected int bpp = 1; 
     53  protected int[] bpp; 
    5454 
    5555  /** Offset to each plane's data. */ 
    56   protected Vector offsets; 
     56  protected Vector[] offsets; 
    5757 
    5858  /** String indicating the compression type. */ 
    59   protected String compression; 
     59  protected String[] compression; 
    6060 
    6161  /** Image width. */ 
    62   private int width; 
     62  private int[] width; 
    6363 
    6464  /** Image height. */ 
    65   private int height; 
     65  private int[] height; 
    6666 
    6767  /** Number of channels. */ 
    68   private int numChannels; 
     68  private int[] numChannels; 
    6969 
    7070  /** Number of timepoints. */ 
    71   private int numT; 
     71  private int[] numT; 
    7272 
    7373  /** Number of Z slices. */ 
    74   private int numZ; 
     74  private int[] numZ; 
    7575 
    7676  /** Dimension order. */ 
    77   private String order; 
     77  private String[] order; 
    7878 
    7979  /** 
     
    9696  } 
    9797 
     98  /** Return the number of series in this file. */ 
     99  public int getSeriesCount(String id) throws FormatException, IOException { 
     100    if (!id.equals(currentId)) initFile(id); 
     101    return width.length; 
     102  } 
     103 
    98104  /** Determines the number of images in the given OME-XML file. */ 
    99105  public int getImageCount(String id) throws FormatException, IOException { 
    100106    if (!id.equals(currentId)) initFile(id); 
    101     return numImages; 
     107    return numImages[series]; 
    102108  } 
    103109 
     
    126132  public int getSizeX(String id) throws FormatException, IOException { 
    127133    if (!id.equals(currentId)) initFile(id); 
    128     return width; 
     134    return width[series]; 
    129135  } 
    130136 
     
    132138  public int getSizeY(String id) throws FormatException, IOException { 
    133139    if (!id.equals(currentId)) initFile(id); 
    134     return height; 
     140    return height[series]; 
    135141  } 
    136142 
     
    138144  public int getSizeZ(String id) throws FormatException, IOException { 
    139145    if (!id.equals(currentId)) initFile(id); 
    140     return numZ; 
     146    return numZ[series]; 
    141147  } 
    142148 
     
    144150  public int getSizeC(String id) throws FormatException, IOException { 
    145151    if (!id.equals(currentId)) initFile(id); 
    146     return numChannels; 
     152    return numChannels[series]; 
    147153  } 
    148154 
     
    150156  public int getSizeT(String id) throws FormatException, IOException { 
    151157    if (!id.equals(currentId)) initFile(id); 
    152     return numT; 
     158    return numT[series]; 
    153159  } 
    154160 
     
    156162  public boolean isLittleEndian(String id) throws FormatException, IOException { 
    157163    if (!id.equals(currentId)) initFile(id); 
    158     return littleEndian; 
     164    return littleEndian[series]; 
    159165  } 
    160166 
     
    167173  { 
    168174    if (!id.equals(currentId)) initFile(id); 
    169     return order; 
     175    return order[series]; 
    170176  } 
    171177 
     
    176182    if (!id.equals(currentId)) initFile(id); 
    177183 
    178     if (no < 0 || no >= numImages) { 
     184    if (no < 0 || no >= numImages[series]) { 
    179185      throw new FormatException("Invalid image number: " + no); 
    180186    } 
    181187 
    182     width = internalStore.getSizeX(null).intValue(); 
    183     height = internalStore.getSizeY(null).intValue(); 
    184  
    185     in.seek(((Integer) offsets.get(no)).intValue()); 
     188    int w = width[series]; 
     189    int h = width[series]; 
     190 
     191    in.seek(((Integer) offsets[series].get(no)).intValue()); 
    186192 
    187193    byte[] buf; 
    188194    if (no < getImageCount(id) - 1) { 
    189  
    190       buf = new byte[((Integer) offsets.get(no+1)).intValue() - 
    191         ((Integer) offsets.get(no)).intValue()]; 
     195      buf = new byte[((Integer) offsets[series].get(no + 1)).intValue() - 
     196        ((Integer) offsets[series].get(no)).intValue()]; 
    192197    } 
    193198    else { 
    194       buf = 
    195         new byte[(int) (in.length() - ((Integer) offsets.get(no)).intValue())]; 
     199      buf = new byte[(int) (in.length() - 
     200        ((Integer) offsets[series].get(no)).intValue())]; 
    196201    } 
    197202    in.read(buf); 
     
    208213    byte[] pixels = Compression.decode(pix); 
    209214 
    210     if (compression.equals("bzip2")) { 
     215    if (compression[series].equals("bzip2")) { 
    211216      byte[] tempPixels = pixels; 
    212217      pixels = new byte[tempPixels.length - 2]; 
     
    215220      ByteArrayInputStream bais = new ByteArrayInputStream(pixels); 
    216221      CBZip2InputStream bzip = new CBZip2InputStream(bais); 
    217       pixels = new byte[width*height*bpp]; 
     222      pixels = new byte[w * h * bpp[series]]; 
    218223      for (int i=0; i<pixels.length; i++) { 
    219224        pixels[i] = (byte) bzip.read(); 
    220225      } 
    221226    } 
    222     else if (compression.equals("zlib")) { 
     227    else if (compression[series].equals("zlib")) { 
    223228      try { 
    224229        Inflater decompressor = new Inflater(); 
    225230        decompressor.setInput(pixels, 0, pixels.length); 
    226         pixels = new byte[width * height * bpp]; 
     231        pixels = new byte[w * h * bpp[series]]; 
    227232        decompressor.inflate(pixels); 
    228233        decompressor.end(); 
     
    239244    throws FormatException, IOException 
    240245  { 
    241     return ImageTools.makeImage(openBytes(id, no), width, height, 
    242       1, false, bpp, littleEndian); 
     246    return ImageTools.makeImage(openBytes(id, no), width[series], 
     247      height[series], 1, false, bpp[series], littleEndian[series]); 
    243248  } 
    244249 
     
    256261    metadata = new Hashtable(); 
    257262    in = new RandomAccessStream(id); 
    258     offsets = new Vector(); 
    259263 
    260264    in.skipBytes(200); 
    261265 
    262     // read a block of 8192 characters, looking for the "BigEndian" pattern 
    263     byte[] buf = new byte[8192]; 
    264     boolean found = false; 
    265     while (!found) { 
    266       if (in.getFilePointer() < in.length()) { 
    267         in.read(buf, 9, 8183); 
    268         String test = new String(buf); 
    269  
    270         int ndx = test.indexOf("BigEndian"); 
    271         if (ndx != -1) { 
    272           found = true; 
    273           String endian = test.substring(ndx + 11); 
    274           if (endian.toLowerCase().startsWith("t")) littleEndian = false; 
    275           else littleEndian = true; 
    276         } 
     266    int numDatasets = 0; 
     267    Vector endianness = new Vector(); 
     268    Vector bigEndianPos = new Vector(); 
     269 
     270    byte[] buf = new byte[1]; 
     271 
     272    while (in.getFilePointer() < in.length()) { 
     273      // read a block of 8192 characters, looking for the "BigEndian" pattern 
     274      buf = new byte[8192]; 
     275      boolean found = false; 
     276      while (!found) { 
     277        if (in.getFilePointer() < in.length()) { 
     278          in.read(buf, 9, 8183); 
     279          String test = new String(buf); 
     280 
     281          int ndx = test.indexOf("BigEndian"); 
     282          if (ndx != -1) { 
     283            found = true; 
     284            String endian = test.substring(ndx + 11); 
     285            endianness.add(new Boolean(!endian.toLowerCase().startsWith("t"))); 
     286            bigEndianPos.add(new Integer(in.getFilePointer() - (8192 - ndx))); 
     287            numDatasets++; 
     288          } 
     289        } 
     290        else if (numDatasets == 0) { 
     291          throw new FormatException("Pixel data not found."); 
     292        } 
     293        else found = true; 
     294      } 
     295    } 
     296 
     297    littleEndian = new boolean[numDatasets]; 
     298    offsets = new Vector[numDatasets]; 
     299 
     300    for (int i=0; i<littleEndian.length; i++) { 
     301      littleEndian[i] = ((Boolean) endianness.get(i)).booleanValue(); 
     302      offsets[i] = new Vector(); 
     303    } 
     304 
     305    // look for the first BinData element in each series 
     306 
     307    for (int i=0; i<numDatasets; i++) { 
     308      in.seek(((Integer) bigEndianPos.get(i)).intValue()); 
     309      boolean found = false; 
     310      buf = new byte[8192]; 
     311      in.read(buf, 0, 14); 
     312 
     313      while (!found) { 
     314        if (in.getFilePointer() < in.length()) { 
     315          int numRead = in.read(buf, 14, 8192-14); 
     316 
     317          String test = new String(buf); 
     318 
     319          int ndx = test.indexOf("<Bin"); 
     320          if (ndx == -1) { 
     321            byte[] b = buf; 
     322            System.arraycopy(b, 8192 - 15, buf, 0, 14); 
     323          } 
     324          else { 
     325            while (!((ndx != -1) && (ndx != test.indexOf("<Bin:External")) && 
     326              (ndx != test.indexOf("<Bin:BinaryFile")))) 
     327            { 
     328              ndx = test.indexOf("<Bin", ndx+1); 
     329            } 
     330            found = true; 
     331            numRead += 14; 
     332            offsets[i].add(new Integer( 
     333              (int) in.getFilePointer() - (numRead - ndx))); 
     334          } 
     335        } 
     336        else { 
     337          throw new FormatException("Pixel data not found"); 
     338        } 
     339      } 
     340    } 
     341 
     342    in.seek(0); 
     343 
     344    String xml = ""; 
     345    for (int i=0; i<numDatasets; i++) { 
     346      if (i == 0) { 
     347        buf = new byte[((Integer) offsets[i].get(0)).intValue()]; 
    277348      } 
    278349      else { 
    279         throw new FormatException("Pixel data not found."); 
    280       } 
    281     } 
    282  
    283     in.seek(0); 
    284  
    285     // look for the first BinData element 
    286  
    287     found = false; 
    288     buf = new byte[8192]; 
    289     in.read(buf, 0, 14); 
    290     while (!found) { 
    291       if (in.getFilePointer() < in.length()) { 
    292         int numRead = in.read(buf, 14, 8192-14); 
    293  
    294         String test = new String(buf); 
    295  
    296         int ndx = test.indexOf("<Bin"); 
    297         if (ndx == -1) throw new FormatException("Pixel data not found"); 
    298         while (!((ndx != -1) && (ndx != test.indexOf("<Bin:External")) && 
    299           (ndx != test.indexOf("<Bin:BinaryFile")))) 
    300         { 
    301           ndx = test.indexOf("<Bin", ndx+1); 
    302         } 
    303         found = true; 
    304         numRead += 14; 
    305         offsets.add(new Integer( 
    306           (int) in.getFilePointer() - (numRead - ndx))); 
    307       } 
    308       else { 
    309         throw new FormatException("Pixel data not found"); 
    310       } 
    311     } 
    312  
    313     in.seek(0); 
    314  
    315     buf = new byte[((Integer) offsets.get(0)).intValue()]; 
    316     in.read(buf); 
    317     String xml = new String(buf); 
    318     xml += "</Pixels></Image></OME>";  // might lose some data this way 
     350        // look for the next Image element 
     351 
     352        boolean found = false; 
     353        buf = new byte[8192]; 
     354        in.read(buf, 0, 14); 
     355        while (!found) { 
     356          if (in.getFilePointer() < in.length()) { 
     357            int numRead = in.read(buf, 14, 8192-14); 
     358 
     359            String test = new String(buf); 
     360 
     361            int ndx = test.indexOf("<Image "); 
     362            if (ndx == -1) { 
     363              byte[] b = buf; 
     364              System.arraycopy(b, 8192 - 15, buf, 0, 14); 
     365            } 
     366            else { 
     367              found = true; 
     368              in.seek(in.getFilePointer() - (8192 - ndx)); 
     369            } 
     370          } 
     371          else { 
     372            throw new FormatException("Pixel data not found"); 
     373          } 
     374        } 
     375 
     376        int bufSize = ((Integer) offsets[i].get(0)).intValue() - 
     377          in.getFilePointer(); 
     378        buf = new byte[bufSize]; 
     379      } 
     380      in.read(buf); 
     381      xml += new String(buf); 
     382      xml += "</Pixels></Image>"; 
     383    } 
     384    xml += "</OME>"; 
    319385 
    320386    // The metadata store we're working with. 
     
    330396    internalStore.createRoot(xml); 
    331397 
    332     int sizeX = 0; 
    333     int sizeY = 0; 
    334     int sizeZ = 0; 
    335     int sizeC = 0; 
    336     int sizeT = 0; 
    337  
    338     String type = internalStore.getPixelType(null); 
    339     if (type.endsWith("16")) bpp = 2; 
    340     else if (type.endsWith("32")) bpp = 4; 
    341     else if (type.equals("float")) bpp = 8; 
    342  
    343     sizeX = internalStore.getSizeX(null).intValue(); 
    344     sizeY = internalStore.getSizeY(null).intValue(); 
    345     sizeZ = internalStore.getSizeZ(null).intValue(); 
    346     sizeC = internalStore.getSizeC(null).intValue(); 
    347     sizeT = internalStore.getSizeT(null).intValue(); 
    348     order = internalStore.getDimensionOrder(null); 
    349  
    350     numZ = sizeZ; 
    351     numT = sizeT; 
    352  
    353     numChannels = sizeC; 
    354  
    355     // calculate the number of raw bytes of pixel data that we are expecting 
    356     int expected = sizeX * sizeY * bpp; 
    357  
    358     // find the compression type and adjust 'expected' accordingly 
    359     buf = new byte[256]; 
    360     in.read(buf); 
    361     String data = new String(buf); 
    362  
    363     in.seek(((Integer) offsets.get(0)).intValue()); 
    364  
    365     int compressionStart = data.indexOf("Compression") + 13; 
    366     int compressionEnd = data.indexOf("\"", compressionStart); 
    367     if (compressionStart != -1 && compressionEnd != -1) { 
    368       compression = data.substring(compressionStart, compressionEnd); 
    369     } 
    370     else compression = "none"; 
    371  
    372     expected /= 2; 
    373     searchForData(expected, sizeZ * sizeT * sizeC); 
    374     numImages = offsets.size(); 
    375     if (numImages < (sizeZ * sizeT * sizeC)) { 
    376       // hope this doesn't happen too often 
    377       in.seek(((Integer) offsets.get(0)).intValue()); 
    378       searchForData(0, sizeZ * sizeT * sizeC); 
    379       numImages = offsets.size(); 
    380     } 
    381     width = internalStore.getSizeX(null).intValue(); 
    382     height = internalStore.getSizeY(null).intValue(); 
     398    width = new int[numDatasets]; 
     399    height = new int[numDatasets]; 
     400    numImages = new int[numDatasets]; 
     401    bpp = new int[numDatasets]; 
     402    littleEndian = new boolean[numDatasets]; 
     403    compression = new String[numDatasets]; 
     404    numChannels = new int[numDatasets]; 
     405    numT = new int[numDatasets]; 
     406    numZ = new int[numDatasets]; 
     407    order = new String[numDatasets]; 
     408 
     409    int oldSeries = getSeries(currentId); 
     410 
     411    for (int i=0; i<numDatasets; i++) { 
     412      setSeries(currentId, i); 
     413      Integer ndx = new Integer(i); 
     414      width[i] = internalStore.getSizeX(ndx).intValue(); 
     415      height[i] = internalStore.getSizeY(ndx).intValue(); 
     416      numT[i] = internalStore.getSizeT(ndx).intValue(); 
     417      numZ[i] = internalStore.getSizeZ(ndx).intValue(); 
     418      numChannels[i] = internalStore.getSizeC(ndx).intValue(); 
     419 
     420      String type = internalStore.getPixelType(ndx); 
     421      if (type.endsWith("16")) bpp[i] = 2; 
     422      else if (type.endsWith("32")) bpp[i] = 4; 
     423      else if (type.equals("float")) bpp[i] = 8; 
     424      else bpp[i] = 1; 
     425 
     426      order[i] = internalStore.getDimensionOrder(ndx); 
     427 
     428      // calculate the number of raw bytes of pixel data that we are expecting 
     429      int expected = width[i] * height[i] * bpp[i]; 
     430 
     431      // find the compression type and adjust 'expected' accordingly 
     432      in.seek(((Integer) offsets[i].get(0)).intValue()); 
     433      buf = new byte[256]; 
     434      in.read(buf); 
     435      String data = new String(buf); 
     436 
     437      int compressionStart = data.indexOf("Compression") + 13; 
     438      int compressionEnd = data.indexOf("\"", compressionStart); 
     439      if (compressionStart != -1 && compressionEnd != -1) { 
     440        compression[i] = data.substring(compressionStart, compressionEnd); 
     441      } 
     442      else compression[i] = "none"; 
     443 
     444      expected /= 2; 
     445 
     446      in.seek(((Integer) offsets[i].get(0)).intValue()); 
     447 
     448      searchForData(expected, numZ[i] * numT[i] * numChannels[i]); 
     449      numImages[i] = offsets[i].size(); 
     450      if (numImages[i] < (numZ[i] * numT[i] * numChannels[i])) { 
     451        // hope this doesn't happen too often 
     452        in.seek(((Integer) offsets[i].get(0)).intValue()); 
     453        searchForData(0, numZ[i] * numT[i] * numChannels[i]); 
     454        numImages[i] = offsets[i].size(); 
     455      } 
     456    } 
     457    setSeries(currentId, oldSeries); 
    383458  } 
    384459 
     
    390465    int iteration = 0; 
    391466    boolean found = false; 
    392     if (offsets.size() > 1) { 
    393       Object zeroth = offsets.get(0); 
    394       offsets.clear(); 
    395       offsets.add(zeroth); 
     467    if (offsets[series].size() > 1) { 
     468      Object zeroth = offsets[series].get(0); 
     469      offsets[series].clear(); 
     470      offsets[series].add(zeroth); 
    396471    } 
    397472 
    398473    in.skipBytes(1); 
    399474    while (((in.getFilePointer() + safe) < in.length()) && 
    400       (offsets.size() < numPlanes)) 
     475      (offsets[series].size() < numPlanes)) 
    401476    { 
    402477      in.skipBytes(safe); 
     
    416491            found = true; 
    417492            if (numRead == buf.length - 20) numRead = buf.length; 
    418             offsets.add(new Integer( 
     493            offsets[series].add(new Integer( 
    419494              (int) in.getFilePointer() - (numRead - ndx))); 
    420495            ndx = test.indexOf("<Bin", ndx+1); 
Note: See TracChangeset for help on using the changeset viewer.