use of loci.formats.tiff.PhotoInterp in project bioformats by openmicroscopy.
the class MetamorphReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
super.initStandardMetadata();
CoreMetadata ms0 = core.get(0);
ms0.sizeZ = 1;
ms0.sizeT = 0;
int rgbChannels = getSizeC();
// Now that the base TIFF standard metadata has been parsed, we need to
// parse out the STK metadata from the UIC4TAG.
TiffIFDEntry uic1tagEntry = null;
TiffIFDEntry uic2tagEntry = null;
TiffIFDEntry uic4tagEntry = null;
try {
uic1tagEntry = tiffParser.getFirstIFDEntry(UIC1TAG);
uic2tagEntry = tiffParser.getFirstIFDEntry(UIC2TAG);
uic4tagEntry = tiffParser.getFirstIFDEntry(UIC4TAG);
} catch (IllegalArgumentException exc) {
LOGGER.debug("Unknown tag", exc);
}
try {
if (uic4tagEntry != null) {
mmPlanes = uic4tagEntry.getValueCount();
}
if (mmPlanes == 0) {
mmPlanes = ifds.size();
}
if (uic2tagEntry != null) {
parseUIC2Tags(uic2tagEntry.getValueOffset());
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (uic4tagEntry != null) {
parseUIC4Tags(uic4tagEntry.getValueOffset());
}
if (uic1tagEntry != null) {
parseUIC1Tags(uic1tagEntry.getValueOffset(), uic1tagEntry.getValueCount());
}
}
in.seek(uic4tagEntry.getValueOffset());
} catch (NullPointerException exc) {
LOGGER.debug("", exc);
} catch (IOException exc) {
LOGGER.debug("Failed to parse proprietary tags", exc);
}
try {
// copy ifds into a new array of Hashtables that will accommodate the
// additional image planes
IFD firstIFD = ifds.get(0);
long[] uic2 = firstIFD.getIFDLongArray(UIC2TAG);
if (uic2 == null) {
throw new FormatException("Invalid Metamorph file. Tag " + UIC2TAG + " not found.");
}
ms0.imageCount = uic2.length;
Object entry = firstIFD.getIFDValue(UIC3TAG);
TiffRational[] uic3 = entry instanceof TiffRational[] ? (TiffRational[]) entry : new TiffRational[] { (TiffRational) entry };
wave = new double[uic3.length];
final List<Double> uniqueWavelengths = new ArrayList<Double>();
for (int i = 0; i < uic3.length; i++) {
wave[i] = uic3[i].doubleValue();
addSeriesMeta("Wavelength [" + intFormatMax(i, mmPlanes) + "]", wave[i]);
final Double v = wave[i];
if (!uniqueWavelengths.contains(v))
uniqueWavelengths.add(v);
}
if (getSizeC() == 1) {
ms0.sizeC = uniqueWavelengths.size();
if (getSizeC() < getImageCount() && getSizeC() > (getImageCount() - getSizeC()) && (getImageCount() % getSizeC()) != 0) {
ms0.sizeC = getImageCount();
}
}
IFDList tempIFDs = new IFDList();
long[] oldOffsets = firstIFD.getStripOffsets();
long[] stripByteCounts = firstIFD.getStripByteCounts();
int rowsPerStrip = (int) firstIFD.getRowsPerStrip()[0];
int stripsPerImage = getSizeY() / rowsPerStrip;
if (stripsPerImage * rowsPerStrip != getSizeY())
stripsPerImage++;
PhotoInterp check = firstIFD.getPhotometricInterpretation();
if (check == PhotoInterp.RGB_PALETTE) {
firstIFD.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION, PhotoInterp.BLACK_IS_ZERO);
}
emWavelength = firstIFD.getIFDLongArray(UIC3TAG);
// for each image plane, construct an IFD hashtable
IFD temp;
for (int i = 0; i < getImageCount(); i++) {
// copy data from the first IFD
temp = new IFD(firstIFD);
// now we need a StripOffsets entry - the original IFD doesn't have this
long[] newOffsets = new long[stripsPerImage];
if (stripsPerImage * (i + 1) <= oldOffsets.length) {
System.arraycopy(oldOffsets, stripsPerImage * i, newOffsets, 0, stripsPerImage);
} else {
System.arraycopy(oldOffsets, 0, newOffsets, 0, stripsPerImage);
long image = (stripByteCounts[0] / rowsPerStrip) * getSizeY();
for (int q = 0; q < stripsPerImage; q++) {
newOffsets[q] += i * image;
}
}
temp.putIFDValue(IFD.STRIP_OFFSETS, newOffsets);
long[] newByteCounts = new long[stripsPerImage];
if (stripsPerImage * i < stripByteCounts.length) {
System.arraycopy(stripByteCounts, stripsPerImage * i, newByteCounts, 0, stripsPerImage);
} else {
Arrays.fill(newByteCounts, stripByteCounts[0]);
}
temp.putIFDValue(IFD.STRIP_BYTE_COUNTS, newByteCounts);
tempIFDs.add(temp);
}
ifds = tempIFDs;
} catch (IllegalArgumentException exc) {
LOGGER.debug("Unknown tag", exc);
} catch (NullPointerException exc) {
LOGGER.debug("", exc);
} catch (FormatException exc) {
LOGGER.debug("Failed to build list of IFDs", exc);
}
// parse (mangle) TIFF comment
String descr = ifds.get(0).getComment();
if (descr != null) {
String[] lines = descr.split("\n");
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < lines.length; i++) {
String line = lines[i].trim();
if (line.startsWith("<") && line.endsWith(">")) {
// XML comment; this will have already been parsed so can be ignored
break;
}
int colon = line.indexOf(':');
if (colon < 0) {
// normal line (not a key/value pair)
if (line.length() > 0) {
// not a blank line
sb.append(line);
sb.append(" ");
}
} else {
String descrValue = null;
if (i == 0) {
// first line could be mangled; make a reasonable guess
int dot = line.lastIndexOf(".", colon);
if (dot >= 0) {
descrValue = line.substring(0, dot + 1);
}
line = line.substring(dot + 1);
colon -= dot + 1;
}
// append value to description
if (descrValue != null) {
sb.append(descrValue);
if (!descrValue.endsWith("."))
sb.append(".");
sb.append(" ");
}
// add key/value pair embedded in comment as separate metadata
String key = line.substring(0, colon);
String value = line.substring(colon + 1).trim();
addSeriesMeta(key, value);
if (key.equals("Exposure")) {
if (value.indexOf('=') != -1) {
value = value.substring(value.indexOf('=') + 1).trim();
}
if (value.indexOf(' ') != -1) {
value = value.substring(0, value.indexOf(' '));
}
try {
value = value.replace(',', '.');
double exposure = Double.parseDouble(value);
exposureTime = exposure / 1000;
} catch (NumberFormatException e) {
}
} else if (key.equals("Bit Depth")) {
if (value.indexOf('-') != -1) {
value = value.substring(0, value.indexOf('-'));
}
try {
ms0.bitsPerPixel = Integer.parseInt(value);
} catch (NumberFormatException e) {
}
} else if (key.equals("Gain")) {
int space = value.indexOf(' ');
if (space != -1) {
int nextSpace = value.indexOf(" ", space + 1);
if (nextSpace < 0) {
nextSpace = value.length();
}
try {
gain = new Double(value.substring(space, nextSpace));
} catch (NumberFormatException e) {
}
}
}
}
}
// replace comment with trimmed version
descr = sb.toString().trim();
if (descr.equals(""))
metadata.remove("Comment");
else
addSeriesMeta("Comment", descr);
}
ms0.sizeT = getImageCount() / (getSizeZ() * (getSizeC() / rgbChannels));
if (getSizeT() * getSizeZ() * (getSizeC() / rgbChannels) != getImageCount()) {
ms0.sizeT = 1;
ms0.sizeZ = getImageCount() / (getSizeC() / rgbChannels);
}
// if '_t' is present in the file name, swap Z and T sizes
// this file was probably part of a larger dataset, but the .nd file is
// missing
String filename = currentId.substring(currentId.lastIndexOf(File.separator) + 1);
if (filename.contains("_t") && getSizeT() > 1) {
int z = getSizeZ();
ms0.sizeZ = getSizeT();
ms0.sizeT = z;
}
if (getSizeZ() == 0)
ms0.sizeZ = 1;
if (getSizeT() == 0)
ms0.sizeT = 1;
if (getSizeZ() * getSizeT() * (isRGB() ? 1 : getSizeC()) != getImageCount()) {
ms0.sizeZ = getImageCount();
ms0.sizeT = 1;
if (!isRGB())
ms0.sizeC = 1;
}
}
use of loci.formats.tiff.PhotoInterp in project bioformats by openmicroscopy.
the class NDPIReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see loci.formats.BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
super.initStandardMetadata();
ifds = tiffParser.getIFDs();
// fix the offsets for > 4 GB files
RandomAccessInputStream stream = new RandomAccessInputStream(currentId);
for (int i = 0; i < ifds.size(); i++) {
IFD ifd = ifds.get(i);
long[] stripOffsets = ifd.getStripOffsets();
boolean neededAdjustment = false;
for (int j = 0; j < stripOffsets.length; j++) {
long prevOffset = i == 0 ? 0 : ifds.get(i - 1).getStripOffsets()[0];
long prevByteCount = i == 0 ? 0 : ifds.get(i - 1).getStripByteCounts()[0];
long currentOffset = (int) stripOffsets[j];
while (currentOffset < prevOffset || currentOffset < prevOffset + prevByteCount) {
long newOffset = currentOffset + 0x100000000L;
if (newOffset < stream.length() && ((j > 0 && (currentOffset < stripOffsets[j - 1])) || (i > 0 && currentOffset < prevOffset + prevByteCount))) {
stripOffsets[j] = newOffset;
currentOffset = stripOffsets[j];
neededAdjustment = true;
}
}
}
if (neededAdjustment) {
ifd.putIFDValue(IFD.STRIP_OFFSETS, stripOffsets);
}
neededAdjustment = false;
long[] stripByteCounts = ifd.getStripByteCounts();
for (int j = 0; j < stripByteCounts.length; j++) {
long currentCount = (int) stripByteCounts[j];
long newByteCount = currentCount + 0x100000000L;
if (currentCount < 0 || neededAdjustment || newByteCount + stripOffsets[j] < in.length()) {
if (newByteCount < ifd.getImageWidth() * ifd.getImageLength()) {
stripByteCounts[j] = newByteCount;
neededAdjustment = true;
}
}
}
if (neededAdjustment) {
ifd.putIFDValue(IFD.STRIP_BYTE_COUNTS, stripByteCounts);
}
}
stream.close();
for (int i = 1; i < ifds.size(); i++) {
IFD ifd = ifds.get(i);
if (ifd.getImageWidth() == ifds.get(0).getImageWidth() && ifd.getImageLength() == ifds.get(0).getImageLength()) {
sizeZ++;
} else if (sizeZ == 1) {
boolean isPyramid;
Object source_lens_value = ifd.getIFDValue(SOURCE_LENS);
if (source_lens_value != null) {
float source_lens = (Float) source_lens_value;
// A value of -1 correspond to the macro image and a value of -2
// correspond to the map image
isPyramid = (source_lens != -1 && source_lens != -2);
} else {
// Assume the last IFD is the macro image
isPyramid = i < ifds.size() - 1;
}
if (isPyramid)
pyramidHeight++;
}
}
// repopulate core metadata
int seriesCount = pyramidHeight + (ifds.size() - pyramidHeight * sizeZ);
for (int i = 0; i < ifds.size(); i++) {
IFD ifd = ifds.get(i);
ifd.remove(THUMB_TAG_2);
ifds.set(i, ifd);
TiffIFDEntry markerTag = (TiffIFDEntry) ifd.get(MARKER_TAG);
if (markerTag != null) {
if (markerTag.getValueOffset() > in.length()) {
// can't rely upon the MARKER_TAG to be detected correctly
ifds.get(i).remove(MARKER_TAG);
} else {
Object value = tiffParser.getIFDValue(markerTag);
ifds.get(i).putIFDValue(MARKER_TAG, value);
}
}
tiffParser.fillInIFD(ifds.get(i));
int[] bpp = ifds.get(i).getBitsPerSample();
for (int q = 0; q < bpp.length; q++) {
if (bpp[q] < 8) {
bpp[q] = 8;
}
}
ifds.get(i).putIFDValue(IFD.BITS_PER_SAMPLE, bpp);
}
core.clear();
for (int s = 0; s < seriesCount; s++) {
CoreMetadata ms = new CoreMetadata();
core.add(ms);
if (s == 0) {
ms.resolutionCount = pyramidHeight;
}
}
for (int s = 0; s < core.size(); s++) {
IFD ifd = ifds.get(getIFDIndex(s, 0));
PhotoInterp p = ifd.getPhotometricInterpretation();
int samples = ifd.getSamplesPerPixel();
CoreMetadata ms = core.get(s);
ms.rgb = samples > 1 || p == PhotoInterp.RGB;
ms.sizeX = (int) ifd.getImageWidth();
ms.sizeY = (int) ifd.getImageLength();
ms.sizeZ = s < pyramidHeight ? sizeZ : 1;
ms.sizeT = 1;
ms.sizeC = ms.rgb ? samples : 1;
ms.littleEndian = ifd.isLittleEndian();
ms.indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null);
ms.imageCount = ms.sizeZ * ms.sizeT;
ms.pixelType = ifd.getPixelType();
ms.metadataComplete = true;
ms.interleaved = ms.sizeX > MAX_SIZE && ms.sizeY > MAX_SIZE;
ms.falseColor = false;
ms.dimensionOrder = "XYCZT";
ms.thumbnail = s != 0;
}
String metadataTag = ifds.get(0).getIFDStringValue(METADATA_TAG);
if (metadataTag != null) {
String[] entries = metadataTag.split("\n");
for (String entry : entries) {
int eq = entry.indexOf('=');
if (eq < 0) {
continue;
}
String key = entry.substring(0, eq).trim();
String value = entry.substring(eq + 1).trim();
addGlobalMeta(key, value);
if (key.equals("Objective.Lens.Magnificant")) {
// not a typo
magnification = new Double(value);
} else if (key.equals("NDP.S/N")) {
serialNumber = value;
} else if (key.equals("Product")) {
instrumentModel = value;
}
}
}
}
use of loci.formats.tiff.PhotoInterp in project bioformats by openmicroscopy.
the class NikonReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
super.initStandardMetadata();
// reset image dimensions
// the actual image data is stored in IFDs referenced by the SubIFD tag
// in the 'real' IFD
CoreMetadata m = core.get(0);
m.imageCount = ifds.size();
IFD firstIFD = ifds.get(0);
PhotoInterp photo = firstIFD.getPhotometricInterpretation();
int samples = firstIFD.getSamplesPerPixel();
m.rgb = samples > 1 || photo == PhotoInterp.RGB || photo == PhotoInterp.CFA_ARRAY;
if (photo == PhotoInterp.CFA_ARRAY)
samples = 3;
m.sizeX = (int) firstIFD.getImageWidth();
m.sizeY = (int) firstIFD.getImageLength();
m.sizeZ = 1;
m.sizeC = isRGB() ? samples : 1;
m.sizeT = ifds.size();
m.pixelType = firstIFD.getPixelType();
m.indexed = false;
// now look for the EXIF IFD pointer
IFDList exifIFDs = tiffParser.getExifIFDs();
if (exifIFDs.size() > 0) {
IFD exifIFD = exifIFDs.get(0);
tiffParser.fillInIFD(exifIFD);
for (Integer key : exifIFD.keySet()) {
int tag = key.intValue();
String name = IFD.getIFDTagName(tag);
if (tag == IFD.CFA_PATTERN) {
byte[] cfa = (byte[]) exifIFD.get(key);
int[] colorMap = new int[cfa.length];
for (int i = 0; i < cfa.length; i++) colorMap[i] = (int) cfa[i];
addGlobalMeta(name, colorMap);
cfaPattern = colorMap;
} else {
addGlobalMeta(name, exifIFD.get(key));
if (name.equals("MAKER_NOTE")) {
byte[] b = (byte[]) exifIFD.get(key);
int extra = new String(b, 0, 10, Constants.ENCODING).startsWith("Nikon") ? 10 : 0;
byte[] buf = new byte[b.length];
System.arraycopy(b, extra, buf, 0, buf.length - extra);
RandomAccessInputStream makerNote = new RandomAccessInputStream(buf);
TiffParser tp = new TiffParser(makerNote);
IFD note = null;
try {
note = tp.getFirstIFD();
} catch (Exception e) {
LOGGER.debug("Failed to parse first IFD", e);
}
if (note != null) {
for (Integer nextKey : note.keySet()) {
int nextTag = nextKey.intValue();
addGlobalMeta(name, note.get(nextKey));
if (nextTag == 150) {
b = (byte[]) note.get(nextKey);
RandomAccessInputStream s = new RandomAccessInputStream(b);
byte check1 = s.readByte();
byte check2 = s.readByte();
lossyCompression = check1 != 0x46;
vPredictor = new int[4];
for (int q = 0; q < vPredictor.length; q++) {
vPredictor[q] = s.readShort();
}
curve = new int[16385];
int bps = ifds.get(0).getBitsPerSample()[0];
int max = 1 << bps & 0x7fff;
int step = 0;
int csize = s.readShort();
if (csize > 1) {
step = max / (csize - 1);
}
if (check1 == 0x44 && check2 == 0x20 && step > 0) {
for (int i = 0; i < csize; i++) {
curve[i * step] = s.readShort();
}
for (int i = 0; i < max; i++) {
int n = i % step;
curve[i] = (curve[i - n] * (step - n) + curve[i - n + step] * n) / step;
}
s.seek(562);
split = s.readShort();
} else {
int maxValue = (int) Math.pow(2, bps) - 1;
Arrays.fill(curve, maxValue);
int nElements = (int) (s.length() - s.getFilePointer()) / 2;
if (nElements < 100) {
for (int i = 0; i < curve.length; i++) {
curve[i] = (short) i;
}
} else {
for (int q = 0; q < nElements; q++) {
curve[q] = s.readShort();
}
}
}
s.close();
} else if (nextTag == WHITE_BALANCE_RGB_COEFFS) {
whiteBalance = (TiffRational[]) note.get(nextKey);
}
}
}
makerNote.close();
}
}
}
}
}
use of loci.formats.tiff.PhotoInterp in project bioformats by openmicroscopy.
the class PyramidTiffReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see loci.formats.in.BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
int seriesCount = ifds.size();
// repopulate core metadata
core.clear();
for (int s = 0; s < seriesCount; s++) {
CoreMetadata ms = new CoreMetadata();
core.add(ms);
if (s == 0) {
ms.resolutionCount = seriesCount;
}
IFD ifd = ifds.get(s);
PhotoInterp p = ifd.getPhotometricInterpretation();
int samples = ifd.getSamplesPerPixel();
ms.rgb = samples > 1 || p == PhotoInterp.RGB;
long numTileRows = ifd.getTilesPerColumn() - 1;
long numTileCols = ifd.getTilesPerRow() - 1;
ms.sizeX = (int) ifd.getImageWidth();
ms.sizeY = (int) ifd.getImageLength();
ms.sizeZ = 1;
ms.sizeT = 1;
ms.sizeC = ms.rgb ? samples : 1;
ms.littleEndian = ifd.isLittleEndian();
ms.indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null);
ms.imageCount = 1;
ms.pixelType = ifd.getPixelType();
ms.metadataComplete = true;
ms.interleaved = false;
ms.falseColor = false;
ms.dimensionOrder = "XYCZT";
ms.thumbnail = s > 0;
}
}
use of loci.formats.tiff.PhotoInterp in project bioformats by openmicroscopy.
the class TrestleReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see loci.formats.in.BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
super.initStandardMetadata();
ifds = tiffParser.getIFDs();
for (IFD ifd : ifds) {
tiffParser.fillInIFD(ifd);
}
String comment = ifds.get(0).getComment();
String[] values = comment.split(";");
for (String v : values) {
int eq = v.indexOf('=');
if (eq < 0)
continue;
String key = v.substring(0, eq).trim();
String value = v.substring(eq + 1).trim();
addGlobalMeta(key, value);
if (key.equals("OverlapsXY")) {
String[] overlapValues = value.split(" ");
overlaps = new int[ifds.size() * 2];
for (int i = 0; i < overlapValues.length; i++) {
overlaps[i] = Integer.parseInt(overlapValues[i]);
}
}
}
int seriesCount = ifds.size();
core.clear();
for (int i = 0; i < seriesCount; i++) {
CoreMetadata c = new CoreMetadata();
if (i == 0 && !hasFlattenedResolutions()) {
c.resolutionCount = seriesCount;
}
core.add(c);
}
for (int s = 0; s < core.size(); s++) {
CoreMetadata ms = core.get(s);
IFD ifd = ifds.get(s);
PhotoInterp p = ifd.getPhotometricInterpretation();
int samples = ifd.getSamplesPerPixel();
ms.rgb = samples > 1 || p == PhotoInterp.RGB;
long numTileRows = ifd.getTilesPerColumn() - 1;
long numTileCols = ifd.getTilesPerRow() - 1;
int overlapX = overlaps[s * 2];
int overlapY = overlaps[s * 2 + 1];
ms.sizeX = (int) (ifd.getImageWidth() - (numTileCols * overlapX));
ms.sizeY = (int) (ifd.getImageLength() - (numTileRows * overlapY));
ms.sizeZ = 1;
ms.sizeT = 1;
ms.sizeC = ms.rgb ? samples : 1;
ms.littleEndian = ifd.isLittleEndian();
ms.indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null);
ms.imageCount = 1;
ms.pixelType = ifd.getPixelType();
ms.metadataComplete = true;
ms.interleaved = false;
ms.falseColor = false;
ms.dimensionOrder = "XYCZT";
ms.thumbnail = s > 0;
}
// look for all of the other associated metadata files
files = new ArrayList<String>();
Location baseFile = new Location(currentId).getAbsoluteFile();
Location parent = baseFile.getParentFile();
String name = baseFile.getName();
if (name.indexOf('.') >= 0) {
name = name.substring(0, name.indexOf('.') + 1);
}
roiFile = new Location(parent, name + "ROI").getAbsolutePath();
roiDrawFile = new Location(parent, name + "ROI-draw").getAbsolutePath();
String[] list = parent.list(true);
for (String f : list) {
if (!f.equals(baseFile.getName())) {
files.add(new Location(parent, f).getAbsolutePath());
}
}
}
Aggregations