Changeset 3245


Ignore:
Timestamp:
10/09/07 12:55:42 (12 years ago)
Author:
melissa
Message:

Parse XML using SAX.

File:
1 edited

Legend:

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

    r3241 r3245  
    2929import javax.xml.parsers.*; 
    3030import loci.formats.*; 
    31 import org.w3c.dom.*; 
    32 import org.xml.sax.SAXException; 
     31import org.xml.sax.*; 
     32import org.xml.sax.helpers.DefaultHandler; 
    3333 
    3434/** 
     
    4343public class OMETiffReader extends BaseTiffReader { 
    4444 
     45  // -- Constants -- 
     46 
     47  /** Factory for generating SAX parsers. */ 
     48  public static final SAXParserFactory SAX_FACTORY = 
     49    SAXParserFactory.newInstance(); 
     50 
    4551  // -- Fields -- 
    4652 
     
    4854  private String[] used; 
    4955 
    50   private int[][] ifdMap; 
    51   private int[][] fileMap; 
     56  /** List of Image IDs. */ 
     57  private Vector imageIDs; 
     58 
     59  /** List of Pixels IDs. */ 
     60  private Vector pixelsIDs; 
     61 
     62  private Vector tempIfdMap, tempFileMap, tempIfdCount; 
     63  private int currentFile, currentSeries, seriesCount; 
     64  private int[] numIFDs; 
     65  private int[][] ifdMap, fileMap; 
     66  private boolean lsids, isWiscScan; 
     67  private Hashtable[][] fds; 
    5268 
    5369  // -- Constructor -- 
     
    96112    FormatTools.checkBufferSize(this, buf.length); 
    97113 
    98     int ifd = ifdMap[series][no]; 
    99     int fileIndex = fileMap[series][no]; 
     114    int ifd = ifdMap[currentSeries][no]; 
     115    int fileIndex = fileMap[currentSeries][no]; 
     116 
     117    /* debug */ System.out.println("plane " + no + " : ifd=" + ifd + 
     118      ", file=" + fileIndex); 
    100119 
    101120    in = new RandomAccessStream(used[fileIndex]); 
    102     ifds = TiffTools.getIFDs(in); 
    103     TiffTools.getSamples(ifds[ifd], in, buf); 
     121    TiffTools.getSamples(fds[fileIndex][ifd], in, buf); 
    104122    in.close(); 
    105123    return swapIfRequired(buf); 
     
    112130    super.initStandardMetadata(); 
    113131 
     132    OMETiffHandler handler = new OMETiffHandler(); 
    114133    String comment = (String) getMeta("Comment"); 
    115     boolean lsids = true; 
    116  
    117     // find list of Image IDs 
    118     Vector v = new Vector(); 
    119     String check = "<Image "; 
    120     int ndx = comment.indexOf(check); 
    121     while (ndx >= 0) { 
    122       int ii = comment.indexOf("ID=\"", ndx); 
    123       v.add(comment.substring(ii + 4, comment.indexOf("\"", ii + 5))); 
    124       ndx = comment.indexOf(check, ndx + 1); 
    125     } 
    126     String[] imageIds = (String[]) v.toArray(new String[0]); 
    127     for (int i=0; i<imageIds.length; i++) { 
    128       if (!imageIds[i].toLowerCase().startsWith("urn:lsid")) { 
    129         lsids = false; 
    130         break; 
    131       } 
    132     } 
    133  
    134     // find list of Pixels IDs 
    135     v.clear(); 
    136     check = "<Pixels "; 
    137     ndx = comment.indexOf(check); 
    138     while (ndx >= 0) { 
    139       int ii = comment.indexOf("ID=\"", ndx); 
    140       v.add(comment.substring(ii + 4, comment.indexOf("\"", ii + 5))); 
    141       ndx = comment.indexOf(check, ndx + 1); 
    142     } 
    143     String[] pixelsIds = (String[]) v.toArray(new String[0]); 
    144     for (int i=0; i<pixelsIds.length; i++) { 
    145       if (!pixelsIds[i].toLowerCase().startsWith("urn:lsid")) { 
    146         lsids = false; 
    147         break; 
    148       } 
    149     } 
    150  
    151     int numSeries = pixelsIds.length; 
    152  
    153     int[] numIFDs = new int[numSeries]; 
    154  
    155     // only look for files in the same dataset if LSIDs are present 
     134 
     135    currentSeries = -1; 
     136    seriesCount = 0; 
     137    imageIDs = null; 
     138    pixelsIDs = null; 
     139    lsids = true; 
     140 
     141    tempIfdMap = new Vector(); 
     142    tempFileMap = new Vector(); 
     143    tempIfdCount = new Vector(); 
     144 
     145    try { 
     146      SAXParser parser = SAX_FACTORY.newSAXParser(); 
     147      parser.parse(new ByteArrayInputStream(comment.getBytes()), handler); 
     148    } 
     149    catch (ParserConfigurationException exc) { 
     150      throw new FormatException(exc); 
     151    } 
     152    catch (SAXException exc) { 
     153      throw new FormatException(exc); 
     154    } 
     155 
     156    // MAJOR HACK : check for OME-XML in the comment of the second IFD 
     157    // There is a version of WiscScan which writes OME-XML to every IFD, 
     158    // but with SizeZ and SizeT equal to 1. 
     159 
     160    String s = null; 
     161    if (ifds.length > 1) { 
     162      s = (String) TiffTools.getIFDValue(ifds[1], TiffTools.IMAGE_DESCRIPTION); 
     163    } 
     164    isWiscScan = s != null && s.indexOf("ome.xsd") != -1; 
     165 
     166    // look for additional files in the dataset 
    156167    Vector files = new Vector(); 
    157168    Location l = new Location(currentId); 
    158169    l = l.getAbsoluteFile().getParentFile(); 
    159170    String[] fileList = l.list(); 
    160     ifdMap = new int[numSeries][]; 
    161     fileMap = new int[numSeries][]; 
    162171 
    163172    if (!lsids) { 
    164173      fileList = new String[] {currentId}; 
    165174      LogTools.println("Not searching for other files - " + 
    166         "Image LSID not present."); 
    167     } 
    168  
    169     Vector comments = new Vector(); 
     175        "Image LSID not present"); 
     176    } 
    170177 
    171178    for (int i=0; i<fileList.length; i++) { 
    172       check = fileList[i].toLowerCase(); 
     179      String check = fileList[i].toLowerCase(); 
    173180      if (check.endsWith(".tif") || check.endsWith(".tiff")) { 
    174181        status("Checking " + fileList[i]); 
    175182        ifds = TiffTools.getIFDs(new RandomAccessStream(l.getAbsolutePath() + 
    176183          File.separator + fileList[i])); 
    177         // TODO - need accurate IFD count 
    178         for (int j=0; j<numSeries; j++) { 
    179           numIFDs[j] += ifds.length; 
    180         } 
    181184        if (ifds[0] == null) continue; 
    182185        comment = 
    183186          (String) TiffTools.getIFDValue(ifds[0], TiffTools.IMAGE_DESCRIPTION); 
    184187        boolean addToList = true; 
    185         for (int s=0; s<imageIds.length; s++) { 
    186           if (comment.indexOf(imageIds[s]) == -1) { 
    187             addToList = false; 
    188             break; 
    189           } 
    190         } 
    191         if (addToList) { 
    192           for (int s=0; s<pixelsIds.length; s++) { 
    193             if (comment.indexOf(pixelsIds[s]) == -1) { 
     188        if (imageIDs != null) { 
     189          for (int k=0; k<imageIDs.size(); k++) { 
     190            if (comment.indexOf((String) imageIDs.get(k)) == -1) { 
    194191              addToList = false; 
     192              break; 
     193            } 
     194          } 
     195          if (addToList) { 
     196            for (int k=0; k<pixelsIDs.size(); k++) { 
     197              if (comment.indexOf((String) pixelsIDs.get(k)) == -1) { 
     198                addToList = false; 
     199                break; 
     200              } 
    195201            } 
    196202          } 
     
    199205        if (addToList) { 
    200206          files.add(l.getAbsolutePath() + File.separator + fileList[i]); 
    201           comments.add(comment); 
    202         } 
    203       } 
     207        } 
     208      } 
     209    } 
     210 
     211    // parse grouped files 
     212 
     213    core = new CoreMetadata(seriesCount); 
     214    ifdMap = new int[seriesCount][]; 
     215    fileMap = new int[seriesCount][]; 
     216    numIFDs = new int[seriesCount]; 
     217 
     218    for (int i=0; i<seriesCount; i++) { 
     219      int ii = ((Integer) tempIfdCount.get(i)).intValue(); 
     220      ifdMap[i] = new int[ii]; 
     221      fileMap[i] = new int[ii]; 
    204222    } 
    205223 
    206224    used = (String[]) files.toArray(new String[0]); 
    207  
    208     for (int i=0; i<numSeries; i++) { 
    209       ifdMap[i] = new int[numIFDs[i]]; 
    210       fileMap[i] = new int[numIFDs[i]]; 
    211     } 
    212  
    213     // set ifdMap and fileMap based on TiffData elements 
     225    fds = new Hashtable[used.length][]; 
     226 
    214227    for (int i=0; i<used.length; i++) { 
    215228      status("Parsing " + used[i]); 
    216       String com = (String) comments.get(i); 
    217       ByteArrayInputStream is = new ByteArrayInputStream(com.getBytes()); 
    218       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    219       Document doc = null; 
     229      currentSeries = -1; 
     230      tempIfdMap = null; 
     231      tempFileMap = null; 
     232      tempIfdCount = null; 
     233      currentFile = i; 
     234 
     235      fds[i] = TiffTools.getIFDs(new RandomAccessStream(used[i])); 
     236      String c = 
     237        (String) TiffTools.getIFDValue(fds[i][0], TiffTools.IMAGE_DESCRIPTION); 
    220238      try { 
    221         DocumentBuilder builder = factory.newDocumentBuilder(); 
    222         doc = builder.parse(is); 
    223       } 
    224       catch (ParserConfigurationException exc) { } 
    225       catch (SAXException exc) { } 
    226       catch (IOException exc) { } 
    227  
    228       Element[] pixels = null; 
    229       if (doc != null) { 
    230         NodeList pixelsList = doc.getElementsByTagName("Pixels"); 
    231         pixels = new Element[pixelsList.getLength()]; 
    232         for (int j=0; j<pixels.length; j++) { 
    233           pixels[j] = (Element) pixelsList.item(j); 
    234  
    235           String order = pixels[j].getAttribute("DimensionOrder"); 
    236           int z = Integer.parseInt(pixels[j].getAttribute("SizeZ")); 
    237           int c = Integer.parseInt(pixels[j].getAttribute("SizeC")); 
    238           int t = Integer.parseInt(pixels[j].getAttribute("SizeT")); 
    239  
    240           NodeList list = pixels[j].getChildNodes(); 
    241           int size = list.getLength(); 
    242           v.clear(); 
    243           for (int k=0; k<size; k++) { 
    244             Node node = list.item(k); 
    245             if (!(node instanceof Element)) continue; 
    246             if ("TiffData".equals(node.getNodeName())) { 
    247               v.add(node); 
    248             } 
    249           } 
    250           Element[] tiffData = new Element[v.size()]; 
    251           v.copyInto(tiffData); 
    252  
    253           int ifdCount = 
    254             TiffTools.getIFDs(new RandomAccessStream(used[i])).length; 
    255  
    256           for (int k=0; k<tiffData.length; k++) { 
    257             String ifd = tiffData[k].getAttribute("IFD"); 
    258             String numPlanes = tiffData[k].getAttribute("NumPlanes"); 
    259             String firstZ = tiffData[k].getAttribute("FirstZ"); 
    260             String firstC = tiffData[k].getAttribute("FirstC"); 
    261             String firstT = tiffData[k].getAttribute("FirstT"); 
    262             if (ifd == null || ifd.equals("")) ifd = "0"; 
    263             if (numPlanes == null || numPlanes.equals("")) { 
    264               numPlanes = "" + ifdCount; 
    265             } 
    266             if (firstZ == null || firstZ.equals("")) firstZ = "0"; 
    267             if (firstC == null || firstC.equals("")) firstC = "0"; 
    268             if (firstT == null || firstT.equals("")) firstT = "0"; 
    269  
    270             int idx = FormatTools.getIndex(order, z, c, t, z * c * t, 
    271               Integer.parseInt(firstZ), Integer.parseInt(firstC), 
    272               Integer.parseInt(firstT)); 
    273  
    274             ifdMap[j][idx] = Integer.parseInt(ifd) % ifdCount; 
    275             fileMap[j][idx] = i; 
    276             for (int q=0; q<Integer.parseInt(numPlanes); q++) { 
    277               ifdMap[j][idx + q] = ifdMap[j][idx] + q; 
    278               fileMap[j][idx + q] = i; 
    279             } 
    280           } 
    281         } 
    282       } 
    283     } 
    284  
    285     comment = (String) getMeta("Comment"); 
    286  
    287     // convert string to DOM 
    288     ByteArrayInputStream is = new ByteArrayInputStream(comment.getBytes()); 
    289     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    290     Document doc = null; 
    291     try { 
    292       DocumentBuilder builder = factory.newDocumentBuilder(); 
    293       doc = builder.parse(is); 
    294     } 
    295     catch (ParserConfigurationException exc) { } 
    296     catch (SAXException exc) { } 
    297     catch (IOException exc) { } 
    298  
    299     // extract TiffData elements from XML 
    300     Element[] pixels = null; 
    301     Element[][] tiffData = null; 
    302     if (doc != null) { 
    303       NodeList pixelsList = doc.getElementsByTagName("Pixels"); 
    304       int nSeries = pixelsList.getLength(); 
    305       v = new Vector(); 
    306       pixels = new Element[nSeries]; 
    307       tiffData = new Element[nSeries][]; 
    308       for (int i=0; i<nSeries; i++) { 
    309         pixels[i] = (Element) pixelsList.item(i); 
    310         NodeList list = pixels[i].getChildNodes(); 
    311         int size = list.getLength(); 
    312         v.clear(); 
    313         for (int j=0; j<size; j++) { 
    314           Node node = list.item(j); 
    315           if (!(node instanceof Element)) continue; 
    316           if ("TiffData".equals(node.getNodeName())) { 
    317             v.add(node); 
    318           } 
    319         } 
    320         tiffData[i] = new Element[v.size()]; 
    321         v.copyInto(tiffData[i]); 
    322       } 
    323     } 
    324  
    325     // MAJOR HACK : check for OME-XML in the comment of the second IFD 
    326     // There is a version of WiscScan which writes OME-XML to every IFD, 
    327     // but with SizeZ and SizeT equal to 1. 
    328  
    329     String s = null; 
    330     if (ifds.length > 1) { 
    331       s = (String) TiffTools.getIFDValue(ifds[1], TiffTools.IMAGE_DESCRIPTION); 
    332     } 
    333     boolean isWiscScan = s != null && s.indexOf("ome.xsd") != -1; 
    334  
    335     // extract SizeZ, SizeC and SizeT from XML block 
    336     if (tiffData != null) { 
    337       boolean rgb = isRGB(); 
    338       boolean indexed = isIndexed(); 
    339       boolean falseColor = isFalseColor(); 
    340       core = new CoreMetadata(tiffData.length); 
    341       Arrays.fill(core.orderCertain, true); 
    342       Arrays.fill(core.indexed, indexed); 
    343       Arrays.fill(core.falseColor, falseColor); 
    344  
    345       for (int i=0; i<tiffData.length; i++) { 
    346         String ifdString = tiffData[i][0].getAttribute("IFD"); 
    347         int ifd = -1; 
    348         if (ifdString == null || ifdString.equals("")) ifd = 0; 
    349         else ifd = Integer.parseInt(ifdString); 
    350         core.sizeX[i] = Integer.parseInt(pixels[i].getAttribute("SizeX")); 
    351         int expectedX = (int) TiffTools.getImageWidth(ifds[ifd]); 
    352         if (core.sizeX[i] != expectedX) { 
    353           LogTools.println("Mismatched width: OME-XML reports SizeX=" + 
    354             core.sizeX[i] + "; expecting " + expectedX); 
    355           core.sizeX[i] = expectedX; 
    356         } 
    357         core.sizeY[i] = Integer.parseInt(pixels[i].getAttribute("SizeY")); 
    358         int expectedY = (int) TiffTools.getImageLength(ifds[ifd]); 
    359         if (core.sizeY[i] != expectedY) { 
    360           LogTools.println("Mismatched height: OME-XML reports SizeY=" + 
    361             core.sizeY[i] + "; expecting " + expectedY); 
    362           core.sizeY[i] = expectedY; 
    363         } 
    364         core.sizeZ[i] = Integer.parseInt(pixels[i].getAttribute("SizeZ")); 
    365         core.sizeC[i] = Integer.parseInt(pixels[i].getAttribute("SizeC")); 
    366         core.sizeT[i] = Integer.parseInt(pixels[i].getAttribute("SizeT")); 
    367  
    368         // HACK: correct for erroneous negative size values 
    369         if (core.sizeZ[i] < 1) core.sizeZ[i] = 1; 
    370         if (core.sizeC[i] < 1) core.sizeC[i] = 1; 
    371         if (core.sizeT[i] < 1) core.sizeT[i] = 1; 
    372  
    373         if (rgb && indexed && core.sizeC[i] == 3) { 
    374           rgb = false; 
    375           core.indexed[i] = false; 
    376           core.falseColor[i] = false; 
    377         } 
    378  
    379         int sc = core.sizeC[i]; 
    380         if (rgb && sc > 1) sc /= 3; 
    381         core.imageCount[i] = core.sizeZ[i] * sc * core.sizeT[i]; 
    382         core.rgb[i] = rgb; 
    383         core.pixelType[i] = FormatTools.pixelTypeFromString( 
    384           pixels[i].getAttribute("PixelType")); 
    385         if (core.pixelType[i] == FormatTools.INT8 || 
    386           core.pixelType[i] == FormatTools.INT16 || 
    387           core.pixelType[i] == FormatTools.INT32) 
    388         { 
    389           core.pixelType[i]++; 
    390         } 
    391  
    392         // MAJOR HACK: adjust SizeT to match the number of IFDs, if this file 
    393         // was written by a buggy version of WiscScan 
    394         if (isWiscScan) core.sizeT[i] = core.imageCount[0]; 
    395  
    396         core.currentOrder[i] = pixels[i].getAttribute("DimensionOrder"); 
    397         core.orderCertain[i] = true; 
    398  
    399         if (numIFDs != null && lsids) { 
    400           if (numIFDs[i] < core.imageCount[i]) { 
    401             LogTools.println("Too few IFDs; got " + numIFDs[i] + ", expected " + 
    402               core.imageCount[i]); 
    403           } 
    404           else if (numIFDs[i] > core.imageCount[i]) { 
    405             LogTools.println("Too many IFDs; got " + numIFDs[i] + 
    406               ", expected " + core.imageCount[i]); 
    407           } 
    408         } 
    409         else if (core.imageCount[i] > ifds.length) { 
    410           core.imageCount[i] = ifds.length; 
    411           if (core.sizeZ[i] > ifds.length) { 
    412             core.sizeZ[i] = ifds.length / (rgb ? core.sizeC[i] : 1); 
    413             core.sizeT[i] = 1; 
    414             if (!rgb) core.sizeC[i] = 1; 
    415           } 
    416           else if (core.sizeT[i] > ifds.length) { 
    417             core.sizeT[i] = ifds.length / (rgb ? core.sizeC[i] : 1); 
    418             core.sizeZ[i] = 1; 
    419             if (!rgb) core.sizeC[i] = 1; 
    420           } 
    421         } 
    422  
    423         boolean[][][] zct = new boolean[core.sizeZ[i]][sc][core.sizeT[i]]; 
    424  
    425         for (int j=0; j<tiffData[i].length; j++) { 
    426           String aIfd = tiffData[i][j].getAttribute("IFD"); 
    427           String aFirstZ = tiffData[i][j].getAttribute("FirstZ"); 
    428           String aFirstT = tiffData[i][j].getAttribute("FirstT"); 
    429           String aFirstC = tiffData[i][j].getAttribute("FirstC"); 
    430           String aNumPlanes = tiffData[i][j].getAttribute("NumPlanes"); 
    431           boolean nullIfd = aIfd == null || aIfd.equals(""); 
    432           boolean nullFirstZ = aFirstZ == null || aFirstZ.equals(""); 
    433           boolean nullFirstC = aFirstC == null || aFirstC.equals(""); 
    434           boolean nullFirstT = aFirstT == null || aFirstT.equals(""); 
    435           boolean nullNumPlanes = aNumPlanes == null || aNumPlanes.equals(""); 
    436  
    437           int firstZ = nullFirstZ ? 0 : Integer.parseInt(aFirstZ); 
    438           int firstC = nullFirstC ? 0 : Integer.parseInt(aFirstC); 
    439           int firstT = nullFirstT ? 0 : Integer.parseInt(aFirstT); 
    440           int numPlanes = nullNumPlanes ? (nullIfd ? core.imageCount[0] : 1) : 
    441             Integer.parseInt(aNumPlanes); 
    442  
    443           // HACK: adjust first values, if this file 
    444           // was written by a buggy version of WiscScan 
    445           if (firstZ >= core.sizeZ[0]) firstZ = core.sizeZ[0] - 1; 
    446           if (firstC >= core.sizeC[0]) firstC = core.sizeC[0] - 1; 
    447           if (firstT >= core.sizeT[0]) firstT = core.sizeT[0] - 1; 
    448  
    449           // populate ZCT matrix 
    450           char d1st = core.currentOrder[i].charAt(2); 
    451           char d2nd = core.currentOrder[i].charAt(3); 
    452           int z = firstZ, t = firstT, c = firstC; 
    453  
    454           for (int k=0; k<numPlanes; k++) { 
    455             zct[z][c][t] = true; 
    456             switch (d1st) { 
    457               case 'Z': 
    458                 z++; 
    459                 if (z >= core.sizeZ[i]) { 
    460                   z = 0; 
    461                   switch (d2nd) { 
    462                     case 'T': 
    463                       t++; 
    464                       if (t >= core.sizeT[i]) { 
    465                         t = 0; 
    466                         c++; 
    467                       } 
    468                       break; 
    469                     case 'C': 
    470                       c++; 
    471                       if (c >= sc) { 
    472                         c = 0; 
    473                         t++; 
    474                       } 
    475                       break; 
    476                   } 
    477                 } 
    478                 break; 
    479               case 'T': 
    480                 t++; 
    481                 if (t >= core.sizeT[i]) { 
    482                   t = 0; 
    483                   switch (d2nd) { 
    484                     case 'Z': 
    485                       z++; 
    486                       if (z >= core.sizeZ[i]) { 
    487                         z = 0; 
    488                         c++; 
    489                       } 
    490                       break; 
    491                     case 'C': 
    492                       c++; 
    493                       if (c >= sc) { 
    494                         c = 0; 
    495                         z++; 
    496                       } 
    497                       break; 
    498                   } 
    499                 } 
    500                 break; 
    501               case 'C': 
    502                 c++; 
    503                 if (c >= sc) { 
    504                   c = 0; 
    505                   switch (d2nd) { 
    506                     case 'Z': 
    507                       z++; 
    508                       if (z >= core.sizeZ[i]) { 
    509                         z = 0; 
    510                         t++; 
    511                       } 
    512                       break; 
    513                     case 'T': 
    514                       t++; 
    515                       if (t >= core.sizeT[i]) { 
    516                         t = 0; 
    517                         z++; 
    518                       } 
    519                       break; 
    520                   } 
    521                 } 
    522                 break; 
    523             } 
    524           } 
     239        SAXParser parser = SAX_FACTORY.newSAXParser(); 
     240        parser.parse(new ByteArrayInputStream(c.getBytes()), handler); 
     241      } 
     242      catch (ParserConfigurationException exc) { 
     243        throw new FormatException(exc); 
     244      } 
     245      catch (SAXException exc) { 
     246        throw new FormatException(exc); 
     247      } 
     248    } 
     249 
     250    for (int i=0; i<getSeriesCount(); i++) { 
     251      if (numIFDs != null && lsids) { 
     252        if (numIFDs[i] < core.imageCount[i]) { 
     253          LogTools.println("Too few IFDs; got " + numIFDs[i] + 
     254            ", expected " + core.imageCount[i]); 
     255        } 
     256        else if (numIFDs[i] > core.imageCount[i]) { 
     257          LogTools.println("Too many IFDs; got " + numIFDs[i] + 
     258            ", expected " + core.imageCount[i]); 
     259        } 
     260      } 
     261      else if (core.imageCount[i] > ifds.length) { 
     262        core.imageCount[i] = ifds.length; 
     263        if (core.sizeZ[i] > ifds.length) { 
     264          core.sizeZ[i] = ifds.length / (core.rgb[i] ? core.sizeC[i] : 1); 
     265          core.sizeT[i] = 1; 
     266          if (!core.rgb[i]) core.sizeC[i] = 1; 
     267        } 
     268        else if (core.sizeT[i] > ifds.length) { 
     269          core.sizeT[i] = ifds.length / (core.rgb[i] ? core.sizeC[i] : 1); 
     270          core.sizeZ[i] = 1; 
     271          if (!core.rgb[i]) core.sizeC[i] = 1; 
    525272        } 
    526273      } 
     
    536283  } 
    537284 
     285  // -- Helper class -- 
     286 
     287  /** SAX handler for parsing XML. */ 
     288  class OMETiffHandler extends DefaultHandler { 
     289    private String order; 
     290    private int sizeZ, sizeC, sizeT; 
     291 
     292    public void startElement(String uri, String localName, String qName, 
     293      Attributes attributes) 
     294    { 
     295      if (qName.equals("Image")) { 
     296        String id = attributes.getValue("ID"); 
     297        if (id.startsWith("urn:lsid:")) { 
     298          if (imageIDs == null) imageIDs = new Vector(); 
     299          imageIDs.add(id); 
     300        } 
     301        else lsids = false; 
     302      } 
     303      else if (qName.equals("Pixels")) { 
     304        currentSeries++; 
     305        String id = attributes.getValue("ID"); 
     306        if (id.startsWith("urn:lsid:")) { 
     307          if (pixelsIDs == null) pixelsIDs = new Vector(); 
     308          pixelsIDs.add(id); 
     309        } 
     310        else lsids = false; 
     311 
     312        order = attributes.getValue("DimensionOrder"); 
     313        sizeZ = Integer.parseInt(attributes.getValue("SizeZ")); 
     314        sizeC = Integer.parseInt(attributes.getValue("SizeC")); 
     315        sizeT = Integer.parseInt(attributes.getValue("SizeT")); 
     316        if (tempIfdCount != null) { 
     317          tempIfdCount.add(new Integer(sizeZ * sizeC * sizeT)); 
     318        } 
     319 
     320        if (sizeZ < 1) sizeZ = 1; 
     321        if (sizeC < 1) sizeC = 1; 
     322        if (sizeT < 1) sizeT = 1; 
     323 
     324        if (core.sizeZ.length > currentSeries) { 
     325          core.sizeX[currentSeries] = 
     326            Integer.parseInt(attributes.getValue("SizeX")); 
     327          core.sizeY[currentSeries] = 
     328            Integer.parseInt(attributes.getValue("SizeY")); 
     329          core.sizeZ[currentSeries] = sizeZ; 
     330          core.sizeC[currentSeries] = sizeC; 
     331          core.sizeT[currentSeries] = sizeT; 
     332          core.currentOrder[currentSeries] = order; 
     333          core.rgb[currentSeries] = isRGB(); 
     334          core.indexed[currentSeries] = isIndexed(); 
     335          core.falseColor[currentSeries] = isFalseColor(); 
     336 
     337          try { 
     338            if (fds != null && fds[currentSeries] != null) { 
     339              int x = (int) TiffTools.getImageWidth(fds[currentSeries][0]); 
     340              int y = (int) TiffTools.getImageLength(fds[currentSeries][0]); 
     341              if (x != core.sizeX[currentSeries]) { 
     342                LogTools.println("Mismatched width: got " + 
     343                  core.sizeX[currentSeries] + ", expected " + x); 
     344                core.sizeX[currentSeries] = x; 
     345              } 
     346              if (y != core.sizeY[currentSeries]) { 
     347                LogTools.println("Mismatched height: got " + 
     348                  core.sizeY[currentSeries] + ", expected " + y); 
     349                core.sizeY[currentSeries] = y; 
     350              } 
     351            } 
     352          } 
     353          catch (FormatException e) { } 
     354 
     355          if (core.rgb[currentSeries] && core.indexed[currentSeries] && 
     356            core.sizeC[currentSeries] == 3) 
     357          { 
     358            core.rgb[currentSeries] = false; 
     359            core.indexed[currentSeries] = false; 
     360            core.falseColor[currentSeries] = false; 
     361          } 
     362 
     363          int sc = core.sizeC[currentSeries]; 
     364          if (core.rgb[currentSeries] && sc > 1) sc /= 3; 
     365          core.imageCount[currentSeries] = 
     366            core.sizeZ[currentSeries] * sc * core.sizeT[currentSeries]; 
     367          core.pixelType[currentSeries] = 
     368            FormatTools.pixelTypeFromString(attributes.getValue("PixelType")); 
     369          if (core.pixelType[currentSeries] == FormatTools.INT8 || 
     370            core.pixelType[currentSeries] == FormatTools.INT16 || 
     371            core.pixelType[currentSeries] == FormatTools.INT32) 
     372          { 
     373            core.pixelType[currentSeries]++; 
     374          } 
     375 
     376          if (isWiscScan) core.sizeT[currentSeries] = core.imageCount[0]; 
     377 
     378          core.orderCertain[currentSeries] = true; 
     379        } 
     380        if (numIFDs != null) { 
     381          numIFDs[currentSeries] += fds[currentSeries].length; 
     382        } 
     383 
     384        seriesCount++; 
     385      } 
     386      else if (qName.equals("TiffData")) { 
     387        String ifd = attributes.getValue("IFD"); 
     388        String numPlanes = attributes.getValue("NumPlanes"); 
     389        String z = attributes.getValue("FirstZ"); 
     390        String c = attributes.getValue("FirstC"); 
     391        String t = attributes.getValue("FirstT"); 
     392        if (ifd == null || ifd.equals("")) ifd = "0"; 
     393        if (numPlanes == null || numPlanes.equals("")) { 
     394          if (fds != null) numPlanes = "" + fds[currentSeries].length; 
     395          else numPlanes = "" + ifds.length; 
     396        } 
     397        if (z == null || z.equals("")) z = "0"; 
     398        if (c == null || c.equals("")) c = "0"; 
     399        if (t == null || t.equals("")) t = "0"; 
     400 
     401        int idx = FormatTools.getIndex(order, sizeZ, sizeC, sizeT, 
     402          sizeZ * sizeC * sizeT, Integer.parseInt(z), Integer.parseInt(c), 
     403          Integer.parseInt(t)); 
     404 
     405        if (tempIfdMap != null) { 
     406          Vector v = new Vector(sizeZ * sizeC * sizeT); 
     407          Vector y = new Vector(sizeZ * sizeC * sizeT); 
     408          if (tempIfdMap.size() >= seriesCount) { 
     409            v = (Vector) tempIfdMap.get(seriesCount - 1); 
     410            y = (Vector) tempFileMap.get(seriesCount - 1); 
     411          } 
     412 
     413          if (v.size() > idx) v.setElementAt(new Integer(ifd), idx); 
     414          else v.add(new Integer(ifd)); 
     415          if (y.size() > idx) y.setElementAt(new Integer(0), idx); 
     416          else y.add(new Integer(0)); 
     417 
     418          for (int i=1; i<Integer.parseInt(numPlanes); i++) { 
     419            if (v.size() > idx + i) { 
     420              v.setElementAt(new Integer(Integer.parseInt(ifd) + 1), idx + i); 
     421            } 
     422            else v.add(new Integer(Integer.parseInt(ifd) + 1)); 
     423            if (y.size() > idx + i) y.setElementAt(new Integer(0), idx + i); 
     424            else y.add(new Integer(0)); 
     425          } 
     426 
     427          if (tempIfdMap.size() > seriesCount) { 
     428            tempIfdMap.setElementAt(v, seriesCount); 
     429          } 
     430          else tempIfdMap.add(v); 
     431        } 
     432        else { 
     433          ifdMap[currentSeries][idx] = Integer.parseInt(ifd); 
     434          fileMap[currentSeries][idx] = currentFile; 
     435          for (int i=1; i<Integer.parseInt(numPlanes); i++) { 
     436            ifdMap[currentSeries][idx + i] = ifdMap[currentSeries][idx] + i; 
     437            fileMap[currentSeries][idx + i] = currentFile; 
     438          } 
     439        } 
     440      } 
     441    } 
     442  } 
    538443} 
Note: See TracChangeset for help on using the changeset viewer.