Search in sources :

Example 21 with FormatException

use of loci.formats.FormatException in project bioformats by openmicroscopy.

the class HitachiReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    if (!checkSuffix(id, "txt")) {
        String base = id;
        if (base.indexOf('.') >= 0) {
            base = base.substring(0, base.lastIndexOf("."));
        }
        id = base + ".txt";
        initFile(id);
        return;
    }
    super.initFile(id);
    String data = DataTools.readFile(id);
    IniParser parser = new IniParser();
    parser.setBackslashContinuesLine(false);
    IniList ini = parser.parseINI(new BufferedReader(new StringReader(data)));
    IniTable image = ini.getTable("SemImageFile");
    if (image == null) {
        throw new FormatException("Could not find 'SemImageFile' table.");
    }
    for (String key : image.keySet()) {
        addGlobalMeta(key, image.get(key));
    }
    String imageName = image.get("SampleName");
    String pixelsFile = image.get("ImageName");
    String date = image.get("Date");
    String time = image.get("Time");
    Location parent = new Location(id).getAbsoluteFile().getParentFile();
    pixelsFile = new Location(parent, pixelsFile).getAbsolutePath();
    ClassList<IFormatReader> classes = ImageReader.getDefaultReaderClasses();
    Class<? extends IFormatReader>[] classArray = classes.getClasses();
    ClassList<IFormatReader> newClasses = new ClassList<IFormatReader>(IFormatReader.class);
    for (Class<? extends IFormatReader> c : classArray) {
        if (!c.equals(HitachiReader.class)) {
            newClasses.addClass(c);
        }
    }
    helperReader = new ImageReader(newClasses);
    helperReader.setId(pixelsFile);
    core = new ArrayList<CoreMetadata>(helperReader.getCoreMetadataList());
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this, getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM);
    store.setImageName(imageName, 0);
    date = DateTools.formatDate(date + " " + time, DATE_FORMAT);
    if (date != null) {
        store.setImageAcquisitionDate(new Timestamp(date), 0);
    }
    populateOMEMetadata(image, store);
}
Also used : IniParser(loci.common.IniParser) IFormatReader(loci.formats.IFormatReader) IniList(loci.common.IniList) ClassList(loci.formats.ClassList) CoreMetadata(loci.formats.CoreMetadata) Timestamp(ome.xml.model.primitives.Timestamp) FormatException(loci.formats.FormatException) MetadataStore(loci.formats.meta.MetadataStore) IniTable(loci.common.IniTable) BufferedReader(java.io.BufferedReader) StringReader(java.io.StringReader) ImageReader(loci.formats.ImageReader) Location(loci.common.Location)

Example 22 with FormatException

use of loci.formats.FormatException in project bioformats by openmicroscopy.

