Changeset 2943


Ignore:
Timestamp:
07/06/07 15:09:56 (13 years ago)
Author:
melissa
Message:

Added OME-TIFF reader; removed OME-TIFF logic from TiffReader.

Location:
trunk/loci/formats
Files:
1 added
2 edited

Legend:

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

    r2937 r2943  
    7272    status("Checking comment style"); 
    7373 
    74     // check for OME-XML in TIFF comment (OME-TIFF format) 
    75     boolean omeTiff = comment != null && comment.indexOf("ome.xsd") >= 0; 
    76     put("OME-TIFF", omeTiff ? "yes" : "no"); 
    77     if (omeTiff) { 
    78       status("Found OME-TIFF: parsing OME-XML"); 
    79  
    80       // convert string to DOM 
    81       ByteArrayInputStream is = new ByteArrayInputStream(comment.getBytes()); 
    82       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    83       Document doc = null; 
    84       try { 
    85         DocumentBuilder builder = factory.newDocumentBuilder(); 
    86         doc = builder.parse(is); 
    87       } 
    88       catch (ParserConfigurationException exc) { } 
    89       catch (SAXException exc) { } 
    90       catch (IOException exc) { } 
    91  
    92       // extract TiffData elements from XML 
    93       Element[] pixels = null; 
    94       Element[][] tiffData = null; 
    95       if (doc != null) { 
    96         NodeList pixelsList = doc.getElementsByTagName("Pixels"); 
    97         int numSeries = pixelsList.getLength(); 
    98         Vector v = new Vector(); 
    99         pixels = new Element[numSeries]; 
    100         tiffData = new Element[numSeries][]; 
    101         for (int i=0; i<numSeries; i++) { 
    102           pixels[i] = (Element) pixelsList.item(i); 
    103           NodeList list = pixels[i].getChildNodes(); 
    104           int size = list.getLength(); 
    105           v.clear(); 
    106           for (int j=0; j<size; j++) { 
    107             Node node = list.item(j); 
    108             if (!(node instanceof Element)) continue; 
    109             if ("TiffData".equals(node.getNodeName())) v.add(node); 
    110           } 
    111           tiffData[i] = new Element[v.size()]; 
    112           v.copyInto(tiffData[i]); 
    113         } 
    114       } 
    115  
    116       // MAJOR HACK : check for OME-XML in the comment of the second IFD 
    117       // There is a version of WiscScan which writes OME-XML to every IFD, 
    118       // but with SizeZ and SizeT equal to 1. 
    119  
    120       String s = null; 
    121       if (ifds.length > 1) { 
    122         s = (String) 
    123           TiffTools.getIFDValue(ifds[1], TiffTools.IMAGE_DESCRIPTION); 
    124       } 
    125       boolean isWiscScan = s != null && s.indexOf("ome.xsd") != -1; 
    126  
    127       // extract SizeZ, SizeC and SizeT from XML block 
    128       if (tiffData != null) { 
    129         boolean rgb = isRGB(); 
    130  
    131         core = new CoreMetadata(tiffData.length); 
    132         Arrays.fill(core.orderCertain, true); 
    133  
    134         for (int i=0; i<tiffData.length; i++) { 
    135           core.sizeX[i] = Integer.parseInt(pixels[i].getAttribute("SizeX")); 
    136           core.sizeY[i] = Integer.parseInt(pixels[i].getAttribute("SizeY")); 
    137           core.sizeZ[i] = Integer.parseInt(pixels[i].getAttribute("SizeZ")); 
    138           core.sizeC[i] = Integer.parseInt(pixels[i].getAttribute("SizeC")); 
    139           core.imageCount[i] = ifds.length; 
    140           int sc = core.sizeC[i]; 
    141           if (rgb) sc /= 3; 
    142           core.sizeT[i] = Integer.parseInt(pixels[i].getAttribute("SizeT")); 
    143           core.pixelType[i] = FormatTools.pixelTypeFromString( 
    144             pixels[i].getAttribute("PixelType")); 
    145           if (core.pixelType[i] == FormatTools.INT8 || 
    146             core.pixelType[i] == FormatTools.INT16 || 
    147             core.pixelType[i] == FormatTools.INT32) 
    148           { 
    149             core.pixelType[i]++; 
    150           } 
    151  
    152           // MAJOR HACK : adjust SizeT to match the number of IFDs, if this 
    153           // file was written by a buggy version of WiscScan 
    154           if (isWiscScan) core.sizeT[i] = core.imageCount[0]; 
    155  
    156           core.currentOrder[i] = pixels[i].getAttribute("DimensionOrder"); 
    157           core.orderCertain[i] = true; 
    158  
    159           boolean[][][] zct = new boolean[core.sizeZ[i]][sc][core.sizeT[i]]; 
    160  
    161           for (int j=0; j<tiffData[i].length; j++) { 
    162             String aIfd = tiffData[i][j].getAttribute("IFD"); 
    163             String aFirstZ = tiffData[i][j].getAttribute("FirstZ"); 
    164             String aFirstT = tiffData[i][j].getAttribute("FirstT"); 
    165             String aFirstC = tiffData[i][j].getAttribute("FirstC"); 
    166             String aNumPlanes = tiffData[i][j].getAttribute("NumPlanes"); 
    167             boolean nullIfd = aIfd == null || "".equals(aIfd); 
    168             boolean nullFirstZ = aFirstZ == null || "".equals(aFirstZ); 
    169             boolean nullFirstT = aFirstT == null || "".equals(aFirstT); 
    170             boolean nullFirstC = aFirstC == null || "".equals(aFirstC); 
    171             boolean nullNumPlanes = aNumPlanes == null || "".equals(aNumPlanes); 
    172             int ifd = nullIfd ? 0 : Integer.parseInt(aIfd); 
    173             int firstZ = nullFirstZ ? 0 : Integer.parseInt(aFirstZ); 
    174             int firstT = nullFirstT ? 0 : Integer.parseInt(aFirstT); 
    175             int firstC = nullFirstC ? 0 : Integer.parseInt(aFirstC); 
    176             int numPlanes = nullNumPlanes ? 
    177               (nullIfd ? core.imageCount[0] : 1) : Integer.parseInt(aNumPlanes); 
    178  
    179             // populate ZCT matrix 
    180             char d1st = core.currentOrder[i].charAt(2); 
    181             char d2nd = core.currentOrder[i].charAt(3); 
    182             int z = firstZ, t = firstT, c = firstC; 
    183  
    184             for (int k=0; k<numPlanes; k++) { 
    185               zct[z][c][t] = true; 
    186               switch (d1st) { 
    187                 case 'Z': 
    188                   z++; 
    189                   if (z >= core.sizeZ[i]) { 
    190                     z = 0; 
    191                     switch (d2nd) { 
    192                       case 'T': 
    193                         t++; 
    194                         if (t >= core.sizeT[i]) { 
    195                           t = 0; 
    196                           c++; 
    197                         } 
    198                         break; 
    199                       case 'C': 
    200                         c++; 
    201                         if (c >= sc) { 
    202                           c = 0; 
    203                           t++; 
    204                         } 
    205                         break; 
    206                     } 
    207                   } 
    208                   break; 
    209                 case 'T': 
    210                   t++; 
    211                   if (t >= core.sizeT[i]) { 
    212                     t = 0; 
    213                     switch (d2nd) { 
    214                       case 'Z': 
    215                         z++; 
    216                         if (z >= core.sizeZ[i]) { 
    217                           z = 0; 
    218                           c++; 
    219                         } 
    220                         break; 
    221                       case 'C': 
    222                         c++; 
    223                         if (c >= sc) { 
    224                           c = 0; 
    225                           z++; 
    226                         } 
    227                         break; 
    228                     } 
    229                   } 
    230                   break; 
    231                 case 'C': 
    232                   c++; 
    233                   if (c >= sc) { 
    234                     c = 0; 
    235                     switch (d2nd) { 
    236                       case 'Z': 
    237                         z++; 
    238                         if (z >= core.sizeZ[i]) { 
    239                           z = 0; 
    240                           t++; 
    241                         } 
    242                         break; 
    243                       case 'T': 
    244                         t++; 
    245                         if (t >= core.sizeT[i]) { 
    246                           t = 0; 
    247                           z++; 
    248                         } 
    249                         break; 
    250                     } 
    251                   } 
    252                   break; 
    253               } 
    254             } 
    255           } 
    256  
    257           // analyze ZCT matrix to determine best SizeZ, SizeC and SizeT 
    258           // for now, we only handle certain special cases: 
    259           boolean success = false; 
    260           int theZ, theT, theC; 
    261  
    262           // 1) all Z, all T, all C 
    263           success = true; 
    264           for (int z=0; z<core.sizeZ[i] && success; z++) { 
    265             for (int t=0; t<core.sizeT[i] && success; t++) { 
    266               for (int c=0; c<sc && success; c++) { 
    267                 if (!zct[z][c][t]) success = false; 
    268               } 
    269             } 
    270           } 
    271           if (success) { 
    272             // NB: sizes are already correct; no corrections necessary 
    273             continue; 
    274           } 
    275  
    276           // 2) single Z, all T, all C 
    277           success = true; 
    278           theZ = -1; 
    279           for (int z=0; z<core.sizeZ[i] && success; z++) { 
    280             if (zct[z][0][0]) { 
    281               if (theZ < 0) theZ = z; 
    282               else success = false; 
    283             } 
    284             boolean state = theZ == z; 
    285             for (int t=0; t<core.sizeT[i] && success; t++) { 
    286               for (int c=0; c<sc && success; c++) { 
    287                 if (zct[z][c][t] != state) success = false; 
    288               } 
    289             } 
    290           } 
    291           if (success) { 
    292             core.sizeZ[i] = 1; 
    293             continue; 
    294           } 
    295  
    296           // 3) all Z, single T, all C 
    297           success = true; 
    298           theT = -1; 
    299           for (int t=0; t<core.sizeT[i] && success; t++) { 
    300             if (zct[0][0][t]) { 
    301               if (theT < 0) theT = t; 
    302               else success = false; 
    303             } 
    304             boolean state = theT == t; 
    305             for (int z=0; z<core.sizeZ[i] && success; z++) { 
    306               for (int c=0; c<sc && success; c++) { 
    307                 if (zct[z][c][t] != state) success = false; 
    308               } 
    309             } 
    310           } 
    311           if (success) { 
    312             core.sizeT[i] = 1; 
    313             continue; 
    314           } 
    315  
    316           // 4) all Z, all T, single C 
    317           success = true; 
    318           theC = -1; 
    319           for (int c=0; c<sc && success; c++) { 
    320             if (zct[0][c][0]) { 
    321               if (theC < 0) theC = c; 
    322               else success = false; 
    323             } 
    324             boolean state = theC == c; 
    325             for (int z=0; z<core.sizeZ[i] && success; z++) { 
    326               for (int t=0; t<core.sizeT[i] && success; t++) { 
    327                 if (zct[z][c][t] != state) success = false; 
    328               } 
    329             } 
    330           } 
    331           if (success) { 
    332             core.sizeC[i] = 1; 
    333             continue; 
    334           } 
    335  
    336           // 5) single Z, single T, all C 
    337           success = true; 
    338           theZ = -1; 
    339           theT = -1; 
    340           for (int z=0; z<core.sizeZ[i] && success; z++) { 
    341             for (int t=0; t<core.sizeT[i] && success; t++) { 
    342               if (zct[z][0][t]) { 
    343                 if (theZ < 0 && theT < 0) { 
    344                   theZ = z; 
    345                   theT = t; 
    346                 } 
    347                 else success = false; 
    348               } 
    349               boolean state = theZ == z && theT == t; 
    350               for (int c=0; c<sc && success; c++) { 
    351                 if (zct[z][c][t] != state) success = false; 
    352               } 
    353             } 
    354           } 
    355           if (success) { 
    356             core.sizeZ[i] = core.sizeT[i] = 1; 
    357             continue; 
    358           } 
    359  
    360           // 6) single Z, all T, single C 
    361           success = true; 
    362           theZ = -1; 
    363           theC = -1; 
    364           for (int z=0; z<core.sizeZ[i] && success; z++) { 
    365             for (int c=0; c<sc && success; c++) { 
    366               if (zct[z][c][0]) { 
    367                 if (theZ < 0 && theC < 0) { 
    368                   theZ = z; 
    369                   theC = c; 
    370                 } 
    371                 else success = false; 
    372               } 
    373               boolean state = theZ == z && theC == c; 
    374               for (int t=0; t<core.sizeT[i] && success; t++) { 
    375                 if (zct[z][c][t] != state) success = false; 
    376               } 
    377             } 
    378           } 
    379           if (success) { 
    380             core.sizeZ[i] = core.sizeC[i] = 1; 
    381             continue; 
    382           } 
    383  
    384           // 7) all Z, single T, single C 
    385           success = true; 
    386           theT = -1; 
    387           theC = -1; 
    388           for (int t=0; t<core.sizeT[i] && success; t++) { 
    389             for (int c=0; c<sc && success; c++) { 
    390               if (zct[0][c][t]) { 
    391                 if (theC < 0 && theT < 0) { 
    392                   theC = c; 
    393                   theT = t; 
    394                 } 
    395                 else success = false; 
    396               } 
    397               boolean state = theC == c && theT == t; 
    398               for (int z=0; z<core.sizeZ[i] && success; z++) { 
    399                 if (zct[z][c][t] != state) success = false; 
    400               } 
    401             } 
    402           } 
    403           if (success) { 
    404             core.sizeT[i] = core.sizeC[i] = 1; 
    405             continue; 
    406           } 
    407  
    408           // 8) single Z, single T, single C 
    409           success = true; 
    410           theZ = -1; 
    411           theT = -1; 
    412           theC = -1; 
    413           int count = 0; 
    414           for (int z=0; z<core.sizeZ[i] && success; z++) { 
    415             for (int t=0; t<core.sizeT[i] && success; t++) { 
    416               for (int c=0; c<sc && success; c++) { 
    417                 if (zct[z][c][t]) { 
    418                   count++; 
    419                   if (count > 1) success = false; 
    420                 } 
    421               } 
    422             } 
    423           } 
    424           if (success) { 
    425             core.sizeZ[i] = core.sizeT[i] = core.sizeC[i] = 1; 
    426             continue; 
    427           } 
    428  
    429           // no easy way to chop up TiffData mappings into regular ZCT dims 
    430           throw new FormatException("Unsupported ZCT index mapping"); 
    431         } 
    432       } 
    433     } 
    434     else if (ifds.length > 1) core.orderCertain[0] = false; 
     74    if (ifds.length > 1) core.orderCertain[0] = false; 
    43575 
    43676    // check for ImageJ-style TIFF comment 
     
    464104  } 
    465105 
    466   /* @see BaseTiffReader#initMetadataStore() */ 
    467   protected void initMetadataStore() { 
    468     // check for OME-XML in TIFF comment (OME-TIFF format) 
    469     // we need an extra check to make sure that any XML we find is indeed 
    470     // OME-XML (and not some other XML variant) 
    471  
    472     String comment = (String) getMeta("Comment"); 
    473     if (comment != null && comment.indexOf("ome.xsd") >= 0) { 
    474       metadata.remove("Comment"); 
    475       boolean isOMEXML; 
    476       try { 
    477         Class omexmlMeta = 
    478           Class.forName("loci.formats.ome.OMEXMLMetadataStore"); 
    479         isOMEXML = omexmlMeta.isAssignableFrom(metadataStore.getClass()); 
    480       } 
    481       catch (Throwable t) { 
    482         isOMEXML = false; 
    483       } 
    484       if (isOMEXML) { 
    485         ReflectedUniverse r = new ReflectedUniverse(); 
    486         try { 
    487           r.exec("import loci.formats.ome.OMEXMLMetadataStore"); 
    488           r.setVar("xmlStore", metadataStore); 
    489           r.setVar("comment", comment); 
    490           r.exec("xmlStore.createRoot(comment)"); 
    491           return; 
    492         } 
    493         catch (ReflectException exc) { 
    494           // OME Java probably not available; ignore this error 
    495         } 
    496       } 
    497     } 
    498     super.initMetadataStore(); 
    499   } 
    500  
    501106} 
  • trunk/loci/formats/readers.txt

    r2940 r2943  
    8383loci.formats.in.ImprovisionTiffReader # tif 
    8484loci.formats.in.TCSReader # tif 
     85loci.formats.in.OMETiffReader # tif 
    8586 
    8687# standard TIFF reader must go last (it accepts any TIFF) 
Note: See TracChangeset for help on using the changeset viewer.