Changeset 6116


Ignore:
Timestamp:
04/12/10 15:44:36 (10 years ago)
Author:
melissa
Message:

Updated a few more readers to respect MetadataOptions.

Location:
trunk/components/bio-formats/src/loci/formats/in
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/in/EPSReader.java

    r6026 r6116  
    2525 
    2626import java.io.IOException; 
    27 import java.util.StringTokenizer; 
    2827 
    2928import loci.common.RandomAccessInputStream; 
     
    5251  // -- Fields -- 
    5352 
    54   /** Bits per sample. */ 
    55   private int bps; 
    56  
    5753  /** Starting line of pixel data. */ 
    5854  private int start; 
     
    152148    super.close(fileOnly); 
    153149    if (!fileOnly) { 
    154       bps = start = 0; 
     150      start = 0; 
    155151      binary = isTiff = false; 
    156152      ifds = null; 
     
    196192      core[0].interleaved = true; 
    197193      core[0].rgb = getSizeC() > 1; 
    198  
    199       bps = firstIFD.getBitsPerSample()[0]; 
    200       switch (bps) { 
    201         case 16: 
    202           core[0].pixelType = FormatTools.UINT16; 
    203           break; 
    204         case 32: 
    205           core[0].pixelType = FormatTools.UINT32; 
    206           break; 
    207         default: 
    208           core[0].pixelType = FormatTools.UINT8; 
    209       } 
     194      core[0].pixelType = firstIFD.getPixelType(); 
    210195 
    211196      core[0].imageCount = 1; 
     
    235220        if (!line.startsWith(image)) { 
    236221          if (line.indexOf("colorimage") != -1) core[0].sizeC = 3; 
    237           StringTokenizer t = new StringTokenizer(line, " "); 
     222          String[] t = line.split(" "); 
    238223          try { 
    239             core[0].sizeX = Integer.parseInt(t.nextToken()); 
    240             core[0].sizeY = Integer.parseInt(t.nextToken()); 
    241             bps = Integer.parseInt(t.nextToken()); 
     224            core[0].sizeX = Integer.parseInt(t[0]); 
     225            core[0].sizeY = Integer.parseInt(t[1]); 
    242226          } 
    243227          catch (NumberFormatException exc) { 
    244228            LOGGER.debug("Could not parse image dimensions", exc); 
    245             core[0].sizeC = Integer.parseInt(t.nextToken()); 
     229            core[0].sizeC = Integer.parseInt(t[3]); 
    246230          } 
    247231        } 
     
    253237        if (line.startsWith("%%BoundingBox:")) { 
    254238          line = line.substring(14); 
    255           StringTokenizer t = new StringTokenizer(line, " "); 
    256           int originX = Integer.parseInt(t.nextToken().trim()); 
    257           int originY = Integer.parseInt(t.nextToken().trim()); 
    258           core[0].sizeX = Integer.parseInt(t.nextToken().trim()) - originX; 
    259           core[0].sizeY = Integer.parseInt(t.nextToken().trim()) - originY; 
     239          String[] t = line.split(" "); 
     240          int originX = Integer.parseInt(t[0].trim()); 
     241          int originY = Integer.parseInt(t[1].trim()); 
     242          core[0].sizeX = Integer.parseInt(t[2].trim()) - originX; 
     243          core[0].sizeY = Integer.parseInt(t[3].trim()) - originY; 
    260244 
    261245          addGlobalMeta("X-coordinate of origin", originX); 
     
    278262      else if (line.startsWith("%ImageData:")) { 
    279263        line = line.substring(11); 
    280         StringTokenizer t = new StringTokenizer(line, " "); 
    281         core[0].sizeX = Integer.parseInt(t.nextToken()); 
    282         core[0].sizeY = Integer.parseInt(t.nextToken()); 
    283         bps = Integer.parseInt(t.nextToken()); 
    284         core[0].sizeC = Integer.parseInt(t.nextToken()); 
    285         while (t.hasMoreTokens()) { 
    286           image = t.nextToken().trim(); 
     264        String[] t = line.split(" "); 
     265        core[0].sizeX = Integer.parseInt(t[0]); 
     266        core[0].sizeY = Integer.parseInt(t[1]); 
     267        core[0].sizeC = Integer.parseInt(t[3]); 
     268        for (int i=4; i<t.length; i++) { 
     269          image = t[i].trim(); 
    287270          if (image.length() > 1) { 
    288271            image = image.substring(1, image.length() - 1); 
     
    295278 
    296279    LOGGER.info("Populating metadata"); 
    297  
    298     if (bps == 0) bps = 8; 
    299280 
    300281    if (getSizeC() == 0) core[0].sizeC = 1; 
  • trunk/components/bio-formats/src/loci/formats/in/FEIReader.java

    r6026 r6116  
    116116    LOGGER.info("Reading file header"); 
    117117 
    118     in.skipBytes(44); 
     118    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.ALL) { 
     119      in.skipBytes(44); 
    119120 
    120     float magnification = in.readFloat(); 
    121     float kV = in.readFloat() / 1000; 
    122     float wd = in.readFloat(); 
    123     in.skipBytes(12); 
    124     float spot = in.readFloat(); 
     121      float magnification = in.readFloat(); 
     122      float kV = in.readFloat() / 1000; 
     123      float wd = in.readFloat(); 
     124      in.skipBytes(12); 
     125      float spot = in.readFloat(); 
     126 
     127      addGlobalMeta("Magnification", magnification); 
     128      addGlobalMeta("kV", kV); 
     129      addGlobalMeta("Working distance", wd); 
     130      addGlobalMeta("Spot", spot); 
     131    } 
    125132 
    126133    in.seek(514); 
  • trunk/components/bio-formats/src/loci/formats/in/FitsReader.java

    r6026 r6116  
    4646public class FitsReader extends FormatReader { 
    4747 
     48  // -- Constants -- 
     49 
     50  private static final int LINE_LENGTH = 80; 
     51 
    4852  // -- Fields -- 
    4953 
    50   /** Number of lines in the header. */ 
    51   private int count; 
     54  private long pixelOffset; 
    5255 
    5356  // -- Constructor -- 
     
    7073    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); 
    7174 
    72     in.seek(2880 * ((((count * 80) - 1) / 2880) + 1)); 
     75    in.seek(pixelOffset); 
    7376    readPlane(in, x, y, w, h, buf); 
    7477    return buf; 
     
    7881  public void close(boolean fileOnly) throws IOException { 
    7982    super.close(fileOnly); 
    80     if (!fileOnly) count = 0; 
     83    if (!fileOnly) pixelOffset = 0; 
    8184  } 
    8285 
     
    8790    super.initFile(id); 
    8891    in = new RandomAccessInputStream(id); 
    89     count = 1; 
    9092 
    91     String line = in.readString(80); 
     93    String line = in.readString(LINE_LENGTH); 
    9294    if (!line.startsWith("SIMPLE")) { 
    9395      throw new FormatException("Unsupported FITS file."); 
     
    9698    String key = "", value = ""; 
    9799    while (true) { 
    98       count++; 
    99       line = in.readString(80); 
     100      line = in.readString(LINE_LENGTH); 
    100101 
    101102      // parse key/value pair 
     
    143144      addGlobalMeta(key, value); 
    144145    } 
     146    while (in.read() == 0x20); 
     147    pixelOffset = in.getFilePointer() - 1; 
    145148 
    146149    core[0].sizeC = 1; 
  • trunk/components/bio-formats/src/loci/formats/in/FluoviewReader.java

    r6062 r6116  
    7575  // hardware settings 
    7676  private String[] gains, voltages, offsets, channelNames, lensNA; 
    77   private String mag, detManu, objManu, comment; 
    78   private Double gamma; 
     77  private String mag, detectorManufacturer, objectiveManufacturer, comment; 
    7978 
    8079  // -- Constructor -- 
     
    107106    throws FormatException, IOException 
    108107  { 
     108    int image = getImageIndex(no); 
     109 
     110    if (getSizeY() == ifds.get(0).getImageLength()) { 
     111      tiffParser.getSamples(ifds.get(image), buf, x, y, w, h); 
     112    } 
     113    else { 
     114      FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); 
     115      tiffParser.getSamples(ifds.get(0), buf, x, image, w, 1); 
     116    } 
     117 
     118    return buf; 
     119  } 
     120 
     121  /* @see loci.formats.IFormatReader#close(boolean) */ 
     122  public void close(boolean fileOnly) throws IOException { 
     123    super.close(fileOnly); 
     124    if (!fileOnly) { 
     125      voxelX = voxelY = voxelZ = voxelC = voxelT = 1; 
     126      dimensionOrder = null; 
     127      gains = voltages = offsets = channelNames = lensNA = null; 
     128      mag = detectorManufacturer = objectiveManufacturer = comment = null; 
     129      date = null; 
     130      timeIndex = -1; 
     131      stamps = null; 
     132    } 
     133  } 
     134 
     135  // -- Internal BaseTiffReader API methods -- 
     136 
     137  /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
     138  protected void initStandardMetadata() throws FormatException, IOException { 
     139    super.initStandardMetadata(); 
     140 
     141    // First, we want to determine whether this file is a Fluoview TIFF. 
     142    // Originally, Andor TIFF had its own reader; however, the two formats are 
     143    // very similar, so it made more sense to merge the two formats into one 
     144    // reader. 
     145 
     146    short[] s = ifds.get(0).getIFDShortArray(MMHEADER); 
     147    if (s == null) { 
     148      throw new FormatException("Invalid Fluoview/Andor TIFF. Tag " + 
     149        MMHEADER + " not found."); 
     150    } 
     151    byte[] mmheader = shortArrayToBytes(s); 
     152 
     153    RandomAccessInputStream ras = new RandomAccessInputStream(mmheader); 
     154    ras.order(isLittleEndian()); 
     155 
     156    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.ALL) { 
     157      put("Header Flag", ras.readShort()); 
     158      put("Image Type", ras.read()); 
     159 
     160      put("Image name", ras.readString(257)); 
     161 
     162      ras.skipBytes(4); // skip pointer to data field 
     163 
     164      put("Number of colors", ras.readInt()); 
     165      ras.skipBytes(4); // skip pointer to palette field 
     166      ras.skipBytes(4); // skip pointer to other palette field 
     167 
     168      put("Comment size", ras.readInt()); 
     169      ras.skipBytes(4); // skip pointer to comment field 
     170    } 
     171    else ras.skipBytes(284); 
     172 
     173    // read dimension information 
     174    String[] names = new String[10]; 
     175    int[] sizes = new int[10]; 
     176    double[] resolutions = new double[10]; 
     177    for (int i=0; i<10; i++) { 
     178      names[i] = ras.readString(16); 
     179      sizes[i] = ras.readInt(); 
     180      double origin = ras.readDouble(); 
     181      resolutions[i] = ras.readDouble(); 
     182 
     183      put("Dimension " + (i + 1) + " Name", names[i]); 
     184      put("Dimension " + (i + 1) + " Size", sizes[i]); 
     185      put("Dimension " + (i + 1) + " Origin", origin); 
     186      put("Dimension " + (i + 1) + " Resolution", resolutions[i]); 
     187      put("Dimension " + (i + 1) + " Units", ras.readString(64)); 
     188    } 
     189 
     190    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.ALL) { 
     191      ras.skipBytes(4); // skip pointer to spatial position data 
     192 
     193      put("Map type", ras.readShort()); 
     194      put("Map min", ras.readDouble()); 
     195      put("Map max", ras.readDouble()); 
     196      put("Min value", ras.readDouble()); 
     197      put("Max value", ras.readDouble()); 
     198 
     199      ras.skipBytes(4); // skip pointer to map data 
     200 
     201      put("Gamma", ras.readDouble()); 
     202      put("Offset", ras.readDouble()); 
     203 
     204      // read gray channel data 
     205      put("Gray Channel Name", ras.readString(16)); 
     206      put("Gray Channel Size", ras.readInt()); 
     207      put("Gray Channel Origin", ras.readDouble()); 
     208      put("Gray Channel Resolution", ras.readDouble()); 
     209      put("Gray Channel Units", ras.readString(64)); 
     210 
     211      ras.skipBytes(4); // skip pointer to thumbnail data 
     212 
     213      put("Voice field", ras.readInt()); 
     214      ras.skipBytes(4); // skip pointer to voice field 
     215 
     216      // now we need to read the MMSTAMP data to determine dimension order 
     217 
     218      readStamps(); 
     219    } 
     220    ras.close(); 
     221 
     222    // calculate the dimension order and axis sizes 
     223 
     224    dimensionOrder = "XY"; 
     225    int seriesCount = 1; 
     226    core[0].sizeZ = core[0].sizeC = core[0].sizeT = 1; 
     227 
     228    for (int i=0; i<10; i++) { 
     229      String name = names[i]; 
     230      int size = sizes[i]; 
     231      double voxel = resolutions[i]; 
     232      if (name == null || size == 0) continue; 
     233      name = name.toLowerCase().trim(); 
     234      if (name.length() == 0) continue; 
     235 
     236      if (name.equals("x")) { 
     237        voxelX = voxel; 
     238      } 
     239      else if (name.equals("y")) { 
     240        voxelY = voxel; 
     241      } 
     242      else if (name.equals("z") || name.equals("event")) { 
     243        core[0].sizeZ *= size; 
     244        if (dimensionOrder.indexOf("Z") == -1) { 
     245          dimensionOrder += "Z"; 
     246        } 
     247        voxelZ = voxel; 
     248      } 
     249      else if (name.equals("ch") || name.equals("wavelength")) { 
     250        core[0].sizeC *= size; 
     251        if (dimensionOrder.indexOf("C") == -1) { 
     252          dimensionOrder += "C"; 
     253        } 
     254        voxelC = voxel; 
     255      } 
     256      else if (name.equals("time") || name.equals("t") || 
     257        name.equals("animation")) 
     258      { 
     259        core[0].sizeT *= size; 
     260        if (dimensionOrder.indexOf("T") == -1) { 
     261          dimensionOrder += "T"; 
     262        } 
     263        voxelT = voxel; 
     264        timeIndex = i - 2; 
     265      } 
     266      else { 
     267        if (dimensionOrder.indexOf("S") == -1) dimensionOrder += "S"; 
     268        seriesCount *= size; 
     269      } 
     270    } 
     271 
     272    if (dimensionOrder.indexOf("Z") == -1) dimensionOrder += "Z"; 
     273    if (dimensionOrder.indexOf("T") == -1) dimensionOrder += "T"; 
     274    if (dimensionOrder.indexOf("C") == -1) dimensionOrder += "C"; 
     275    if (dimensionOrder.indexOf("S") == -1) dimensionOrder += "S"; 
     276 
     277    core[0].imageCount = ifds.size() / seriesCount; 
     278    if (getSizeZ() > getImageCount()) core[0].sizeZ = getImageCount(); 
     279    if (getSizeT() > getImageCount()) core[0].sizeT = getImageCount(); 
     280 
     281    if (getImageCount() == 1 && (getSizeT() == getSizeY() || 
     282      getSizeZ() == getSizeY()) && (getSizeT() > getImageCount() || 
     283      getSizeZ() > getImageCount())) 
     284    { 
     285      core[0].sizeY = 1; 
     286      core[0].imageCount = getSizeZ() * getSizeC() * getSizeT(); 
     287    } 
     288    core[0].dimensionOrder = dimensionOrder.replaceAll("S", ""); 
     289 
     290    if (seriesCount > 1) { 
     291      CoreMetadata oldCore = core[0]; 
     292      core = new CoreMetadata[seriesCount]; 
     293      for (int i=0; i<seriesCount; i++) { 
     294        core[i] = oldCore; 
     295      } 
     296    } 
     297 
     298    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.ALL) { 
     299      // cut up the comment, if necessary 
     300      comment = ifds.get(0).getComment(); 
     301 
     302      gains = new String[getSizeC()]; 
     303      offsets = new String[getSizeC()]; 
     304      voltages = new String[getSizeC()]; 
     305      channelNames = new String[getSizeC()]; 
     306      lensNA = new String[getSizeC()]; 
     307 
     308      parseComment(); 
     309      addGlobalMeta("Comment", comment); 
     310    } 
     311  } 
     312 
     313  /* @see loci.formats.in.BaseTiffReader#initMetadataStore() */ 
     314  protected void initMetadataStore() throws FormatException { 
     315    super.initMetadataStore(); 
     316    MetadataStore store = 
     317      new FilterMetadata(getMetadataStore(), isMetadataFiltered()); 
     318    MetadataTools.populatePixels(store, this, true); 
     319 
     320    if (date != null) { 
     321      store.setImageCreationDate(date, 0); 
     322    } 
     323 
     324    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.ALL) { 
     325      return; 
     326    } 
     327 
     328    store.setImageDescription(comment, 0); 
     329 
     330    // link Instrument and Image 
     331    String instrumentID = MetadataTools.createLSID("Instrument", 0); 
     332    store.setInstrumentID(instrumentID, 0); 
     333    store.setImageInstrumentRef(instrumentID, 0); 
     334 
     335    // populate timing data 
     336    if (timeIndex >= 0) { 
     337      for (int i=0; i<getImageCount(); i++) { 
     338        store.setPlaneTimingDeltaT( 
     339          new Double(stamps[timeIndex][i] / 1000.0), 0, 0, i); 
     340      } 
     341    } 
     342 
     343    // populate Dimensions 
     344    store.setDimensionsPhysicalSizeX(voxelX, 0, 0); 
     345    store.setDimensionsPhysicalSizeY(voxelY, 0, 0); 
     346    store.setDimensionsPhysicalSizeZ(voxelZ, 0, 0); 
     347    store.setDimensionsTimeIncrement(voxelT, 0, 0); 
     348    if ((int) voxelC > 0) { 
     349      store.setDimensionsWaveIncrement((int) voxelC, 0, 0); 
     350    } 
     351 
     352    // populate LogicalChannel data 
     353 
     354    for (int i=0; i<getSizeC(); i++) { 
     355      if (channelNames[i] != null) { 
     356        store.setLogicalChannelName(channelNames[i].trim(), 0, i); 
     357      } 
     358    } 
     359 
     360    // populate Detector data 
     361 
     362    for (int i=0; i<getSizeC(); i++) { 
     363      if (voltages[i] != null) { 
     364        if (detectorManufacturer != null) { 
     365          store.setDetectorManufacturer(detectorManufacturer, 0, 0); 
     366        } 
     367        store.setDetectorSettingsVoltage(new Double(voltages[i]), 0, 0); 
     368      } 
     369      if (gains[i] != null) { 
     370        store.setDetectorSettingsGain(new Double(gains[i]), 0, i); 
     371      } 
     372      if (offsets[i] != null) { 
     373        store.setDetectorSettingsOffset(new Double(offsets[i]), 0, i); 
     374      } 
     375      store.setDetectorType("Unknown", 0, i); 
     376 
     377      // link DetectorSettings to an actual Detector 
     378      String detectorID = MetadataTools.createLSID("Detector", 0, i); 
     379      store.setDetectorID(detectorID, 0, i); 
     380      store.setDetectorSettingsDetector(detectorID, 0, i); 
     381    } 
     382 
     383    // populate Objective data 
     384 
     385    if (mag != null && mag.toLowerCase().endsWith("x")) { 
     386      mag = mag.substring(0, mag.length() - 1); 
     387    } 
     388    else if (mag == null) mag = "1"; 
     389 
     390    store.setObjectiveCorrection("Unknown", 0, 0); 
     391    store.setObjectiveImmersion("Unknown", 0, 0); 
     392 
     393    if (objectiveManufacturer != null) { 
     394      String[] objectiveData = objectiveManufacturer.split(" "); 
     395      store.setObjectiveModel(objectiveData[0], 0, 0); 
     396      if (objectiveData.length > 2) { 
     397        store.setObjectiveImmersion(objectiveData[2], 0, 0); 
     398      } 
     399    } 
     400 
     401    if (mag != null) { 
     402      store.setObjectiveCalibratedMagnification(new Double(mag), 0, 0); 
     403    } 
     404 
     405    for (int i=0; i<getSizeC(); i++) { 
     406      if (lensNA[i] != null) { 
     407        store.setObjectiveLensNA(new Double(lensNA[i]), 0, i); 
     408      } 
     409    } 
     410 
     411    // link Objective to Image using ObjectiveSettings 
     412    String objectiveID = MetadataTools.createLSID("Objective", 0, 0); 
     413    store.setObjectiveID(objectiveID, 0, 0); 
     414    store.setObjectiveSettingsObjective(objectiveID, 0); 
     415  } 
     416 
     417  // -- Helper methods -- 
     418 
     419  private int getImageIndex(int no) { 
    109420    // the 'series' axis can be in any position relative to Z, C and T 
    110421    // we need to convert the plane number within the series into an IFD number 
     
    132443    } 
    133444 
    134     int image = FormatTools.positionToRaster(lengths, realPos); 
    135  
    136     if (getSizeY() == ifds.get(0).getImageLength()) { 
    137       tiffParser.getSamples(ifds.get(image), buf, x, y, w, h); 
    138     } 
    139     else { 
    140       FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); 
    141       tiffParser.getSamples(ifds.get(0), buf, x, image, w, 1); 
    142     } 
    143  
    144     return buf; 
    145   } 
    146  
    147   /* @see loci.formats.IFormatReader#close(boolean) */ 
    148   public void close(boolean fileOnly) throws IOException { 
    149     super.close(fileOnly); 
    150     if (!fileOnly) { 
    151       voxelX = voxelY = voxelZ = voxelC = voxelT = 1; 
    152       dimensionOrder = null; 
    153       gains = voltages = offsets = channelNames = lensNA = null; 
    154       mag = detManu = objManu = comment = null; 
    155       gamma = null; 
    156       date = null; 
    157       timeIndex = -1; 
    158       stamps = null; 
    159     } 
    160   } 
    161  
    162   // -- Internal BaseTiffReader API methods -- 
    163  
    164   /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
    165   protected void initStandardMetadata() throws FormatException, IOException { 
    166     super.initStandardMetadata(); 
    167  
    168     // First, we want to determine whether this file is a Fluoview TIFF. 
    169     // Originally, Andor TIFF had its own reader; however, the two formats are 
    170     // very similar, so it made more sense to merge the two formats into one 
    171     // reader. 
    172  
    173     short[] s = ifds.get(0).getIFDShortArray(MMHEADER); 
    174     if (s == null) { 
    175       throw new FormatException("Invalid Fluoview/Andor TIFF. Tag " + 
    176         MMHEADER + " not found."); 
    177     } 
    178     byte[] mmheader = new byte[s.length]; 
    179     for (int i=0; i<mmheader.length; i++) { 
    180       mmheader[i] = (byte) s[i]; 
    181       if (mmheader[i] < 0) mmheader[i]++; 
    182     } 
    183  
    184     RandomAccessInputStream ras = new RandomAccessInputStream(mmheader); 
    185     ras.order(isLittleEndian()); 
    186  
    187     put("Header Flag", ras.readShort()); 
    188     put("Image Type", ras.read()); 
    189  
    190     put("Image name", ras.readString(257)); 
    191  
    192     ras.skipBytes(4); // skip pointer to data field 
    193  
    194     put("Number of colors", ras.readInt()); 
    195     ras.skipBytes(4); // skip pointer to palette field 
    196     ras.skipBytes(4); // skip pointer to other palette field 
    197  
    198     put("Comment size", ras.readInt()); 
    199     ras.skipBytes(4); // skip pointer to comment field 
    200  
    201     // read dimension information 
    202     String[] names = new String[10]; 
    203     int[] sizes = new int[10]; 
    204     double[] resolutions = new double[10]; 
    205     for (int i=0; i<10; i++) { 
    206       names[i] = ras.readString(16); 
    207       sizes[i] = ras.readInt(); 
    208       double origin = ras.readDouble(); 
    209       resolutions[i] = ras.readDouble(); 
    210  
    211       put("Dimension " + (i+1) + " Name", names[i]); 
    212       put("Dimension " + (i+1) + " Size", sizes[i]); 
    213       put("Dimension " + (i+1) + " Origin", origin); 
    214       put("Dimension " + (i+1) + " Resolution", resolutions[i]); 
    215       put("Dimension " + (i+1) + " Units", ras.readString(64)); 
    216     } 
    217  
    218     ras.skipBytes(4); // skip pointer to spatial position data 
    219  
    220     put("Map type", ras.readShort()); 
    221     put("Map min", ras.readDouble()); 
    222     put("Map max", ras.readDouble()); 
    223     put("Min value", ras.readDouble()); 
    224     put("Max value", ras.readDouble()); 
    225  
    226     ras.skipBytes(4); // skip pointer to map data 
    227  
    228     put("Gamma", ras.readDouble()); 
    229     put("Offset", ras.readDouble()); 
    230  
    231     // read gray channel data 
    232     put("Gray Channel Name", ras.readString(16)); 
    233     put("Gray Channel Size", ras.readInt()); 
    234     put("Gray Channel Origin", ras.readDouble()); 
    235     put("Gray Channel Resolution", ras.readDouble()); 
    236     put("Gray Channel Units", ras.readString(64)); 
    237  
    238     ras.skipBytes(4); // skip pointer to thumbnail data 
    239  
    240     put("Voice field", ras.readInt()); 
    241     ras.skipBytes(4); // skip pointer to voice field 
    242  
    243     // now we need to read the MMSTAMP data to determine dimension order 
    244  
     445    return FormatTools.positionToRaster(lengths, realPos); 
     446  } 
     447 
     448  private void readStamps() throws FormatException, IOException { 
    245449    stamps = new long[8][ifds.size()]; 
    246450    for (int i=0; i<ifds.size(); i++) { 
    247       s = ifds.get(i).getIFDShortArray(MMSTAMP); 
    248       byte[] stamp = new byte[s.length]; 
    249       for (int j=0; j<s.length; j++) { 
    250         stamp[j] = (byte) s[j]; 
    251         if (stamp[j] < 0) stamp[j]++; 
    252       } 
    253       ras.close(); 
    254       ras = new RandomAccessInputStream(stamp); 
     451      byte[] stamp = shortArrayToBytes(ifds.get(i).getIFDShortArray(MMSTAMP)); 
     452      RandomAccessInputStream ras = new RandomAccessInputStream(stamp); 
    255453 
    256454      // each stamp is 8 longs, representing the position on dimensions 3-10 
     
    258456        stamps[j][i] = ras.readLong() / 10000; 
    259457      } 
    260     } 
    261     ras.close(); 
    262  
    263     // calculate the dimension order and axis sizes 
    264  
    265     dimensionOrder = "XY"; 
    266     int seriesCount = 1; 
    267     core[0].sizeZ = core[0].sizeC = core[0].sizeT = 1; 
    268  
    269     for (int i=0; i<10; i++) { 
    270       String name = names[i]; 
    271       int size = sizes[i]; 
    272       double voxel = resolutions[i]; 
    273       if (name == null || size == 0) continue; 
    274       name = name.toLowerCase().trim(); 
    275       if (name.length() == 0) continue; 
    276  
    277       if (name.equals("x")) { 
    278         voxelX = voxel; 
    279       } 
    280       else if (name.equals("y")) { 
    281         voxelY = voxel; 
    282       } 
    283       else if (name.equals("z") || name.equals("event")) { 
    284         core[0].sizeZ *= size; 
    285         if (dimensionOrder.indexOf("Z") == -1) { 
    286           dimensionOrder += "Z"; 
    287         } 
    288         voxelZ = voxel; 
    289       } 
    290       else if (name.equals("ch") || name.equals("wavelength")) { 
    291         core[0].sizeC *= size; 
    292         if (dimensionOrder.indexOf("C") == -1) { 
    293           dimensionOrder += "C"; 
    294         } 
    295         voxelC = voxel; 
    296       } 
    297       else if (name.equals("time") || name.equals("t") || 
    298         name.equals("animation")) 
    299       { 
    300         core[0].sizeT *= size; 
    301         if (dimensionOrder.indexOf("T") == -1) { 
    302           dimensionOrder += "T"; 
    303         } 
    304         voxelT = voxel; 
    305         timeIndex = i - 2; 
    306       } 
    307       else { 
    308         if (dimensionOrder.indexOf("S") == -1) dimensionOrder += "S"; 
    309         seriesCount *= size; 
    310       } 
    311     } 
    312  
    313     if (dimensionOrder.indexOf("Z") == -1) dimensionOrder += "Z"; 
    314     if (dimensionOrder.indexOf("T") == -1) dimensionOrder += "T"; 
    315     if (dimensionOrder.indexOf("C") == -1) dimensionOrder += "C"; 
    316     if (dimensionOrder.indexOf("S") == -1) dimensionOrder += "S"; 
    317  
    318     core[0].imageCount = ifds.size() / seriesCount; 
    319     if (getSizeZ() > getImageCount()) core[0].sizeZ = getImageCount(); 
    320     if (getSizeT() > getImageCount()) core[0].sizeT = getImageCount(); 
    321  
    322     if (getImageCount() == 1 && (getSizeT() == getSizeY() || 
    323       getSizeZ() == getSizeY()) && (getSizeT() > getImageCount() || 
    324       getSizeZ() > getImageCount())) 
    325     { 
    326       core[0].sizeY = 1; 
    327       core[0].imageCount = getSizeZ() * getSizeC() * getSizeT(); 
    328     } 
    329     core[0].dimensionOrder = dimensionOrder.replaceAll("S", ""); 
    330  
    331     if (seriesCount > 1) { 
    332       CoreMetadata oldCore = core[0]; 
    333       core = new CoreMetadata[seriesCount]; 
    334       for (int i=0; i<seriesCount; i++) { 
    335         core[i] = oldCore; 
    336       } 
    337     } 
    338  
    339     // cut up the comment, if necessary 
    340     comment = ifds.get(0).getComment(); 
    341  
    342     gains = new String[getSizeC()]; 
    343     offsets = new String[getSizeC()]; 
    344     voltages = new String[getSizeC()]; 
    345     channelNames = new String[getSizeC()]; 
    346     lensNA = new String[getSizeC()]; 
    347  
     458      ras.close(); 
     459    } 
     460  } 
     461 
     462  private byte[] shortArrayToBytes(short[] s) { 
     463    byte[] b = new byte[s.length]; 
     464    for (int i=0; i<s.length; i++) { 
     465      b[i] = (byte) s[i]; 
     466      if (b[i] < 0) b[i]++; 
     467    } 
     468    return b; 
     469  } 
     470 
     471  private void parseComment() { 
    348472    if (comment != null) { 
    349473      // this is an INI-style comment, with one key/value pair per line 
     
    382506          } 
    383507          else if (key.equals("Magnification")) mag = value; 
    384           else if (key.equals("System Configuration")) detManu = value; 
    385           else if (key.equals("Objective Lens")) objManu = value; 
    386           else if (key.equals("Gamma")) gamma = new Double(value); 
     508          else if (key.equals("System Configuration")) { 
     509            detectorManufacturer = value; 
     510          } 
     511          else if (key.equals("Objective Lens")) objectiveManufacturer = value; 
    387512          else if (key.startsWith("Channel ") && key.endsWith("Dye")) { 
    388513            for (int i=0; i<channelNames.length; i++) { 
     
    446571      else comment = ""; 
    447572    } 
    448     addGlobalMeta("Comment", comment); 
    449   } 
    450  
    451   /* @see loci.formats.in.BaseTiffReader#initMetadataStore() */ 
    452   protected void initMetadataStore() throws FormatException { 
    453     super.initMetadataStore(); 
    454     MetadataStore store = 
    455       new FilterMetadata(getMetadataStore(), isMetadataFiltered()); 
    456     MetadataTools.populatePixels(store, this, true); 
    457  
    458     store.setImageDescription(comment, 0); 
    459     if (date != null) { 
    460       store.setImageCreationDate(date, 0); 
    461     } 
    462  
    463     // link Instrument and Image 
    464     String instrumentID = MetadataTools.createLSID("Instrument", 0); 
    465     store.setInstrumentID(instrumentID, 0); 
    466     store.setImageInstrumentRef(instrumentID, 0); 
    467  
    468     // populate timing data 
    469     if (timeIndex >= 0) { 
    470       for (int i=0; i<getImageCount(); i++) { 
    471         store.setPlaneTimingDeltaT( 
    472           new Double(stamps[timeIndex][i] / 1000.0), 0, 0, i); 
    473       } 
    474     } 
    475  
    476     // populate Dimensions 
    477     store.setDimensionsPhysicalSizeX(voxelX, 0, 0); 
    478     store.setDimensionsPhysicalSizeY(voxelY, 0, 0); 
    479     store.setDimensionsPhysicalSizeZ(voxelZ, 0, 0); 
    480     store.setDimensionsTimeIncrement(voxelT, 0, 0); 
    481     if ((int) voxelC > 0) { 
    482       store.setDimensionsWaveIncrement((int) voxelC, 0, 0); 
    483     } 
    484  
    485     // populate LogicalChannel data 
    486  
    487     for (int i=0; i<getSizeC(); i++) { 
    488       if (channelNames[i] != null) { 
    489         store.setLogicalChannelName(channelNames[i].trim(), 0, i); 
    490       } 
    491     } 
    492  
    493     // populate Detector data 
    494  
    495     for (int i=0; i<getSizeC(); i++) { 
    496       // CTR CHECK 
    497 //      store.setDisplayChannel(i, null, null, gamma, null); 
    498  
    499       if (voltages[i] != null) { 
    500         if (detManu != null) store.setDetectorManufacturer(detManu, 0, 0); 
    501         store.setDetectorSettingsVoltage(new Double(voltages[i]), 0, 0); 
    502       } 
    503       if (gains[i] != null) { 
    504         store.setDetectorSettingsGain(new Double(gains[i]), 0, i); 
    505       } 
    506       if (offsets[i] != null) { 
    507         store.setDetectorSettingsOffset(new Double(offsets[i]), 0, i); 
    508       } 
    509       store.setDetectorType("Unknown", 0, i); 
    510  
    511       // link DetectorSettings to an actual Detector 
    512       String detectorID = MetadataTools.createLSID("Detector", 0, i); 
    513       store.setDetectorID(detectorID, 0, i); 
    514       store.setDetectorSettingsDetector(detectorID, 0, i); 
    515     } 
    516  
    517     // populate Objective data 
    518  
    519     if (mag != null && mag.toLowerCase().endsWith("x")) { 
    520       mag = mag.substring(0, mag.length() - 1); 
    521     } 
    522     else if (mag == null) mag = "1"; 
    523  
    524     store.setObjectiveCorrection("Unknown", 0, 0); 
    525     store.setObjectiveImmersion("Unknown", 0, 0); 
    526  
    527     if (objManu != null) { 
    528       String[] objectiveData = objManu.split(" "); 
    529       store.setObjectiveModel(objectiveData[0], 0, 0); 
    530       if (objectiveData.length > 2) { 
    531         store.setObjectiveImmersion(objectiveData[2], 0, 0); 
    532       } 
    533     } 
    534  
    535     if (mag != null) { 
    536       store.setObjectiveCalibratedMagnification(new Double(mag), 0, 0); 
    537     } 
    538  
    539     for (int i=0; i<getSizeC(); i++) { 
    540       if (lensNA[i] != null) { 
    541         store.setObjectiveLensNA(new Double(lensNA[i]), 0, i); 
    542       } 
    543     } 
    544  
    545     // link Objective to Image using ObjectiveSettings 
    546     String objectiveID = MetadataTools.createLSID("Objective", 0, 0); 
    547     store.setObjectiveID(objectiveID, 0, 0); 
    548     store.setObjectiveSettingsObjective(objectiveID, 0); 
    549573  } 
    550574 
  • trunk/components/bio-formats/src/loci/formats/in/GIFReader.java

    r6026 r6116  
    5454  private static final int MAX_STACK_SIZE = 4096; 
    5555 
     56  private static final int IMAGE_SEPARATOR = 0x2c; 
     57  private static final int EXTENSION = 0x21; 
     58  private static final int END = 0x3b; 
     59  private static final int GRAPHICS = 0xf9; 
     60 
    5661  // -- Fields -- 
    57  
    58   /** Global color table used. */ 
    59   private boolean gctFlag; 
    60  
    61   /** Size of global color table. */ 
    62   private int gctSize; 
    6362 
    6463  /** Global color table. */ 
    6564  private int[] gct; 
    6665 
    67   /** Local color table. */ 
    68   private int[] lct; 
    69  
    7066  /** Active color table. */ 
    7167  private int[] act; 
    7268 
    73   /** Local color table flag. */ 
    74   private boolean lctFlag; 
    75  
    7669  /** Interlace flag. */ 
    7770  private boolean interlace; 
    78  
    79   /** Local color table size. */ 
    80   private int lctSize; 
    8171 
    8272  /** Current image rectangle. */ 
     
    170160    super.close(fileOnly); 
    171161    if (!fileOnly) { 
    172       gctFlag = lctFlag = interlace = transparency = false; 
    173       gctSize = lctSize = ix = iy = iw = ih = blockSize = 0; 
     162      interlace = transparency = false; 
     163      ix = iy = iw = ih = blockSize = 0; 
    174164      dispose = lastDispose = transIndex = 0; 
    175       gct = lct = act; 
     165      gct = act; 
    176166      prefix = null; 
    177167      suffix = pixelStack = pixels = null; 
     
    197187    String ident = in.readString(6); 
    198188 
    199     if (!ident.startsWith("GIF")) { 
     189    if (!ident.startsWith(GIF_MAGIC_STRING)) { 
    200190      throw new FormatException("Not a valid GIF file."); 
    201191    } 
     
    207197 
    208198    int packed = in.read() & 0xff; 
    209     gctFlag = (packed & 0x80) != 0; 
    210     gctSize = 2 << (packed & 7); 
    211     in.skipBytes(1); 
    212     in.skipBytes(1); 
     199    boolean gctFlag = (packed & 0x80) != 0; 
     200    int gctSize = 2 << (packed & 7); 
     201    in.skipBytes(2); 
    213202 
    214203    if (gctFlag) { 
    215       int nbytes = 3 * gctSize; 
    216       byte[] c = new byte[nbytes]; 
    217       in.read(c); 
    218  
    219       gct = new int[256]; 
    220       int i = 0; 
    221       int j = 0; 
    222       int r, g, b; 
    223       while (i < gctSize) { 
    224         r = c[j++] & 0xff; 
    225         g = c[j++] & 0xff; 
    226         b = c[j++] & 0xff; 
    227         gct[i++] = 0xff000000 | (r << 16) | (g << 8) | b; 
    228       } 
     204      gct = readLut(gctSize); 
    229205    } 
    230206 
     
    235211      int code = in.read() & 0xff; 
    236212      switch (code) { 
    237         case 0x2c: // image separator: 
    238           ix = in.readShort(); 
    239           iy = in.readShort(); 
    240           iw = in.readShort(); 
    241           ih = in.readShort(); 
    242  
    243           packed = in.read(); 
    244           lctFlag = (packed & 0x80) != 0; 
    245           interlace = (packed & 0x40) != 0; 
    246           lctSize = 2 << (packed & 7); 
    247  
    248           if (lctFlag) { 
    249             int nbytes = 3 * lctSize; 
    250             byte[] c = new byte[nbytes]; 
    251             int n = 0; 
    252             try { n = in.read(c); } 
    253             catch (IOException e) { } 
    254  
    255             if (n < nbytes) { 
    256               throw new FormatException("Local color table not found"); 
    257             } 
    258  
    259             lct = new int[256]; 
    260             int i = 0; 
    261             int j = 0; 
    262             while (i < lctSize) { 
    263               int r = c[j++] & 0xff; 
    264               int g = c[j++] & 0xff; 
    265               int b = c[j++] & 0xff; 
    266               lct[i++] = 0xff000000 | (r << 16) + (g << 8) | b; 
    267             } 
    268  
    269             act = lct; 
    270           } 
    271           else { 
    272             act = gct; 
    273           } 
    274  
    275           int save = 0; 
    276  
    277           if (transparency) { 
    278             save = act[transIndex]; 
    279             act[transIndex] = 0; 
    280           } 
    281  
    282           if (act == null) throw new FormatException("Color table not found."); 
    283  
    284           decodeImageData(); 
    285  
    286           int check = 0; 
    287           do { check = readBlock(); } 
    288           while (blockSize > 0 && check != -1); 
    289  
    290           core[0].imageCount++; 
    291  
    292           if (transparency) act[transIndex] = save; 
    293  
    294           lastDispose = dispose; 
    295           lct = null; 
    296  
     213        case IMAGE_SEPARATOR: 
     214          readImageBlock(); 
    297215          break; 
    298         case 0x21: // extension 
     216        case EXTENSION: 
    299217          code = in.read() & 0xff; 
    300218          switch (code) { 
    301             case 0xf9: // graphics control extension 
     219            case GRAPHICS: 
    302220              in.skipBytes(1); 
    303221              packed = in.read() & 0xff; 
     
    308226              in.skipBytes(1); 
    309227              break; 
    310             case 0xff:  // application extension 
     228            default: 
    311229              if (readBlock() == -1) { 
    312230                done = true; 
    313231                break; 
    314232              } 
    315  
    316               String app = new String(dBlock, 0, 11); 
    317               if (app.equals("NETSCAPE2.0")) { 
    318                 do { 
    319                   check = readBlock(); 
    320                 } 
    321                 while (blockSize > 0 && check != -1); 
    322               } 
    323               else { 
    324                 do { 
    325                   check = readBlock(); 
    326                 } 
    327                 while (blockSize > 0 && check != -1); 
    328               } 
    329               break; 
    330             default: 
    331               do { 
    332                 check = readBlock(); 
    333               } 
    334               while (blockSize > 0 && check != -1); 
     233              skipBlocks(); 
    335234          } 
    336235          break; 
    337         case 0x3b: // terminator 
     236        case END: 
    338237          done = true; 
    339238          break; 
     
    380279        } 
    381280      } 
    382       catch (IOException e) { } 
     281      catch (IOException e) { 
     282        LOGGER.trace("Truncated block", e); 
     283      } 
    383284    } 
    384285    return n; 
     
    390291    int npix = iw * ih; 
    391292 
    392     int available, clear, codeMask, codeSize, eoi, inCode, oldCode, bits, code, 
    393       count, i, datum, dataSize, first, top, bi, pi; 
    394  
    395293    if (pixels == null || pixels.length < npix) pixels = new byte[npix]; 
    396294 
     
    401299    // initialize GIF data stream decoder 
    402300 
    403     dataSize = in.read() & 0xff; 
    404  
    405     clear = 1 << dataSize; 
    406     eoi = clear + 1; 
    407     available = clear + 2; 
    408     oldCode = nullCode; 
    409     codeSize = dataSize + 1; 
    410     codeMask = (1 << codeSize) - 1; 
     301    int dataSize = in.read() & 0xff; 
     302 
     303    int clear = 1 << dataSize; 
     304    int eoi = clear + 1; 
     305    int available = clear + 2; 
     306    int oldCode = nullCode; 
     307    int codeSize = dataSize + 1; 
     308    int codeMask = (1 << codeSize) - 1; 
     309    int code = 0, inCode = 0; 
    411310    for (code=0; code<clear; code++) { 
    412311      prefix[code] = 0; 
     
    416315    // decode GIF pixel stream 
    417316 
    418     datum = bits = count = first = top = pi = bi = 0; 
     317    int datum = 0, first = 0, top = 0, pi = 0, bi = 0, bits = 0, count = 0; 
     318    int i = 0; 
    419319 
    420320    for (i=0; i<npix;) { 
     
    426326            bi = 0; 
    427327          } 
    428           datum += (((int) dBlock[bi]) & 0xff) << bits; 
     328          datum += (dBlock[bi] & 0xff) << bits; 
    429329          bits += 8; 
    430330          bi++; 
     
    469369          code = prefix[code]; 
    470370        } 
    471         first = ((int) suffix[code]) & 0xff; 
     371        first = suffix[code] & 0xff; 
    472372 
    473373        if (available >= MAX_STACK_SIZE) break; 
     
    546446        while (dx < dlim) { 
    547447          // map color and insert in destination 
    548           int index = ((int) pixels[sx++]) & 0xff; 
     448          int index = pixels[sx++] & 0xff; 
    549449          dest[dx++] = (byte) index; 
    550450        } 
     
    555455  } 
    556456 
     457  private void skipBlocks() throws IOException { 
     458    int check = 0; 
     459    do { check = readBlock(); } 
     460    while (blockSize > 0 && check != -1); 
     461  } 
     462 
     463  private void readImageBlock() throws FormatException, IOException { 
     464    ix = in.readShort(); 
     465    iy = in.readShort(); 
     466    iw = in.readShort(); 
     467    ih = in.readShort(); 
     468 
     469    int packed = in.read(); 
     470    boolean lctFlag = (packed & 0x80) != 0; 
     471    interlace = (packed & 0x40) != 0; 
     472    int lctSize = 2 << (packed & 7); 
     473 
     474    act = lctFlag ? readLut(lctSize) : gct; 
     475 
     476    int save = 0; 
     477 
     478    if (transparency) { 
     479      save = act[transIndex]; 
     480      act[transIndex] = 0; 
     481    } 
     482 
     483    if (act == null) throw new FormatException("Color table not found."); 
     484 
     485    decodeImageData(); 
     486    skipBlocks(); 
     487 
     488    core[0].imageCount++; 
     489 
     490    if (transparency) act[transIndex] = save; 
     491 
     492    lastDispose = dispose; 
     493  } 
     494 
     495  /** Read a color lookup table of the specified size. */ 
     496  private int[] readLut(int size) throws FormatException { 
     497    int nbytes = 3 * size; 
     498    byte[] c = new byte[nbytes]; 
     499    int n = 0; 
     500    try { n = in.read(c); } 
     501    catch (IOException e) { } 
     502 
     503    if (n < nbytes) { 
     504      throw new FormatException("Color table not found"); 
     505    } 
     506 
     507    int[] lut = new int[256]; 
     508    int j = 0; 
     509    for (int i=0; i<size; i++) { 
     510      int r = c[j++] & 0xff; 
     511      int g = c[j++] & 0xff; 
     512      int b = c[j++] & 0xff; 
     513      lut[i] = 0xff000000 | (r << 16) | (g << 8) | b; 
     514    } 
     515    return lut; 
     516  } 
     517 
    557518} 
Note: See TracChangeset for help on using the changeset viewer.