Example #1
0
  /* @see IFormatHandler#setId(String) */
  public void setId(String id) throws FormatException, IOException {
    try {
      super.setId(id);
    } catch (CMMException e) {
      // strip out all but the first application marker
      // ImageIO isn't too keen on supporting multiple application markers
      // in the same stream, as evidenced by:
      //
      // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6488904

      in = new RandomAccessInputStream(id);
      ByteArrayOutputStream v = new ByteArrayOutputStream();

      byte[] tag = new byte[2];
      in.read(tag);
      v.write(tag);

      in.read(tag);
      int tagValue = DataTools.bytesToShort(tag, false) & 0xffff;
      boolean appNoteFound = false;
      while (tagValue != 0xffdb) {
        if (!appNoteFound || (tagValue < 0xffe0 && tagValue >= 0xfff0)) {
          v.write(tag);

          in.read(tag);
          int len = DataTools.bytesToShort(tag, false) & 0xffff;
          byte[] tagContents = new byte[len - 2];
          in.read(tagContents);
          v.write(tag);
          v.write(tagContents);
        } else {
          in.read(tag);
          int len = DataTools.bytesToShort(tag, false) & 0xffff;
          in.skipBytes(len - 2);
        }

        if (tagValue >= 0xffe0 && tagValue < 0xfff0 && !appNoteFound) {
          appNoteFound = true;
        }
        in.read(tag);
        tagValue = DataTools.bytesToShort(tag, false) & 0xffff;
      }
      v.write(tag);
      byte[] remainder = new byte[(int) (in.length() - in.getFilePointer())];
      in.read(remainder);
      v.write(remainder);

      ByteArrayHandle bytes = new ByteArrayHandle(v.toByteArray());

      Location.mapFile(currentId + ".fixed", bytes);
      super.setId(currentId + ".fixed");
    }
    if (getSizeX() > MAX_SIZE && getSizeY() > MAX_SIZE && !legacyReaderInitialized) {
      close();
      useLegacy = true;
      super.setId(id);
    }
    currentId = id;
  }
  private void writePixels(String chunk, byte[] stream, int x, int y, int width, int height)
      throws FormatException, IOException {
    MetadataRetrieve r = getMetadataRetrieve();
    int sizeC = getSamplesPerPixel();
    String type = r.getPixelsType(series).toString();
    int pixelType = FormatTools.pixelTypeFromString(type);
    boolean signed = FormatTools.isSigned(pixelType);

    if (!isFullPlane(x, y, width, height)) {
      throw new FormatException("APNGWriter does not support writing tiles.");
    }

    ByteArrayOutputStream s = new ByteArrayOutputStream();
    s.write(chunk.getBytes());
    if (chunk.equals("fdAT")) {
      s.write(DataTools.intToBytes(nextSequenceNumber++, false));
    }
    DeflaterOutputStream deflater = new DeflaterOutputStream(s);
    int planeSize = stream.length / sizeC;
    int rowLen = stream.length / height;
    int bytesPerPixel = stream.length / (width * height * sizeC);
    byte[] rowBuf = new byte[rowLen];
    for (int i = 0; i < height; i++) {
      deflater.write(0);
      if (interleaved) {
        if (littleEndian) {
          for (int col = 0; col < width * sizeC; col++) {
            int offset = (i * sizeC * width + col) * bytesPerPixel;
            int pixel = DataTools.bytesToInt(stream, offset, bytesPerPixel, littleEndian);
            DataTools.unpackBytes(pixel, rowBuf, col * bytesPerPixel, bytesPerPixel, false);
          }
        } else System.arraycopy(stream, i * rowLen, rowBuf, 0, rowLen);
      } else {
        int max = (int) Math.pow(2, bytesPerPixel * 8 - 1);
        for (int col = 0; col < width; col++) {
          for (int c = 0; c < sizeC; c++) {
            int offset = c * planeSize + (i * width + col) * bytesPerPixel;
            int pixel = DataTools.bytesToInt(stream, offset, bytesPerPixel, littleEndian);
            if (signed) {
              if (pixel < max) pixel += max;
              else pixel -= max;
            }
            int output = (col * sizeC + c) * bytesPerPixel;
            DataTools.unpackBytes(pixel, rowBuf, output, bytesPerPixel, false);
          }
        }
      }
      deflater.write(rowBuf);
    }
    deflater.finish();
    byte[] b = s.toByteArray();

    // write chunk length
    out.writeInt(b.length - 4);
    out.write(b);

    // write checksum
    out.writeInt(crc(b));
  }
  /* @see loci.formats.IFormatHandler#setId(String) */
  public void setId(String id) throws FormatException, IOException {
    super.setId(id);

    if (out.length() == 0) {
      MetadataRetrieve r = getMetadataRetrieve();
      int width = r.getPixelsSizeX(series).getValue().intValue();
      int height = r.getPixelsSizeY(series).getValue().intValue();
      int bytesPerPixel = FormatTools.getBytesPerPixel(r.getPixelsType(series).toString());
      int nChannels = getSamplesPerPixel();
      boolean indexed = getColorModel() != null && (getColorModel() instanceof IndexColorModel);
      littleEndian = !r.getPixelsBinDataBigEndian(series, 0);

      // write 8-byte PNG signature
      out.write(PNG_SIG);

      // write IHDR chunk

      out.writeInt(13);
      byte[] b = new byte[17];
      b[0] = 'I';
      b[1] = 'H';
      b[2] = 'D';
      b[3] = 'R';

      DataTools.unpackBytes(width, b, 4, 4, false);
      DataTools.unpackBytes(height, b, 8, 4, false);

      b[12] = (byte) (bytesPerPixel * 8);
      if (indexed) b[13] = (byte) 3;
      else if (nChannels == 1) b[13] = (byte) 0;
      else if (nChannels == 2) b[13] = (byte) 4;
      else if (nChannels == 3) b[13] = (byte) 2;
      else if (nChannels == 4) b[13] = (byte) 6;
      b[14] = (byte) 0;
      b[15] = (byte) 0;
      b[16] = (byte) 0;

      out.write(b);
      out.writeInt(crc(b));

      // write acTL chunk

      out.writeInt(8);
      out.writeBytes("acTL");
      numFramesPointer = out.getFilePointer();
      out.writeInt(0);
      out.writeInt(0);
      out.writeInt(0); // save a place for the CRC
    }
  }
  private void parsePosition(int posIndex) throws IOException, FormatException {
    Position p = positions.get(posIndex);
    String s = DataTools.readFile(p.metadataFile);
    parsePosition(s, posIndex);

    buildTIFFList(posIndex);
  }
