Changeset 7052


Ignore:
Timestamp:
10/08/10 14:58:00 (9 years ago)
Author:
melissa
Message:

Fixed a handful of lovely dimension detection bugs.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.1/components/bio-formats/src/loci/formats/in/SlidebookReader.java

    r5676 r7052  
    2626import java.io.EOFException; 
    2727import java.io.IOException; 
     28import java.util.Arrays; 
     29import java.util.Hashtable; 
    2830import java.util.Vector; 
    2931 
     
    4345 * 
    4446 * <dl><dt><b>Source code:</b></dt> 
    45  * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/bio-formats/src/loci/formats/in/SlidebookReader.java">Trac</a>, 
    46  * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/bio-formats/src/loci/formats/in/SlidebookReader.java">SVN</a></dd></dl> 
     47 * <dd><a href="http://dev.loci.wisc.edu/trac/java/browser/trunk/components/bio-formats/src/loci/formats/in/SlidebookReader.java">Trac</a>, 
     48 * <a href="http://dev.loci.wisc.edu/svn/java/trunk/components/bio-formats/src/loci/formats/in/SlidebookReader.java">SVN</a></dd></dl> 
    4749 * 
    48  * @author Melissa Linkert linkert at wisc.edu 
     50 * @author Melissa Linkert melissa at glencoesoftware.com 
    4951 */ 
    5052public class SlidebookReader extends FormatReader { 
     
    5254  // -- Constants -- 
    5355 
    54   public static final long SLD_MAGIC_BYTES = 0x6c000001494900L; 
     56  public static final long SLD_MAGIC_BYTES_1 = 0x6c000001L; 
     57  public static final long SLD_MAGIC_BYTES_2 = 0xf5010201L; 
     58  public static final long SLD_MAGIC_BYTES_3 = 0xf6010101L; 
    5559 
    5660  // -- Fields -- 
     
    6165  private Vector<Float> ndFilters; 
    6266 
     67  private boolean adjust = true; 
     68  private boolean isSpool; 
     69  private Hashtable<Integer, Integer> metadataInPlanes; 
     70 
    6371  // -- Constructor -- 
    6472 
    6573  /** Constructs a new Slidebook reader. */ 
    6674  public SlidebookReader() { 
    67     super("Olympus Slidebook", "sld"); 
     75    super("Olympus Slidebook", new String[] {"sld", "spl"}); 
    6876    domains = new String[] {FormatTools.LM_DOMAIN}; 
    6977  } 
     
    7583    final int blockLen = 8; 
    7684    if (!FormatTools.validStream(stream, blockLen, false)) return false; 
    77     return stream.readLong() == SLD_MAGIC_BYTES; 
     85    long magicBytes = stream.readInt(); 
     86    return magicBytes == SLD_MAGIC_BYTES_1 || magicBytes == SLD_MAGIC_BYTES_2; 
    7887  } 
    7988 
     
    9099    in.seek(offset); 
    91100 
     101    // if this is a spool file, there may be an extra metadata block here 
     102    if (isSpool) { 
     103      Integer[] keys = metadataInPlanes.keySet().toArray(new Integer[0]); 
     104      Arrays.sort(keys); 
     105      for (int key : keys) { 
     106        if (key < no) { 
     107          in.skipBytes(256); 
     108        } 
     109      } 
     110 
     111      in.order(false); 
     112      long magicBytes = (long) in.readInt() & 0xffffffffL; 
     113      in.order(isLittleEndian()); 
     114      if (magicBytes == SLD_MAGIC_BYTES_3 && !metadataInPlanes.contains(no)) { 
     115        metadataInPlanes.put(no, 0); 
     116        in.skipBytes(252); 
     117      } 
     118      else in.seek(in.getFilePointer() - 4); 
     119    } 
     120 
    92121    readPlane(in, x, y, w, h, buf); 
    93122    return buf; 
     
    100129      metadataOffsets = pixelOffsets = pixelLengths = null; 
    101130      ndFilters = null; 
     131      isSpool = false; 
     132      metadataInPlanes = null; 
     133      adjust = true; 
    102134    } 
    103135  } 
     
    110142    super.initFile(id); 
    111143    in = new RandomAccessInputStream(id); 
     144    isSpool = checkSuffix(id, "spl"); 
     145    if (isSpool) { 
     146      metadataInPlanes = new Hashtable<Integer, Integer>(); 
     147    } 
    112148 
    113149    status("Finding offsets to pixel data"); 
     
    151187 
    152188    while (in.getFilePointer() < in.length() - 8) { 
     189      debug("Looking for block at " + in.getFilePointer()); 
    153190      in.skipBytes(4); 
    154191      int checkOne = in.read(); 
     
    157194        (checkOne == 'M' && checkTwo == 'M')) 
    158195      { 
     196        debug("Found metadata offset: " + (in.getFilePointer() - 6)); 
    159197        metadataOffsets.add(new Long(in.getFilePointer() - 6)); 
    160198        in.skipBytes(in.readShort() - 8); 
     
    171209              foundBlock = true; 
    172210              in.seek(in.getFilePointer() - block.length + i - 2); 
     211              debug("Found metadata offset: " + (in.getFilePointer() - 2)); 
    173212              metadataOffsets.add(new Long(in.getFilePointer() - 2)); 
    174213              in.skipBytes(in.readShort() - 5); 
     
    238277          else in.seek(fp); 
    239278 
     279          debug("Found pixel offset at " + fp); 
    240280          pixelOffsets.add(new Long(fp)); 
    241281          try { 
     
    246286            while (!found && in.getFilePointer() < in.length()) { 
    247287              for (int i=0; i<n-6; i++) { 
    248                 if ((buf[i] == 'h' && buf[i + 1] == 0 && 
    249                   buf[i+4] == 'I' && buf[i+5] == 'I') || 
    250                   (buf[i] == 0 && buf[i+1] == 'h' && 
    251                   buf[i+4] == 'M' && buf[i+5] == 'M')) 
     288                if (((buf[i] == 'h' || buf[i] == 'i') && buf[i + 1] == 0 && 
     289                  buf[i + 4] == 'I' && buf[i + 5] == 'I') || 
     290                  (buf[i] == 0 && (buf[i + 1] == 'h' || buf[i + 1] == 'i') && 
     291                  buf[i + 4] == 'M' && buf[i + 5] == 'M')) 
    252292                { 
    253293                  found = true; 
    254294                  in.seek(in.getFilePointer() - n + i - 20); 
     295                  if (buf[i] == 'i' || buf[i + 1] == 'i') { 
     296                    pixelOffsets.remove(pixelOffsets.size() - 1); 
     297                  } 
    255298                  break; 
    256299                } 
     
    265308 
    266309            if (in.getFilePointer() <= in.length()) { 
    267               pixelLengths.add(new Long(in.getFilePointer() - fp)); 
     310              if (pixelOffsets.size() > pixelLengths.size()) { 
     311                long length = in.getFilePointer() - fp; 
     312                if (((length / 2) % 2) == 1) { 
     313                  pixelOffsets.setElementAt(fp + 2, pixelOffsets.size() - 1); 
     314                  length -= 2; 
     315                } 
     316                pixelLengths.add(new Long(length)); 
     317              } 
    268318            } 
    269319            else pixelOffsets.remove(pixelOffsets.size() - 1); 
     
    280330      long offset = pixelOffsets.get(i).longValue(); 
    281331 
    282       if (length + offset + 6 >= in.length()) { 
     332      int padding = isSpool ? 0 : 7; 
     333 
     334      if (length + offset + padding > in.length()) { 
    283335        pixelOffsets.remove(i); 
    284336        pixelLengths.remove(i); 
     
    300352    // determine total number of pixel bytes 
    301353 
    302     float pixelSize = 1; 
     354    Vector<Float> pixelSize = new Vector<Float>(); 
    303355    String objective = null; 
    304356    Vector<Float> pixelSizeZ = new Vector<Float>(); 
     
    388440              imageNames[nextName++] = in.readCString().trim(); 
    389441            } 
    390             if (core[nextName - 1].sizeX == 0 || core[nextName - 1].sizeY == 0) 
     442 
     443            long fp = in.getFilePointer(); 
     444            if ((in.getFilePointer() % 2) == 1) in.skipBytes(1); 
     445            while (in.readShort() == 0); 
     446            in.skipBytes(18); 
     447            if (in.getFilePointer() - fp > 123 && (fp % 2) == 0) { 
     448              in.seek(fp + 123); 
     449            } 
     450 
     451            int x = in.readInt(); 
     452            int y = in.readInt(); 
     453            int div = in.readShort(); 
     454            x /= (div == 0 ? 1 : div); 
     455            div = in.readShort(); 
     456            y /= (div == 0 ? 1 : div); 
     457            if (x > 16 && (x < core[nextName - 1].sizeX || 
     458              core[nextName - 1].sizeX == 0) && y > 16 && 
     459              (y < core[nextName - 1].sizeY || core[nextName - 1].sizeY == 0)) 
    391460            { 
    392               in.skipBytes(123); 
    393               core[nextName - 1].sizeX = in.readInt(); 
    394               core[nextName - 1].sizeY = in.readInt(); 
    395               int div = in.readInt(); 
    396               core[nextName - 1].sizeX /= (div == 0 ? 1 : div); 
    397               div = in.readInt(); 
    398               core[nextName - 1].sizeY /= (div == 0 ? 1 : div); 
     461              core[nextName - 1].sizeX = x; 
     462              core[nextName - 1].sizeY = y; 
     463              adjust = false; 
    399464            } 
    400465          } 
     
    413478          objective = in.readCString(); 
    414479          in.seek(fp + 144); 
    415           pixelSize = in.readFloat(); 
     480          pixelSize.add(in.readFloat()); 
    416481        } 
    417482        else if (n == 'e') { 
     
    425490        else if (n == 'k') { 
    426491          in.skipBytes(14); 
    427           setSeries(nextName - 1); 
     492          if (nextName > 0) setSeries(nextName - 1); 
    428493          addSeriesMeta("Mag. changer", in.readCString()); 
     494        } 
     495        else if (isSpool) { 
     496          // spool files don't necessarily have block identifiers 
     497          for (int j=0; j<pixelOffsets.size(); j++) { 
     498            long end = j == pixelOffsets.size() - 1 ? in.length() : 
     499              pixelOffsets.get(j + 1).longValue(); 
     500            if (in.getFilePointer() < end) { 
     501              in.skipBytes(16); 
     502              core[j].sizeX = in.readShort(); 
     503              core[j].sizeY = in.readShort(); 
     504              break; 
     505            } 
     506          } 
    429507        } 
    430508      } 
     
    435513      long pixels = pixelLengths.get(i).longValue() / 2; 
    436514      boolean x = true; 
    437       while (getSizeX() * getSizeY() * getSizeC() * getSizeZ() > pixels) { 
    438         if (x) core[i].sizeX /= 2; 
    439         else core[i].sizeY /= 2; 
    440         x = !x; 
    441       } 
     515 
    442516      if (getSizeC() == 0) core[i].sizeC = 1; 
    443517      if (getSizeZ() == 0) core[i].sizeZ = 1; 
     518 
     519      long plane = pixels / (getSizeC() * getSizeZ()); 
     520 
     521      if (adjust) { 
     522        boolean widthGreater = getSizeX() > getSizeY(); 
     523        while (getSizeX() * getSizeY() > plane) { 
     524          if (x) core[i].sizeX /= 2; 
     525          else core[i].sizeY /= 2; 
     526          x = !x; 
     527        } 
     528        while (getSizeX() * getSizeY() < plane || 
     529          (getSizeX() < getSizeY() && widthGreater)) 
     530        { 
     531          core[i].sizeX++; 
     532          core[i].sizeY = (int) (plane / getSizeX()); 
     533        } 
     534      } 
     535 
    444536      int nPlanes = getSizeZ() * getSizeC(); 
    445537      core[i].sizeT = (int) (pixels / (getSizeX() * getSizeY() * nPlanes)); 
     538      while (getSizeX() * getSizeY() * nPlanes * getSizeT() > pixels) { 
     539        core[i].sizeT--; 
     540      } 
    446541      if (getSizeT() == 0) core[i].sizeT = 1; 
    447542      core[i].imageCount = nPlanes * getSizeT(); 
     
    458553    MetadataTools.populatePixels(store, this); 
    459554 
     555    // populate Image data 
     556 
     557    for (int i=0; i<getSeriesCount(); i++) { 
     558      if (imageNames[i] != null) store.setImageName(imageNames[i], i); 
     559      MetadataTools.setDefaultCreationDate(store, id, i); 
     560    } 
     561 
    460562    // link Instrument and Image 
    461563    String instrumentID = MetadataTools.createLSID("Instrument", 0); 
     
    475577    store.setObjectiveSettingsObjective(objectiveID, 0); 
    476578 
    477     // populate Image data 
     579    // populate Dimensions data 
    478580 
    479581    for (int i=0; i<getSeriesCount(); i++) { 
    480       if (imageNames[i] != null) store.setImageName(imageNames[i], i); 
    481       MetadataTools.setDefaultCreationDate(store, id, i); 
    482     } 
    483  
    484     // populate Dimensions data 
    485  
    486     for (int i=0; i<getSeriesCount(); i++) { 
    487       store.setDimensionsPhysicalSizeX(new Float(pixelSize), i, 0); 
    488       store.setDimensionsPhysicalSizeY(new Float(pixelSize), i, 0); 
     582      if (i < pixelSize.size()) { 
     583        store.setDimensionsPhysicalSizeX(new Float(pixelSize.get(i)), i, 0); 
     584        store.setDimensionsPhysicalSizeY(new Float(pixelSize.get(i)), i, 0); 
     585      } 
    489586      int idx = 0; 
    490587      for (int q=0; q<i; q++) { 
  • branches/4.2/components/bio-formats/src/loci/formats/in/SlidebookReader.java

    r7007 r7052  
    6464  private Vector<Double> ndFilters; 
    6565 
     66  private boolean adjust = true; 
    6667  private boolean isSpool; 
    6768  private Hashtable<Integer, Integer> metadataInPlanes; 
     
    129130      isSpool = false; 
    130131      metadataInPlanes = null; 
     132      adjust = true; 
    131133    } 
    132134  } 
     
    306308            if (in.getFilePointer() <= in.length()) { 
    307309              if (pixelOffsets.size() > pixelLengths.size()) { 
    308                 pixelLengths.add(new Long(in.getFilePointer() - fp)); 
     310                long length = in.getFilePointer() - fp; 
     311                if (((length / 2) % 2) == 1) { 
     312                  pixelOffsets.setElementAt(fp + 2, pixelOffsets.size() - 1); 
     313                  length -= 2; 
     314                } 
     315                pixelLengths.add(new Long(length)); 
    309316              } 
    310317            } 
     
    432439              imageNames[nextName++] = in.readCString().trim(); 
    433440            } 
    434             if (core[nextName - 1].sizeX == 0 || core[nextName - 1].sizeY == 0) 
     441 
     442            long fp = in.getFilePointer(); 
     443            if ((in.getFilePointer() % 2) == 1) in.skipBytes(1); 
     444            while (in.readShort() == 0); 
     445            in.skipBytes(18); 
     446            if (in.getFilePointer() - fp > 123 && (fp % 2) == 0) { 
     447              in.seek(fp + 123); 
     448            } 
     449 
     450            int x = in.readInt(); 
     451            int y = in.readInt(); 
     452            int div = in.readShort(); 
     453            x /= (div == 0 ? 1 : div); 
     454            div = in.readShort(); 
     455            y /= (div == 0 ? 1 : div); 
     456            if (x > 16 && (x < core[nextName - 1].sizeX || 
     457              core[nextName - 1].sizeX == 0) && y > 16 && 
     458              (y < core[nextName - 1].sizeY || core[nextName - 1].sizeY == 0)) 
    435459            { 
    436               in.skipBytes(123); 
    437               core[nextName - 1].sizeX = in.readInt(); 
    438               core[nextName - 1].sizeY = in.readInt(); 
    439               int div = in.readInt(); 
    440               core[nextName - 1].sizeX /= (div == 0 ? 1 : div); 
    441               div = in.readInt(); 
    442               core[nextName - 1].sizeY /= (div == 0 ? 1 : div); 
     460              core[nextName - 1].sizeX = x; 
     461              core[nextName - 1].sizeY = y; 
     462              adjust = false; 
    443463            } 
    444464          } 
     
    492512      long pixels = pixelLengths.get(i).longValue() / 2; 
    493513      boolean x = true; 
    494       while (getSizeX() * getSizeY() * getSizeC() * getSizeZ() > pixels) { 
    495         if (x) core[i].sizeX /= 2; 
    496         else core[i].sizeY /= 2; 
    497         x = !x; 
    498       } 
     514 
    499515      if (getSizeC() == 0) core[i].sizeC = 1; 
    500516      if (getSizeZ() == 0) core[i].sizeZ = 1; 
     517 
     518      long plane = pixels / (getSizeC() * getSizeZ()); 
     519 
     520      if (adjust) { 
     521        boolean widthGreater = getSizeX() > getSizeY(); 
     522        while (getSizeX() * getSizeY() > plane) { 
     523          if (x) core[i].sizeX /= 2; 
     524          else core[i].sizeY /= 2; 
     525          x = !x; 
     526        } 
     527        while (getSizeX() * getSizeY() < plane || 
     528          (getSizeX() < getSizeY() && widthGreater)) 
     529        { 
     530          core[i].sizeX++; 
     531          core[i].sizeY = (int) (plane / getSizeX()); 
     532        } 
     533      } 
     534 
    501535      int nPlanes = getSizeZ() * getSizeC(); 
    502536      core[i].sizeT = (int) (pixels / (getSizeX() * getSizeY() * nPlanes)); 
  • trunk/components/bio-formats/src/loci/formats/in/SlidebookReader.java

    r6881 r7052  
    6464  private Vector<Double> ndFilters; 
    6565 
     66  private boolean adjust = true; 
    6667  private boolean isSpool; 
    6768  private Hashtable<Integer, Integer> metadataInPlanes; 
     
    129130      isSpool = false; 
    130131      metadataInPlanes = null; 
     132      adjust = true; 
    131133    } 
    132134  } 
     
    306308            if (in.getFilePointer() <= in.length()) { 
    307309              if (pixelOffsets.size() > pixelLengths.size()) { 
    308                 pixelLengths.add(new Long(in.getFilePointer() - fp)); 
     310                long length = in.getFilePointer() - fp; 
     311                if (((length / 2) % 2) == 1) { 
     312                  pixelOffsets.setElementAt(fp + 2, pixelOffsets.size() - 1); 
     313                  length -= 2; 
     314                } 
     315                pixelLengths.add(new Long(length)); 
    309316              } 
    310317            } 
     
    432439              imageNames[nextName++] = in.readCString().trim(); 
    433440            } 
    434             if (core[nextName - 1].sizeX == 0 || core[nextName - 1].sizeY == 0) 
     441 
     442            long fp = in.getFilePointer(); 
     443            if ((in.getFilePointer() % 2) == 1) in.skipBytes(1); 
     444            while (in.readShort() == 0); 
     445            in.skipBytes(18); 
     446            if (in.getFilePointer() - fp > 123 && (fp % 2) == 0) { 
     447              in.seek(fp + 123); 
     448            } 
     449 
     450            int x = in.readInt(); 
     451            int y = in.readInt(); 
     452            int div = in.readShort(); 
     453            x /= (div == 0 ? 1 : div); 
     454            div = in.readShort(); 
     455            y /= (div == 0 ? 1 : div); 
     456            if (x > 16 && (x < core[nextName - 1].sizeX || 
     457              core[nextName - 1].sizeX == 0) && y > 16 && 
     458              (y < core[nextName - 1].sizeY || core[nextName - 1].sizeY == 0)) 
    435459            { 
    436               in.skipBytes(123); 
    437               core[nextName - 1].sizeX = in.readInt(); 
    438               core[nextName - 1].sizeY = in.readInt(); 
    439               int div = in.readInt(); 
    440               core[nextName - 1].sizeX /= (div == 0 ? 1 : div); 
    441               div = in.readInt(); 
    442               core[nextName - 1].sizeY /= (div == 0 ? 1 : div); 
     460              core[nextName - 1].sizeX = x; 
     461              core[nextName - 1].sizeY = y; 
     462              adjust = false; 
    443463            } 
    444464          } 
     
    492512      long pixels = pixelLengths.get(i).longValue() / 2; 
    493513      boolean x = true; 
    494       while (getSizeX() * getSizeY() * getSizeC() * getSizeZ() > pixels) { 
    495         if (x) core[i].sizeX /= 2; 
    496         else core[i].sizeY /= 2; 
    497         x = !x; 
    498       } 
     514 
    499515      if (getSizeC() == 0) core[i].sizeC = 1; 
    500516      if (getSizeZ() == 0) core[i].sizeZ = 1; 
     517 
     518      long plane = pixels / (getSizeC() * getSizeZ()); 
     519 
     520      if (adjust) { 
     521        boolean widthGreater = getSizeX() > getSizeY(); 
     522        while (getSizeX() * getSizeY() > plane) { 
     523          if (x) core[i].sizeX /= 2; 
     524          else core[i].sizeY /= 2; 
     525          x = !x; 
     526        } 
     527        while (getSizeX() * getSizeY() < plane || 
     528          (getSizeX() < getSizeY() && widthGreater)) 
     529        { 
     530          core[i].sizeX++; 
     531          core[i].sizeY = (int) (plane / getSizeX()); 
     532        } 
     533      } 
     534 
    501535      int nPlanes = getSizeZ() * getSizeC(); 
    502536      core[i].sizeT = (int) (pixels / (getSizeX() * getSizeY() * nPlanes)); 
Note: See TracChangeset for help on using the changeset viewer.