Changeset 1759


Ignore:
Timestamp:
11/07/06 18:19:08 (13 years ago)
Author:
curtis
Message:

1) Add (far too much) logic to TiffReader to handle proper setting of

C, Z and T sizes for OME-TIFF.

2) Make BaseTiffReader's initStandardMetadata method throw FormatException,

so that subclasses (i.e., TiffReader) can object in certain cases
(i.e., when an OME-TIFF block is not formulated properly).

Location:
trunk/loci/formats/in
Files:
8 edited

Legend:

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

    r1755 r1759  
    100100 
    101101  /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
    102   protected void initStandardMetadata() { 
     102  protected void initStandardMetadata() throws FormatException { 
    103103    super.initStandardMetadata(); 
    104104 
  • trunk/loci/formats/in/BaseTiffReader.java

    r1755 r1759  
    113113 
    114114  /** Populates the metadata hashtable and metadata store. */ 
    115   protected void initMetadata() { 
     115  protected void initMetadata() throws FormatException { 
    116116    initStandardMetadata(); 
    117117    initMetadataStore(); 
     
    125125   * overwritten if you do so. 
    126126   */ 
    127   protected void initStandardMetadata() { 
     127  protected void initStandardMetadata() throws FormatException { 
    128128    Hashtable ifd = ifds[0]; 
    129129    if (metadata == null) metadata = new Hashtable(); 
  • trunk/loci/formats/in/FluoviewReader.java

    r1672 r1759  
    109109 
    110110  /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
    111   protected void initStandardMetadata() { 
     111  protected void initStandardMetadata() throws FormatException { 
    112112    super.initStandardMetadata(); 
    113113 
  • trunk/loci/formats/in/GelReader.java

    r1671 r1759  
    6262 
    6363  /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
    64   protected void initStandardMetadata() { 
     64  protected void initStandardMetadata() throws FormatException { 
    6565    super.initStandardMetadata(); 
    6666 
  • trunk/loci/formats/in/MetamorphReader.java

    r1671 r1759  
    108108 
    109109  /** Populates the metadata hashtable. */ 
    110   protected void initStandardMetadata() { 
     110  protected void initStandardMetadata() throws FormatException { 
    111111    super.initStandardMetadata(); 
    112112 
  • trunk/loci/formats/in/NikonReader.java

    r1755 r1759  
    229229 
    230230  /* @see BaseTiffReader#initStandardMetadata() */ 
    231   protected void initStandardMetadata() { 
     231  protected void initStandardMetadata() throws FormatException { 
    232232    super.initStandardMetadata(); 
    233233 
  • trunk/loci/formats/in/SEQReader.java

    r1645 r1759  
    6161 
    6262  /** Overridden to include the three SEQ-specific tags. */ 
    63   protected void initStandardMetadata() { 
     63  protected void initStandardMetadata() throws FormatException { 
    6464    super.initStandardMetadata(); 
    6565 
  • trunk/loci/formats/in/TiffReader.java

    r1755 r1759  
    2525package loci.formats.in; 
    2626 
     27import java.io.ByteArrayInputStream; 
    2728import java.io.IOException; 
    2829import java.util.StringTokenizer; 
     30import java.util.Vector; 
     31import javax.xml.parsers.*; 
    2932import loci.formats.*; 
     33import org.w3c.dom.*; 
     34import org.xml.sax.SAXException; 
    3035 
    3136/** 
    32  * TiffReader is the file format reader for TIFF files. 
     37 * TiffReader is the file format reader for TIFF files, including OME-TIFF. 
    3338 * 
    3439 * @author Curtis Rueden ctrueden at wisc.edu 
    3540 * @author Melissa Linkert linkert at cs.wisc.edu 
    3641 */ 
    37  
    3842public class TiffReader extends BaseTiffReader { 
    3943 
     
    5256   * that is inserted into the metadata store. 
    5357   * @param zSize the number of optical sections to use when making a call to 
    54    * {@link MetadataStore#setPixels(Integer, Integer, Integer, Integer, 
    55    *   Integer, Integer, Boolean, String, Integer)}. 
     58   * {@link loci.formats.MetadataStore#setPixels(Integer, Integer, Integer, 
     59   *   Integer, Integer, Integer, Boolean, String, Integer)}. 
    5660   */ 
    5761  protected void setSizeZ(int zSize) { 
     
    6367 
    6468  /** Parses standard metadata. */ 
    65   protected void initStandardMetadata() { 
     69  protected void initStandardMetadata() throws FormatException { 
    6670    super.initStandardMetadata(); 
    6771    String comment = (String) metadata.get("Comment"); 
     72 
     73    // check for OME-XML in TIFF comment (OME-TIFF format) 
     74    boolean omeTiff = comment != null && comment.indexOf("ome.xsd") >= 0; 
     75    put("OME-TIFF", omeTiff ? "yes" : "no"); 
     76    if (omeTiff) { 
     77      // convert string to DOM 
     78      ByteArrayInputStream is = new ByteArrayInputStream(comment.getBytes()); 
     79      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     80      Document doc = null; 
     81      try { 
     82        DocumentBuilder builder = factory.newDocumentBuilder(); 
     83        doc = builder.parse(is); 
     84      } 
     85      catch (ParserConfigurationException exc) { } 
     86      catch (SAXException exc) { } 
     87      catch (IOException exc) { } 
     88 
     89      // extract TiffData elements from XML 
     90      Element[] pixels = null; 
     91      Element[][] tiffData = null; 
     92      if (doc != null) { 
     93        NodeList pixelsList = doc.getElementsByTagName("Pixels"); 
     94        int numSeries = pixelsList.getLength(); 
     95        Vector v = new Vector(); 
     96        pixels = new Element[numSeries]; 
     97        tiffData = new Element[numSeries][]; 
     98        for (int i=0; i<numSeries; i++) { 
     99          pixels[i] = (Element) pixelsList.item(i); 
     100          NodeList list = pixels[i].getChildNodes(); 
     101          int size = list.getLength(); 
     102          v.clear(); 
     103          for (int j=0; j<size; j++) { 
     104            Node node = list.item(j); 
     105            if (!(node instanceof Element)) continue; 
     106            if ("TiffData".equals(node.getNodeName())) v.add(node); 
     107          } 
     108          tiffData[i] = new Element[v.size()]; 
     109          v.copyInto(tiffData[i]); 
     110        } 
     111      } 
     112 
     113      // extract SizeZ, SizeC and SizeT from XML block 
     114      if (tiffData != null) { 
     115        boolean rgb = false; 
     116        try { 
     117          rgb = isRGB(currentId); 
     118        } 
     119        catch (IOException exc) { 
     120          throw new FormatException(exc); 
     121        } 
     122        sizeX = new int[tiffData.length]; 
     123        sizeY = new int[tiffData.length]; 
     124        sizeZ = new int[tiffData.length]; 
     125        sizeC = new int[tiffData.length]; 
     126        sizeT = new int[tiffData.length]; 
     127        pixelType = new int[tiffData.length]; 
     128        currentOrder = new String[tiffData.length]; 
     129        orderCertain = new boolean[tiffData.length]; 
     130 
     131        for (int i=0; i<tiffData.length; i++) { 
     132          sizeX[i] = Integer.parseInt(pixels[i].getAttribute("SizeX")); 
     133          sizeY[i] = Integer.parseInt(pixels[i].getAttribute("SizeY")); 
     134          sizeZ[i] = Integer.parseInt(pixels[i].getAttribute("SizeZ")); 
     135          sizeC[i] = Integer.parseInt(pixels[i].getAttribute("SizeC")); 
     136          int sc = sizeC[i]; 
     137          if (rgb) sc /= 3; 
     138          sizeT[i] = Integer.parseInt(pixels[i].getAttribute("SizeT")); 
     139          pixelType[i] = FormatReader.pixelTypeFromString( 
     140            pixels[i].getAttribute("PixelType")); 
     141          currentOrder[i] = pixels[i].getAttribute("DimensionOrder"); 
     142          orderCertain[i] = true; 
     143 
     144          boolean[][][] zct = new boolean[sizeZ[i]][sc][sizeT[i]]; 
     145 
     146          for (int j=0; j<tiffData[i].length; j++) { 
     147            String aIfd = tiffData[i][j].getAttribute("IFD"); 
     148            String aFirstZ = tiffData[i][j].getAttribute("FirstZ"); 
     149            String aFirstT = tiffData[i][j].getAttribute("FirstT"); 
     150            String aFirstC = tiffData[i][j].getAttribute("FirstC"); 
     151            String aNumPlanes = tiffData[i][j].getAttribute("NumPlanes"); 
     152            boolean nullIfd = aIfd == null || "".equals(aIfd); 
     153            boolean nullFirstZ = aFirstZ == null || "".equals(aFirstZ); 
     154            boolean nullFirstT = aFirstT == null || "".equals(aFirstT); 
     155            boolean nullFirstC = aFirstC == null || "".equals(aFirstC); 
     156            boolean nullNumPlanes = aNumPlanes == null || "".equals(aNumPlanes); 
     157            int ifd = nullIfd ? 0 : Integer.parseInt(aIfd); 
     158            int firstZ = nullFirstZ ? 0 : Integer.parseInt(aFirstZ); 
     159            int firstT = nullFirstT ? 0 : Integer.parseInt(aFirstT); 
     160            int firstC = nullFirstC ? 0 : Integer.parseInt(aFirstC); 
     161            int numPlanes = nullNumPlanes ? 
     162              (nullIfd ? numImages : 1) : Integer.parseInt(aNumPlanes); 
     163 
     164            // populate ZCT matrix 
     165            char d1st = currentOrder[i].charAt(2); 
     166            char d2nd = currentOrder[i].charAt(3); 
     167            int z = firstZ, t = firstT, c = firstC; 
     168            for (int k=0; k<numPlanes; k++) { 
     169              zct[z][c][t] = true; 
     170              switch (d1st) { 
     171                case 'Z': 
     172                  z++; 
     173                  if (z >= sizeZ[i]) { 
     174                    z = 0; 
     175                    switch (d2nd) { 
     176                      case 'T': 
     177                        t++; 
     178                        if (t >= sizeT[i]) { 
     179                          t = 0; 
     180                          c++; 
     181                        } 
     182                        break; 
     183                      case 'C': 
     184                        c++; 
     185                        if (c >= sc) { 
     186                          c = 0; 
     187                          t++; 
     188                        } 
     189                        break; 
     190                    } 
     191                  } 
     192                  break; 
     193                case 'T': 
     194                  t++; 
     195                  if (t >= sizeT[i]) { 
     196                    t = 0; 
     197                    switch (d2nd) { 
     198                      case 'Z': 
     199                        z++; 
     200                        if (z >= sizeZ[i]) { 
     201                          z = 0; 
     202                          c++; 
     203                        } 
     204                        break; 
     205                      case 'C': 
     206                        c++; 
     207                        if (c >= sc) { 
     208                          c = 0; 
     209                          z++; 
     210                        } 
     211                        break; 
     212                    } 
     213                  } 
     214                  break; 
     215                case 'C': 
     216                  c++; 
     217                  if (c >= sc) { 
     218                    c = 0; 
     219                    switch (d2nd) { 
     220                      case 'Z': 
     221                        z++; 
     222                        if (z >= sizeZ[i]) { 
     223                          z = 0; 
     224                          t++; 
     225                        } 
     226                        break; 
     227                      case 'T': 
     228                        t++; 
     229                        if (t >= sizeT[i]) { 
     230                          t = 0; 
     231                          z++; 
     232                        } 
     233                        break; 
     234                    } 
     235                  } 
     236                  break; 
     237              } 
     238            } 
     239          } 
     240 
     241          // analyze ZCT matrix to determine best SizeZ, SizeC and SizeT 
     242          // for now, we only handle certain special cases: 
     243          boolean success = false; 
     244          int theZ, theT, theC; 
     245 
     246          // 1) all Z, all T, all C 
     247          success = true; 
     248          for (int z=0; z<sizeZ[i] && success; z++) { 
     249            for (int t=0; t<sizeT[i] && success; t++) { 
     250              for (int c=0; c<sc && success; c++) { 
     251                if (!zct[z][c][t]) success = false; 
     252              } 
     253            } 
     254          } 
     255          if (success) { 
     256            // NB: sizes are already correct; no corrections necessary 
     257            continue; 
     258          } 
     259 
     260          // 2) single Z, all T, all C 
     261          success = true; 
     262          theZ = -1; 
     263          for (int z=0; z<sizeZ[i] && success; z++) { 
     264            if (zct[z][0][0]) { 
     265              if (theZ < 0) theZ = z; 
     266              else success = false; 
     267            } 
     268            boolean state = theZ == z; 
     269            for (int t=0; t<sizeT[i] && success; t++) { 
     270              for (int c=0; c<sc && success; c++) { 
     271                if (zct[z][c][t] != state) success = false; 
     272              } 
     273            } 
     274          } 
     275          if (success) { 
     276            sizeZ[i] = 1; 
     277            continue; 
     278          } 
     279 
     280          // 3) all Z, single T, all C 
     281          success = true; 
     282          theT = -1; 
     283          for (int t=0; t<sizeT[i] && success; t++) { 
     284            if (zct[0][0][t]) { 
     285              if (theT < 0) theT = t; 
     286              else success = false; 
     287            } 
     288            boolean state = theT == t; 
     289            for (int z=0; z<sizeZ[i] && success; z++) { 
     290              for (int c=0; c<sc && success; c++) { 
     291                if (zct[z][c][t] != state) success = false; 
     292              } 
     293            } 
     294          } 
     295          if (success) { 
     296            sizeT[i] = 1; 
     297            continue; 
     298          } 
     299 
     300          // 4) all Z, all T, single C 
     301          success = true; 
     302          theC = -1; 
     303          for (int c=0; c<sc && success; c++) { 
     304            if (zct[0][c][0]) { 
     305              if (theC < 0) theC = c; 
     306              else success = false; 
     307            } 
     308            boolean state = theC == c; 
     309            for (int z=0; z<sizeZ[i] && success; z++) { 
     310              for (int t=0; t<sizeT[i] && success; t++) { 
     311                if (zct[z][c][t] != state) success = false; 
     312              } 
     313            } 
     314          } 
     315          if (success) { 
     316            sizeC[i] = 1; 
     317            continue; 
     318          } 
     319 
     320          // 5) single Z, single T, all C 
     321          success = true; 
     322          theZ = -1; 
     323          theT = -1; 
     324          for (int z=0; z<sizeZ[i] && success; z++) { 
     325            for (int t=0; t<sizeT[i] && success; t++) { 
     326              if (zct[z][0][t]) { 
     327                if (theZ < 0 && theT < 0) { 
     328                  theZ = z; 
     329                  theT = t; 
     330                } 
     331                else success = false; 
     332              } 
     333              boolean state = theZ == z && theT == t; 
     334              for (int c=0; c<sc && success; c++) { 
     335                if (zct[z][c][t] != state) success = false; 
     336              } 
     337            } 
     338          } 
     339          if (success) { 
     340            sizeZ[i] = sizeT[i] = 1; 
     341            continue; 
     342          } 
     343 
     344          // 6) single Z, all T, single C 
     345          success = true; 
     346          theZ = -1; 
     347          theC = -1; 
     348          for (int z=0; z<sizeZ[i] && success; z++) { 
     349            for (int c=0; c<sc && success; c++) { 
     350              if (zct[z][c][0]) { 
     351                if (theZ < 0 && theC < 0) { 
     352                  theZ = z; 
     353                  theC = c; 
     354                } 
     355                else success = false; 
     356              } 
     357              boolean state = theZ == z && theC == c; 
     358              for (int t=0; t<sizeT[i] && success; t++) { 
     359                if (zct[z][c][t] != state) success = false; 
     360              } 
     361            } 
     362          } 
     363          if (success) { 
     364            sizeZ[i] = sizeC[i] = 1; 
     365            continue; 
     366          } 
     367 
     368          // 7) all Z, single T, single C 
     369          success = true; 
     370          theT = -1; 
     371          theC = -1; 
     372          for (int t=0; t<sizeT[i] && success; t++) { 
     373            for (int c=0; c<sc && success; c++) { 
     374              if (zct[0][c][t]) { 
     375                if (theC < 0 && theT < 0) { 
     376                  theC = c; 
     377                  theT = t; 
     378                } 
     379                else success = false; 
     380              } 
     381              boolean state = theC == c && theT == t; 
     382              for (int z=0; z<sizeZ[i] && success; z++) { 
     383                if (zct[z][c][t] != state) success = false; 
     384              } 
     385            } 
     386          } 
     387          if (success) { 
     388            sizeT[i] = sizeC[i] = 1; 
     389            continue; 
     390          } 
     391 
     392          // 8) single Z, single T, single C 
     393          success = true; 
     394          theZ = -1; 
     395          theT = -1; 
     396          theC = -1; 
     397          int count = 0; 
     398          for (int z=0; z<sizeZ[i] && success; z++) { 
     399            for (int t=0; t<sizeT[i] && success; t++) { 
     400              for (int c=0; c<sc && success; c++) { 
     401                if (zct[z][c][t]) { 
     402                  count++; 
     403                  if (count > 1) success = false; 
     404                } 
     405              } 
     406            } 
     407          } 
     408          if (success) { 
     409            sizeZ[i] = sizeT[i] = sizeC[i] = 1; 
     410            continue; 
     411          } 
     412 
     413          // no easy way to chop up TiffData mappings into regular ZCT dims 
     414          throw new FormatException("Unsupported ZCT index mapping"); 
     415        } 
     416      } 
     417    } 
     418    else if (ifds.length > 1) orderCertain[0] = false; 
    68419 
    69420    // check for ImageJ-style TIFF comment 
     
    91442      metadata.remove("Comment"); 
    92443    } 
    93  
    94     if (comment != null) orderCertain[0] = comment.indexOf("ome.xsd") >= 0; 
    95     else if (ifds.length > 1) orderCertain[0] = false; 
    96444  } 
    97445 
     
    101449    // we need an extra check to make sure that any XML we find is indeed 
    102450    // OME-XML (and not some other XML variant) 
    103     MetadataStore store = new DummyMetadataStore(); 
    104     try { 
    105       store = getMetadataStore(currentId); 
     451 
     452    String comment = (String) metadata.get("Comment"); 
     453    if (comment != null && comment.indexOf("ome.xsd") >= 0) { 
     454      metadata.remove("Comment"); 
     455      if (metadataStore instanceof OMEXMLMetadataStore) { 
     456        OMEXMLMetadataStore xmlStore = (OMEXMLMetadataStore) metadataStore; 
     457        xmlStore.createRoot(comment); 
     458        return; 
     459      } 
    106460    } 
    107     catch (Exception e) { } 
    108  
    109     String comment = (String) metadata.get("Comment"); 
    110     if (store instanceof OMEXMLMetadataStore && 
    111       comment != null && comment.indexOf("ome.xsd") >= 0) 
    112     { 
    113       OMEXMLMetadataStore xmlStore = (OMEXMLMetadataStore) store; 
    114       xmlStore.createRoot(comment); 
    115     } 
    116     else super.initMetadataStore(); 
     461    super.initMetadataStore(); 
     462  } 
     463 
     464  // -- IFormatReader methods -- 
     465 
     466  /* @see loci.formats.IFormatReader#getSeriesCount(String) */ 
     467  public int getSeriesCount(String id) throws FormatException, IOException { 
     468    if (!id.equals(currentId)) initFile(id); 
     469    return currentOrder.length; 
    117470  } 
    118471 
Note: See TracChangeset for help on using the changeset viewer.