Example #5
0
  private void parseROIs(MetadataStore store) throws IOException {
    if (roiFile == null) return;
    String roiData = DataTools.readFile(roiFile);
    String[] lines = roiData.split("\r\n");

    int firstRow = 0;
    while (firstRow < lines.length && !lines[firstRow].startsWith("ROI")) {
      firstRow++;
    }
    firstRow += 2;
    if (firstRow >= lines.length) return;

    for (int i = firstRow; i < lines.length; i++) {
      String[] cols = lines[i].split("\t");
      if (cols.length < 6) break;

      if (cols[2].trim().length() > 0) {
        String rectangleID = MetadataTools.createLSID("Shape", i - firstRow, 0);
        store.setRectangleID(rectangleID, i - firstRow, 0);
        store.setRectangleX(new Double(cols[2]), i - firstRow, 0);
        store.setRectangleY(new Double(cols[3]), i - firstRow, 0);
        store.setRectangleWidth(new Double(cols[4]), i - firstRow, 0);
        store.setRectangleHeight(new Double(cols[5]), i - firstRow, 0);
        String roiID = MetadataTools.createLSID("ROI", i - firstRow);
        store.setROIID(roiID, i - firstRow);
        for (int s = 0; s < getSeriesCount(); s++) {
          store.setImageROIRef(roiID, s, i - firstRow);
        }
      }
    }
  }
  /** Parse metadata values from the Acqusition.xml file. */
  private void parseXMLFile() throws IOException {
    Position p = positions.get(getSeries());
    String xmlData = DataTools.readFile(p.xmlFile);
    xmlData = XMLTools.sanitizeXML(xmlData);

    DefaultHandler handler = new MicromanagerHandler();
    XMLTools.parseXML(xmlData, handler);
  }
 /**
  * Calculates a SHA-1 digest on a byte array.
  *
  * @param buf Byte array to calculate a SHA-1 digest for.
  * @return Hex string of the SHA-1 digest for <code>buf</code>.
  */
 private String sha1(byte[] buf) {
   try {
     MessageDigest md = MessageDigest.getInstance("SHA-1");
     return DataTools.bytesToHex(md.digest(buf));
   } catch (Exception e) {
     throw new RuntimeException(e);
   }
 }
  private void writeFooter() throws IOException {
    // write IEND chunk
    out.writeInt(0);
    out.writeBytes("IEND");
    out.writeInt(crc("IEND".getBytes()));

    // update frame count
    out.seek(numFramesPointer);
    out.writeInt(numFrames);
    out.skipBytes(4);
    byte[] b = new byte[12];
    b[0] = 'a';
    b[1] = 'c';
    b[2] = 'T';
    b[3] = 'L';
    DataTools.unpackBytes(numFrames, b, 4, 4, false);
    DataTools.unpackBytes(0, b, 8, 4, false);
    out.writeInt(crc(b));
  }