the class ImarisHDFReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    try {
        ServiceFactory factory = new ServiceFactory();
        netcdf = factory.getInstance(NetCDFService.class);
        netcdf.setFile(id);
    } catch (DependencyException e) {
        throw new MissingLibraryException(NetCDFServiceImpl.NO_NETCDF_MSG, e);
    }
    pixelSizeX = pixelSizeY = pixelSizeZ = 1;
    emWave = new ArrayList<String>();
    exWave = new ArrayList<String>();
    channelMin = new ArrayList<String>();
    channelMax = new ArrayList<String>();
    gain = new ArrayList<String>();
    pinhole = new ArrayList<String>();
    channelName = new ArrayList<String>();
    microscopyMode = new ArrayList<String>();
    colors = new ArrayList<double[]>();
    seriesCount = 0;
    // read all of the metadata key/value pairs
    parseAttributes();
    CoreMetadata ms0 = core.get(0);
    if (seriesCount > 1) {
        for (int i = 1; i < seriesCount; i++) {
            core.add(new CoreMetadata());
        }
        for (int i = 1; i < seriesCount; i++) {
            CoreMetadata ms = core.get(i);
            String groupPath = "DataSet/ResolutionLevel_" + i + "/TimePoint_0/Channel_0";
            ms.sizeX = Integer.parseInt(netcdf.getAttributeValue(groupPath + "/ImageSizeX"));
            ms.sizeY = Integer.parseInt(netcdf.getAttributeValue(groupPath + "/ImageSizeY"));
            ms.sizeZ = Integer.parseInt(netcdf.getAttributeValue(groupPath + "/ImageSizeZ"));
            ms.imageCount = ms.sizeZ * getSizeC() * getSizeT();
            ms.sizeC = getSizeC();
            ms.sizeT = getSizeT();
            ms.thumbnail = true;
            if (ms.sizeZ == ms0.sizeZ && ms.sizeC == ms0.sizeC && ms.sizeT == ms0.sizeT) {
                // do not assume that all series will have the same dimensions
                // if the Z, C or T size is different, then it cannot
                // be a subresolution
                ms0.resolutionCount++;
            }
        }
    }
    ms0.imageCount = getSizeZ() * getSizeC() * getSizeT();
    ms0.thumbnail = false;
    ms0.dimensionOrder = "XYZCT";
    // determine pixel type - this isn't stored in the metadata, so we need
    // to check the pixels themselves
    int type = -1;
    Object pix = getImageData(0, 0, 0, 1, 1);
    if (pix instanceof byte[][])
        type = FormatTools.UINT8;
    else if (pix instanceof short[][])
        type = FormatTools.UINT16;
    else if (pix instanceof int[][])
        type = FormatTools.UINT32;
    else if (pix instanceof float[][])
        type = FormatTools.FLOAT;
    else if (pix instanceof double[][])
        type = FormatTools.DOUBLE;
    else {
        throw new FormatException("Unknown pixel type: " + pix);
    }
    for (int i = 0; i < core.size(); i++) {
        CoreMetadata ms = core.get(i);
        ms.pixelType = type;
        ms.dimensionOrder = "XYZCT";
        ms.rgb = false;
        ms.thumbSizeX = 128;
        ms.thumbSizeY = 128;
        ms.orderCertain = true;
        ms.littleEndian = true;
        ms.interleaved = false;
        ms.indexed = colors.size() >= getSizeC();
    }
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
    String imageName = new Location(getCurrentFile()).getName();
    for (int s = 0; s < getSeriesCount(); s++) {
        store.setImageName(imageName + " Resolution Level " + (s + 1), s);
    }
    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.MINIMUM) {
        return;
    }
    int cIndex = 0;
    for (int s = 0; s < getSeriesCount(); s++) {
        setSeries(s);
        double px = pixelSizeX, py = pixelSizeY, pz = pixelSizeZ;
        if (px == 1)
            px = (maxX - minX) / getSizeX();
        if (py == 1)
            py = (maxY - minY) / getSizeY();
        if (pz == 1)
            pz = (maxZ - minZ) / getSizeZ();
        Length sizeX = FormatTools.getPhysicalSizeX(px);
        Length sizeY = FormatTools.getPhysicalSizeY(py);
        Length sizeZ = FormatTools.getPhysicalSizeZ(pz);
        if (sizeX != null) {
            store.setPixelsPhysicalSizeX(sizeX, s);
        }
        if (sizeY != null) {
            store.setPixelsPhysicalSizeY(sizeY, s);
        }
        if (sizeZ != null) {
            store.setPixelsPhysicalSizeZ(sizeZ, s);
        }
        for (int i = 0; i < getSizeC(); i++, cIndex++) {
            Float gainValue = null;
            Integer pinholeValue = null, emWaveValue = null, exWaveValue;
            if (cIndex < gain.size()) {
                try {
                    gainValue = new Float(gain.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            if (cIndex < pinhole.size()) {
                try {
                    pinholeValue = new Integer(pinhole.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            if (cIndex < emWave.size()) {
                try {
                    emWaveValue = new Integer(emWave.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            if (cIndex < exWave.size()) {
                try {
                    exWaveValue = new Integer(exWave.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            Double minValue = null, maxValue = null;
            if (cIndex < channelMin.size()) {
                try {
                    minValue = new Double(channelMin.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            if (cIndex < channelMax.size()) {
                try {
                    maxValue = new Double(channelMax.get(cIndex));
                } catch (NumberFormatException e) {
                }
            }
            if (i < colors.size()) {
                double[] color = colors.get(i);
                Color realColor = new Color((int) (color[0] * 255), (int) (color[1] * 255), (int) (color[2] * 255), 255);
                store.setChannelColor(realColor, s, i);
            }
        }
    }
    setSeries(0);
}
Also used : ServiceFactory(loci.common.services.ServiceFactory) Color(ome.xml.model.primitives.Color) DependencyException(loci.common.services.DependencyException) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) MissingLibraryException(loci.formats.MissingLibraryException) NetCDFService(loci.formats.services.NetCDFService) Location(loci.common.Location)

Example 23 with FormatException

use of loci.formats.FormatException in project bioformats by openmicroscopy.

the class InCellReader method openBytes.

/**
 * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
 */
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
    int[] coordinates = getZCTCoords(no);
    int well = getWellFromSeries(getSeries());
    int field = getFieldFromSeries(getSeries());
    int timepoint = oneTimepointPerSeries ? getSeries() % channelsPerTimepoint.size() : coordinates[2];
    int image = getIndex(coordinates[0], coordinates[1], 0);
    if (imageFiles[well][field][timepoint][image] == null)
        return buf;
    String filename = imageFiles[well][field][timepoint][image].filename;
    if (filename == null || !(new Location(filename).exists()))
        return buf;
    if (imageFiles[well][field][timepoint][image].isTiff) {
        try {
            tiffReader.setId(filename);
            return tiffReader.openBytes(0, buf, x, y, w, h);
        } catch (FormatException e) {
            LOGGER.debug("", e);
        } catch (IOException e) {
            LOGGER.debug("", e);
        }
        return buf;
    }
    // pixels are stored in .im files
    RandomAccessInputStream s = new RandomAccessInputStream(filename);
    if (s.length() > FormatTools.getPlaneSize(this)) {
        s.seek(128);
        readPlane(s, x, y, w, h, buf);
    }
    s.close();
    return buf;
}
Also used : IOException(java.io.IOException) RandomAccessInputStream(loci.common.RandomAccessInputStream) FormatException(loci.formats.FormatException) Location(loci.common.Location)

Example 24 with FormatException

use of loci.formats.FormatException in project bioformats by openmicroscopy.

the class GatanReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    in = new RandomAccessInputStream(id);
    pixelOffset = 0;
    CoreMetadata m = core.get(0);
    LOGGER.info("Verifying Gatan format");
    m.littleEndian = false;
    pixelSizes = new ArrayList<Double>();
    units = new ArrayList<String>();
    shapes = new ArrayList<ROIShape>();
    in.order(isLittleEndian());
    // only support version 3
    version = in.readInt();
    if (version != 3 && version != 4) {
        throw new FormatException("invalid header");
    }
    LOGGER.info("Reading tags");
    in.skipBytes(4);
    skipPadding();
    m.littleEndian = in.readInt() != 1;
    in.order(isLittleEndian());
    // TagGroup instance
    in.skipBytes(2);
    skipPadding();
    int numTags = in.readInt();
    if (numTags > in.length()) {
        m.littleEndian = !isLittleEndian();
        in.order(isLittleEndian());
        adjustEndianness = false;
    }
    LOGGER.debug("tags ({}) {", numTags);
    try {
        parseTags(numTags, null, "  ");
    } catch (Exception e) {
        throw new FormatException("Unable to parse metadata tag", e);
    }
    LOGGER.debug("}");
    LOGGER.info("Populating metadata");
    m.littleEndian = true;
    if (getSizeX() == 0 || getSizeY() == 0) {
        throw new FormatException("Dimensions information not found");
    }
    if (m.sizeZ == 0) {
        m.sizeZ = 1;
    }
    m.sizeC = 1;
    m.sizeT = 1;
    m.dimensionOrder = "XYZTC";
    m.imageCount = getSizeZ() * getSizeC() * getSizeT();
    int bytes = (int) (numPixelBytes / (getSizeX() * getSizeY() * (long) getImageCount()));
    if (bytes != FormatTools.getBytesPerPixel(getPixelType())) {
        m.pixelType = FormatTools.pixelTypeFromBytes(bytes, signed, false);
    }
    m.rgb = false;
    m.interleaved = false;
    m.metadataComplete = true;
    m.indexed = false;
    m.falseColor = false;
    // The metadata store we're working with.
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this, true);
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        int index = 0;
        if (pixelSizes.size() > 4) {
            index = pixelSizes.size() - 3;
        } else if (pixelSizes.size() == 4) {
            if (Math.abs(pixelSizes.get(0) - 1.0) < Constants.EPSILON) {
                index = pixelSizes.size() - 2;
            }
        }
        if (index + 2 < pixelSizes.size() && Math.abs(pixelSizes.get(index + 1) - pixelSizes.get(index + 2)) < Constants.EPSILON) {
            if (Math.abs(pixelSizes.get(index) - pixelSizes.get(index + 1)) > Constants.EPSILON && getSizeY() > 1) {
                index++;
            }
        }
        if (index < pixelSizes.size() - 1) {
            Double x = pixelSizes.get(index);
            Double y = pixelSizes.get(index + 1);
            String xUnits = index < units.size() ? units.get(index) : "";
            String yUnits = index + 1 < units.size() ? units.get(index + 1) : "";
            Length sizeX = FormatTools.getPhysicalSizeX(x, convertUnits(xUnits));
            Length sizeY = FormatTools.getPhysicalSizeY(y, convertUnits(yUnits));
            if (sizeX != null) {
                store.setPixelsPhysicalSizeX(sizeX, 0);
            }
            if (sizeY != null) {
                store.setPixelsPhysicalSizeY(sizeY, 0);
            }
            if (index < pixelSizes.size() - 2) {
                Double z = pixelSizes.get(index + 2);
                String zUnits = index + 2 < units.size() ? units.get(index + 2) : "";
                Length sizeZ = FormatTools.getPhysicalSizeZ(z, convertUnits(zUnits));
                if (sizeZ != null) {
                    store.setPixelsPhysicalSizeZ(sizeZ, 0);
                }
            }
        }
        String instrument = MetadataTools.createLSID("Instrument", 0);
        store.setInstrumentID(instrument, 0);
        store.setImageInstrumentRef(instrument, 0);
        String objective = MetadataTools.createLSID("Objective", 0, 0);
        store.setObjectiveID(objective, 0, 0);
        store.setObjectiveCorrection(getCorrection("Unknown"), 0, 0);
        store.setObjectiveImmersion(getImmersion("Unknown"), 0, 0);
        store.setObjectiveNominalMagnification(mag, 0, 0);
        store.setObjectiveSettingsID(objective, 0);
        String detector = MetadataTools.createLSID("Detector", 0, 0);
        store.setDetectorID(detector, 0, 0);
        store.setDetectorSettingsID(detector, 0, 0);
        store.setDetectorSettingsVoltage(new ElectricPotential(voltage, UNITS.VOLT), 0, 0);
        if (info == null)
            info = "";
        String[] scopeInfo = info.split("\\(");
        for (String token : scopeInfo) {
            token = token.trim();
            if (token.startsWith("Mode")) {
                token = token.substring(token.indexOf(' ')).trim();
                String mode = token.substring(0, token.indexOf(' ')).trim();
                if (mode.equals("TEM"))
                    mode = "Other";
                store.setChannelAcquisitionMode(getAcquisitionMode(mode), 0, 0);
            }
        }
        store.setPlanePositionX(posX, 0, 0);
        store.setPlanePositionY(posY, 0, 0);
        store.setPlanePositionZ(posZ, 0, 0);
        for (int i = 0; i < getImageCount(); i++) {
            store.setPlaneExposureTime(new Time(sampleTime, UNITS.SECOND), 0, i);
        }
    }
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.NO_OVERLAYS && shapes.size() > 0) {
        for (int i = 0; i < shapes.size(); i++) {
            String roi = MetadataTools.createLSID("ROI", i);
            store.setROIID(roi, i);
            store.setImageROIRef(roi, 0, i);
            String shapeID = MetadataTools.createLSID("Shape", i, 0);
            ROIShape shape = shapes.get(i);
            switch(shape.type) {
                case LINE:
                    store.setLineID(shapeID, i, 0);
                    store.setLineX1(shape.x1, i, 0);
                    store.setLineY1(shape.y1, i, 0);
                    store.setLineX2(shape.x2, i, 0);
                    store.setLineY2(shape.y2, i, 0);
                    store.setLineText(shape.text, i, 0);
                    store.setLineFontSize(shape.fontSize, i, 0);
                    store.setLineStrokeColor(shape.strokeColor, i, 0);
                    break;
                case TEXT:
                    store.setLabelID(shapeID, i, 0);
                    store.setLabelX(shape.x1, i, 0);
                    store.setLabelY(shape.y1, i, 0);
                    store.setLabelText(shape.text, i, 0);
                    store.setLabelFontSize(shape.fontSize, i, 0);
                    store.setLabelStrokeColor(shape.strokeColor, i, 0);
                    break;
                case ELLIPSE:
                    store.setEllipseID(shapeID, i, 0);
                    double radiusX = (shape.x2 - shape.x1) / 2;
                    double radiusY = (shape.y2 - shape.y1) / 2;
                    store.setEllipseX(shape.x1 + radiusX, i, 0);
                    store.setEllipseY(shape.y1 + radiusY, i, 0);
                    store.setEllipseRadiusX(radiusX, i, 0);
                    store.setEllipseRadiusY(radiusY, i, 0);
                    store.setEllipseText(shape.text, i, 0);
                    store.setEllipseFontSize(shape.fontSize, i, 0);
                    store.setEllipseStrokeColor(shape.strokeColor, i, 0);
                    break;
                case RECTANGLE:
                    store.setRectangleID(shapeID, i, 0);
                    store.setRectangleX(shape.x1, i, 0);
                    store.setRectangleY(shape.y1, i, 0);
                    store.setRectangleWidth(shape.x2 - shape.x1, i, 0);
                    store.setRectangleHeight(shape.y2 - shape.y1, i, 0);
                    store.setRectangleText(shape.text, i, 0);
                    store.setRectangleFontSize(shape.fontSize, i, 0);
                    store.setRectangleStrokeColor(shape.strokeColor, i, 0);
                    break;
                default:
                    LOGGER.warn("Unknown ROI type: {}", shape.type);
            }
        }
    }
}
Also used : Time(ome.units.quantity.Time) CoreMetadata(loci.formats.CoreMetadata) ElectricPotential(ome.units.quantity.ElectricPotential) FormatException(loci.formats.FormatException) FormatException(loci.formats.FormatException) IOException(java.io.IOException) ParseException(java.text.ParseException) MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 25 with FormatException

use of loci.formats.FormatException in project bioformats by openmicroscopy.

the class HamamatsuVMSReader method openBytes.

/**
 * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
 */
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
    int startCol = x / MAX_JPEG_SIZE;
    int startRow = y / MAX_JPEG_SIZE;
    String file = null;
    switch(getCoreIndex()) {
        case 0:
            file = tileFiles[no][startRow][startCol];
            break;
        case 1:
            file = macroFile;
            break;
        case 2:
            file = mapFile;
            break;
    }
    if (getSizeX() <= MAX_SIZE || getSizeY() <= MAX_SIZE) {
        JPEGReader reader = new JPEGReader();
        reader.setId(file);
        reader.openBytes(0, buf, x, y, w, h);
        reader.close();
        return buf;
    }
    if (service == null) {
        service = new JPEGTurboServiceImpl();
    }
    try {
        Region image = new Region(x, y, w, h);
        for (int row = startRow; row < nRows; row++) {
            for (int col = startCol; col < nCols; col++) {
                Region tile = new Region(col * MAX_JPEG_SIZE, row * MAX_JPEG_SIZE, col == nCols - 1 ? getSizeX() % MAX_JPEG_SIZE : MAX_JPEG_SIZE, row == nRows - 1 ? getSizeY() % MAX_JPEG_SIZE : MAX_JPEG_SIZE);
                if (!tile.intersects(image)) {
                    continue;
                }
                file = tileFiles[no][row][col];
                if (initializedSeries != getCoreIndex() || initializedPlane != no || !file.equals(initializedFile)) {
                    service.close();
                    if (restartMarkers.containsKey(file)) {
                        service.setRestartMarkers(restartMarkers.get(file));
                    } else {
                        service.setRestartMarkers(null);
                    }
                    // closing the service will close this file
                    RandomAccessInputStream s = new RandomAccessInputStream(file);
                    service.initialize(s, tile.width, tile.height);
                    restartMarkers.put(file, service.getRestartMarkers());
                    initializedSeries = getCoreIndex();
                    initializedPlane = no;
                    initializedFile = file;
                }
                Region intersection = tile.intersection(image);
                int tileX = intersection.x % MAX_JPEG_SIZE;
                int tileY = intersection.y % MAX_JPEG_SIZE;
                int rowLen = intersection.width * getRGBChannelCount();
                byte[] b = new byte[rowLen * intersection.height];
                service.getTile(b, tileX, tileY, intersection.width, intersection.height);
                for (int tileRow = 0; tileRow < intersection.height; tileRow++) {
                    int src = tileRow * rowLen;
                    int dest = (((intersection.y + tileRow - y) * w) + (intersection.x - x)) * getRGBChannelCount();
                    System.arraycopy(b, src, buf, dest, rowLen);
                }
            }
        }
    } catch (ServiceException e) {
        throw new FormatException(e);
    }
    return buf;
}
Also used : ServiceException(loci.common.services.ServiceException) Region(loci.common.Region) RandomAccessInputStream(loci.common.RandomAccessInputStream) FormatException(loci.formats.FormatException) JPEGTurboServiceImpl(loci.formats.services.JPEGTurboServiceImpl)

Aggregations

FormatException (loci.formats.FormatException)246 IOException (java.io.IOException)91 CoreMetadata (loci.formats.CoreMetadata)86 RandomAccessInputStream (loci.common.RandomAccessInputStream)73 MetadataStore (loci.formats.meta.MetadataStore)66 Location (loci.common.Location)48 DependencyException (loci.common.services.DependencyException)44 ServiceException (loci.common.services.ServiceException)43 Length (ome.units.quantity.Length)39 ServiceFactory (loci.common.services.ServiceFactory)35 ArrayList (java.util.ArrayList)33 IFD (loci.formats.tiff.IFD)32 TiffParser (loci.formats.tiff.TiffParser)25 OMEXMLService (loci.formats.services.OMEXMLService)23 Time (ome.units.quantity.Time)23 Timestamp (ome.xml.model.primitives.Timestamp)23 ImagePlus (ij.ImagePlus)21 ImageReader (loci.formats.ImageReader)20 IMetadata (loci.formats.meta.IMetadata)18 IFormatReader (loci.formats.IFormatReader)14