Example #9
0
 private static double decodeWord(byte[] plane, int index, int pixelType, boolean little) {
   final double value;
   switch (pixelType) {
     case FormatTools.UINT8:
       value = plane[index] & 0xff;
       break;
     case FormatTools.INT8:
       value = plane[index];
       break;
     case FormatTools.UINT16:
       value = DataTools.bytesToShort(plane, 2 * index, 2, little) & 0xffff;
       break;
     case FormatTools.INT16:
       value = DataTools.bytesToShort(plane, 2 * index, 2, little);
       break;
     case FormatTools.UINT32:
       value = DataTools.bytesToInt(plane, 4 * index, 4, little) & 0xffffffffL;
       break;
     case FormatTools.INT32:
       value = DataTools.bytesToInt(plane, 4 * index, 4, little);
       break;
     case FormatTools.FLOAT:
       value = DataTools.bytesToFloat(plane, 4 * index, 4, little);
       break;
     case FormatTools.DOUBLE:
       value = DataTools.bytesToDouble(plane, 8 * index, 8, little);
       break;
     default:
       value = Double.NaN;
   }
   return value;
 }
Example #10
0
 @SuppressWarnings({"rawtypes", "unchecked"})
 private void populatePlane(IFormatReader r, int no, byte[] plane, PlanarAccess planarAccess) {
   final int pixelType = r.getPixelType();
   final int bpp = FormatTools.getBytesPerPixel(pixelType);
   final boolean fp = FormatTools.isFloatingPoint(pixelType);
   final boolean little = r.isLittleEndian();
   Object planeArray = DataTools.makeDataArray(plane, bpp, fp, little);
   if (planeArray == plane) {
     // array was returned by reference; make a copy
     final byte[] planeCopy = new byte[plane.length];
     System.arraycopy(plane, 0, planeCopy, 0, plane.length);
     planeArray = planeCopy;
   }
   planarAccess.setPlane(no, makeArray(planeArray));
 }
Example #11
0
  /* @see loci.formats.FormatReader#initFile(String) */
  @Override
  protected void initFile(String id) throws FormatException, IOException {
    // read the pattern from the file
    // the file should just contain a single line with the relative or
    // absolute file pattern

    currentId = new Location(id).getAbsolutePath();
    String pattern = DataTools.readFile(id).trim();
    String dir = new Location(id).getAbsoluteFile().getParent();
    if (new Location(pattern).getParent() == null) {
      pattern = dir + File.separator + pattern;
    }

    helper.setUsingPatternIds(true);
    helper.setCanChangePattern(false);
    helper.setId(pattern);
    core = helper.getCoreMetadataList();
  }
Example #12
0
  /* @see loci.formats.FormatReader#initFile(String) */
  protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);

    Location parent = new Location(id).getAbsoluteFile().getParentFile();

    String[] lines = DataTools.readFile(currentId).split("\r\n");

    for (String line : lines) {
      int eq = line.indexOf("=");
      if (eq < 0) {
        continue;
      }
      String key = line.substring(0, eq).trim();
      String value = line.substring(eq + 1).trim();

      if (key.equals("NoImages")) {
        ndpiFiles = new String[Integer.parseInt(value)];
        readers = new ChannelSeparator[ndpiFiles.length];
      } else if (key.startsWith("Image")) {
        int index = Integer.parseInt(key.replaceAll("Image", ""));
        ndpiFiles[index] = new Location(parent, value).getAbsolutePath();
        readers[index] = new ChannelSeparator(new NDPIReader());
      }
    }

    readers[0].setMetadataStore(getMetadataStore());
    readers[0].setId(ndpiFiles[0]);

    core = readers[0].getCoreMetadata();
    for (int i = 0; i < getSeriesCount(); i++) {
      core[i].sizeC = readers.length;
      core[i].rgb = false;
      core[i].imageCount = core[i].sizeC * core[i].sizeZ * core[i].sizeT;
      core[i].cLengths = new int[] {getSizeC()};
    }

    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
  }
  private void writeFCTL(int width, int height) throws IOException {
    out.writeInt(26);
    byte[] b = new byte[30];
    b[0] = 'f';
    b[1] = 'c';
    b[2] = 'T';
    b[3] = 'L';

    DataTools.unpackBytes(nextSequenceNumber++, b, 4, 4, false);
    DataTools.unpackBytes(width, b, 8, 4, false);
    DataTools.unpackBytes(height, b, 12, 4, false);
    DataTools.unpackBytes(0, b, 16, 4, false);
    DataTools.unpackBytes(0, b, 20, 4, false);
    DataTools.unpackBytes(1, b, 24, 2, false);
    DataTools.unpackBytes(fps, b, 26, 2, false);
    b[28] = (byte) 1;
    b[29] = (byte) 0;

    out.write(b);
    out.writeInt(crc(b));
  }
  private void parseROIs(MetadataStore store) throws FormatException, IOException {
    if (MetadataTools.isOMEXMLMetadata(store) || MetadataTools.isOMEXMLRoot(store.getRoot())) {
      return;
    }

    String roiID = MetadataTools.createLSID("ROI", 0, 0);
    String maskID = MetadataTools.createLSID("Shape", 0, 0);

    store.setROIID(roiID, 0);
    store.setMaskID(maskID, 0, 0);

    String positionData = DataTools.readFile(roiDrawFile);
    String[] coordinates = positionData.split("[ ,]");

    double x1 = Double.parseDouble(coordinates[1]);
    double y1 = Double.parseDouble(coordinates[2]);
    double x2 = Double.parseDouble(coordinates[3]);
    double y2 = Double.parseDouble(coordinates[5]);

    store.setMaskX(x1, 0, 0);
    store.setMaskY(y1, 0, 0);
    store.setMaskWidth(x2 - x1, 0, 0);
    store.setMaskHeight(y2 - y1, 0, 0);

    store.setImageROIRef(roiID, 0, 0);

    ImageReader roiReader = new ImageReader();
    roiReader.setId(roiFile);
    byte[] roiPixels = roiReader.openBytes(0);
    roiReader.close();

    BitWriter bits = new BitWriter(roiPixels.length / 8);
    for (int i = 0; i < roiPixels.length; i++) {
      bits.write(roiPixels[i] == 0 ? 0 : 1, 1);
    }
    store.setMaskBinData(bits.toByteArray(), 0, 0);
  }
Example #15
0
  /* @see loci.formats.FormatReader#initFile(String) */
  protected void initFile(String id) throws FormatException, IOException {
    // make sure we have the experiment file
    id = locateExperimentFile(id);
    super.initFile(id);
    Location dir = new Location(id).getAbsoluteFile().getParentFile();

    for (String file : dir.list(true)) {
      Location f = new Location(dir, file);
      if (!f.isDirectory()) {
        if (checkSuffix(file, META_EXT)) {
          metadataFiles.add(f.getAbsolutePath());
        }
      }
    }

    // parse Experiment metadata
    IniList experiment = readMetaData(id);

    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
      objective = experiment.getTable("Geometry").get("Name");
      IniTable camera = experiment.getTable("Camera");
      binning = camera.get("BinX") + "x" + camera.get("BinY");

      parseChannelData(dir);

      addGlobalMeta("Objective", objective);
      addGlobalMeta("Camera binning", binning);
    }

    Vector<String> uniqueRows = new Vector<String>();
    Vector<String> uniqueColumns = new Vector<String>();

    for (String well : wellLabels) {
      String row = well.substring(0, 1).trim();
      String column = well.substring(1).trim();

      if (!uniqueRows.contains(row) && row.length() > 0) uniqueRows.add(row);
      if (!uniqueColumns.contains(column) && column.length() > 0) {
        uniqueColumns.add(column);
      }
    }

    int nSlices = getSizeZ() == 0 ? 1 : getSizeZ();
    int nTimepoints = getSizeT();
    int nWells = wellLabels.size();
    int nChannels = getSizeC() == 0 ? channelNames.size() : getSizeC();
    if (nChannels == 0) nChannels = 1;

    tiffs = getTiffs(dir.getAbsolutePath());

    reader = new MinimalTiffReader();
    reader.setId(tiffs[0][0]);

    int sizeX = reader.getSizeX();
    int sizeY = reader.getSizeY();
    int pixelType = reader.getPixelType();
    boolean rgb = reader.isRGB();
    boolean interleaved = reader.isInterleaved();
    boolean indexed = reader.isIndexed();
    boolean littleEndian = reader.isLittleEndian();

    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
      IniParser parser = new IniParser();
      for (String metadataFile : metadataFiles) {
        String filename = new Location(metadataFile).getName();
        if (!checkSuffix(metadataFile, "txt")) {
          String data = DataTools.readFile(metadataFile);
          IniList ini = parser.parseINI(new BufferedReader(new StringReader(data)));
          HashMap<String, String> h = ini.flattenIntoHashMap();
          for (String key : h.keySet()) {
            addGlobalMeta(filename + " " + key, h.get(key));
          }
        }
      }
    }

    for (int i = 0; i < getSeriesCount(); i++) {
      core[i] = new CoreMetadata();
      core[i].sizeC = nChannels;
      core[i].sizeZ = nSlices;
      core[i].sizeT = nTimepoints;
      core[i].sizeX = sizeX / fieldCols;
      core[i].sizeY = sizeY / fieldRows;
      core[i].pixelType = pixelType;
      core[i].rgb = rgb;
      core[i].interleaved = interleaved;
      core[i].indexed = indexed;
      core[i].littleEndian = littleEndian;
      core[i].dimensionOrder = "XYZTC";
      core[i].imageCount = nSlices * nTimepoints * nChannels;
    }

    MetadataStore store = makeFilterMetadata();
    boolean populatePlanes = getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM;
    MetadataTools.populatePixels(store, this, populatePlanes);

    String plateAcqID = MetadataTools.createLSID("PlateAcquisition", 0, 0);
    store.setPlateAcquisitionID(plateAcqID, 0, 0);
    if (fieldRows * fieldCols > 0) {
      store.setPlateAcquisitionMaximumFieldCount(new PositiveInteger(fieldRows * fieldCols), 0, 0);
    } else {
      LOGGER.warn("Expected positive value for MaximumFieldCount; got {}", fieldRows * fieldCols);
    }

    for (int row = 0; row < wellRows; row++) {
      for (int col = 0; col < wellCols; col++) {
        int index = row * wellCols + col;

        store.setWellID(MetadataTools.createLSID("Well", 0, index), 0, index);
        store.setWellRow(new NonNegativeInteger(row), 0, index);
        store.setWellColumn(new NonNegativeInteger(col), 0, index);
      }
    }

    for (int i = 0; i < getSeriesCount(); i++) {
      int well = i / (fieldRows * fieldCols);
      int field = i % (fieldRows * fieldCols);

      MetadataTools.setDefaultCreationDate(store, tiffs[well][0], i);

      String name = wellLabels.get(well);
      String row = name.substring(0, 1);
      Integer col = Integer.parseInt(name.substring(1));

      int index = (row.charAt(0) - 'A') * wellCols + col - 1;

      String wellSampleID = MetadataTools.createLSID("WellSample", 0, index, field);
      store.setWellSampleID(wellSampleID, 0, index, field);
      store.setWellSampleIndex(new NonNegativeInteger(i), 0, index, field);

      String imageID = MetadataTools.createLSID("Image", i);
      store.setWellSampleImageRef(imageID, 0, index, field);
      store.setImageID(imageID, i);
      store.setImageName(name + " Field #" + (field + 1), i);

      store.setPlateAcquisitionWellSampleRef(wellSampleID, 0, 0, i);
    }

    MetadataLevel level = getMetadataOptions().getMetadataLevel();
    if (level != MetadataLevel.MINIMUM) {
      String instrumentID = MetadataTools.createLSID("Instrument", 0);
      store.setInstrumentID(instrumentID, 0);

      String objectiveID = MetadataTools.createLSID("Objective", 0, 0);
      store.setObjectiveID(objectiveID, 0, 0);
      if (objective != null) {
        String[] tokens = objective.split(" ");
        String mag = tokens[0].replaceAll("[xX]", "");
        String na = null;
        int naIndex = 0;
        for (int i = 0; i < tokens.length; i++) {
          if (tokens[i].equals("NA")) {
            naIndex = i + 1;
            na = tokens[naIndex];
            break;
          }
        }

        Integer magnification = new Integer(mag);
        if (magnification > 0) {
          store.setObjectiveNominalMagnification(new PositiveInteger(magnification), 0, 0);
        } else {
          LOGGER.warn("Expected positive value for NominalMagnification; got {}", magnification);
        }
        if (na != null) {
          na = na.substring(0, 1) + "." + na.substring(1);
          store.setObjectiveLensNA(new Double(na), 0, 0);
        }
        if (naIndex + 1 < tokens.length) {
          store.setObjectiveManufacturer(tokens[naIndex + 1], 0, 0);
        }
      }

      // populate LogicalChannel data
      for (int i = 0; i < getSeriesCount(); i++) {
        store.setImageInstrumentRef(instrumentID, i);
        store.setObjectiveSettingsID(objectiveID, i);

        for (int c = 0; c < getSizeC(); c++) {
          store.setChannelName(channelNames.get(c), i, c);
          if (emWave[c] > 0) {
            store.setChannelEmissionWavelength(new PositiveInteger(emWave[c]), i, c);
          } else {
            LOGGER.warn("Expected positive value for EmissionWavelength; got {}", emWave[c]);
          }
          if (exWave[c] > 0) {
            store.setChannelExcitationWavelength(new PositiveInteger(exWave[c]), i, c);
          } else {
            LOGGER.warn("Expected positive value for ExcitationWavelength; got {}", exWave[c]);
          }

          String detectorID = MetadataTools.createLSID("Detector", 0, c);
          store.setDetectorID(detectorID, 0, c);
          store.setDetectorSettingsID(detectorID, i, c);
          store.setDetectorSettingsGain(gain[c], i, c);
          store.setDetectorSettingsOffset(offset[c], i, c);
          store.setDetectorSettingsBinning(getBinning(binning), i, c);
        }

        long firstPlane = 0;
        for (int p = 0; p < getImageCount(); p++) {
          int[] zct = getZCTCoords(p);
          store.setPlaneExposureTime(exposure[zct[1]], i, p);
          String file = getFilename(i, p);
          if (file != null) {
            long plane = getTimestamp(file);
            if (p == 0) {
              firstPlane = plane;
            }
            double timestamp = (plane - firstPlane) / 1000.0;
            store.setPlaneDeltaT(timestamp, i, p);
          }
        }
      }

      store.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
      store.setPlateRowNamingConvention(getNamingConvention("Letter"), 0);
      store.setPlateColumnNamingConvention(getNamingConvention("Number"), 0);
      store.setPlateName(plateName, 0);
      store.setPlateDescription(plateDescription, 0);

      if (level != MetadataLevel.NO_OVERLAYS) {
        parseROIs(store);
      }
    }
  }