Search in sources :

Example 1 with TiffRational

use of loci.formats.tiff.TiffRational 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;
    }
}
Also used : IFD(loci.formats.tiff.IFD) ArrayList(java.util.ArrayList) TiffRational(loci.formats.tiff.TiffRational) PhotoInterp(loci.formats.tiff.PhotoInterp) IOException(java.io.IOException) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) TiffIFDEntry(loci.formats.tiff.TiffIFDEntry) IFDList(loci.formats.tiff.IFDList)

Example 2 with TiffRational

use of loci.formats.tiff.TiffRational in project bioformats by openmicroscopy.

the class DNGReader 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 = FormatTools.UINT16;
    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 offset = DataTools.bytesToInt(b, b.length - 4, isLittleEndian());
                    byte[] buf = new byte[b.length + offset - 8];
                    System.arraycopy(b, b.length - 8, buf, 0, 8);
                    System.arraycopy(b, 0, buf, offset, b.length - 8);
                    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 == WHITE_BALANCE_RGB_COEFFS) {
                                if (note.get(nextTag) instanceof TiffRational[]) {
                                    TiffRational[] wb = (TiffRational[]) note.get(nextTag);
                                    whiteBalance = new double[wb.length];
                                    for (int i = 0; i < wb.length; i++) {
                                        whiteBalance[i] = wb[i].doubleValue();
                                    }
                                } else {
                                    // use a default white balance table
                                    whiteBalance = new double[3];
                                    whiteBalance[0] = 2.391381;
                                    whiteBalance[1] = 0.929156;
                                    whiteBalance[2] = 1.298254;
                                }
                            }
                        }
                    }
                    makerNote.close();
                }
            }
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) PhotoInterp(loci.formats.tiff.PhotoInterp) TiffRational(loci.formats.tiff.TiffRational) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) IOException(java.io.IOException) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 3 with TiffRational

use of loci.formats.tiff.TiffRational in project bioformats by openmicroscopy.

the class TiffRationalTest method testEqualTiffRational.

@Test
public void testEqualTiffRational() {
    TiffRational a = new TiffRational(1, 4);
    TiffRational b = new TiffRational(1, 4);
    assertTrue(a.equals(b));
    assertTrue(a.equals((Object) b));
    assertEquals(0, a.compareTo(b));
}
Also used : TiffRational(loci.formats.tiff.TiffRational) Test(org.testng.annotations.Test)

Example 4 with TiffRational

use of loci.formats.tiff.TiffRational in project bioformats by openmicroscopy.

the class TiffWriter method prepareToWriteImage.

/**
 * Performs the preparation for work prior to the usage of the TIFF saver.
 * This method is factored out from <code>saveBytes()</code> in an attempt to
 * ensure thread safety.
 */
protected int prepareToWriteImage(int no, byte[] buf, IFD ifd, int x, int y, int w, int h) throws IOException, FormatException {
    MetadataRetrieve retrieve = getMetadataRetrieve();
    boolean littleEndian = false;
    if (retrieve.getPixelsBigEndian(series) != null) {
        littleEndian = !retrieve.getPixelsBigEndian(series).booleanValue();
    } else if (retrieve.getPixelsBinDataCount(series) == 0) {
        littleEndian = !retrieve.getPixelsBinDataBigEndian(series, 0).booleanValue();
    }
    // at one time.
    synchronized (this) {
        if (!initialized[series][no]) {
            initialized[series][no] = true;
            RandomAccessInputStream tmp = createInputStream();
            if (tmp.length() == 0) {
                synchronized (this) {
                    // write TIFF header
                    tiffSaver.writeHeader();
                }
            }
            tmp.close();
        }
    }
    int c = getSamplesPerPixel();
    int type = FormatTools.pixelTypeFromString(retrieve.getPixelsType(series).toString());
    int bytesPerPixel = FormatTools.getBytesPerPixel(type);
    int blockSize = w * h * c * bytesPerPixel;
    if (blockSize > buf.length) {
        c = buf.length / (w * h * bytesPerPixel);
    }
    formatCompression(ifd);
    byte[][] lut = AWTImageTools.get8BitLookupTable(cm);
    if (lut != null) {
        int[] colorMap = new int[lut.length * lut[0].length];
        for (int i = 0; i < lut.length; i++) {
            for (int j = 0; j < lut[0].length; j++) {
                colorMap[i * lut[0].length + j] = (int) ((lut[i][j] & 0xff) << 8);
            }
        }
        ifd.putIFDValue(IFD.COLOR_MAP, colorMap);
    } else {
        short[][] lut16 = AWTImageTools.getLookupTable(cm);
        if (lut16 != null) {
            int[] colorMap = new int[lut16.length * lut16[0].length];
            for (int i = 0; i < lut16.length; i++) {
                for (int j = 0; j < lut16[0].length; j++) {
                    colorMap[i * lut16[0].length + j] = (int) (lut16[i][j] & 0xffff);
                }
            }
            ifd.putIFDValue(IFD.COLOR_MAP, colorMap);
        }
    }
    int width = retrieve.getPixelsSizeX(series).getValue().intValue();
    int height = retrieve.getPixelsSizeY(series).getValue().intValue();
    ifd.put(new Integer(IFD.IMAGE_WIDTH), new Long(width));
    ifd.put(new Integer(IFD.IMAGE_LENGTH), new Long(height));
    Length px = retrieve.getPixelsPhysicalSizeX(series);
    Double physicalSizeX = px == null || px.value(UNITS.MICROMETER) == null ? null : px.value(UNITS.MICROMETER).doubleValue();
    if (physicalSizeX == null || physicalSizeX.doubleValue() == 0) {
        physicalSizeX = 0d;
    } else
        physicalSizeX = 1d / physicalSizeX;
    Length py = retrieve.getPixelsPhysicalSizeY(series);
    Double physicalSizeY = py == null || py.value(UNITS.MICROMETER) == null ? null : py.value(UNITS.MICROMETER).doubleValue();
    if (physicalSizeY == null || physicalSizeY.doubleValue() == 0) {
        physicalSizeY = 0d;
    } else
        physicalSizeY = 1d / physicalSizeY;
    ifd.put(IFD.RESOLUTION_UNIT, 3);
    ifd.put(IFD.X_RESOLUTION, new TiffRational((long) (physicalSizeX * 1000 * 10000), 1000));
    ifd.put(IFD.Y_RESOLUTION, new TiffRational((long) (physicalSizeY * 1000 * 10000), 1000));
    if (!isBigTiff) {
        isBigTiff = (out.length() + 2 * (width * height * c * bytesPerPixel)) >= 4294967296L;
        if (isBigTiff) {
            throw new FormatException("File is too large; call setBigTiff(true)");
        }
    }
    // write the image
    ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(littleEndian));
    if (!ifd.containsKey(IFD.REUSE)) {
        ifd.put(IFD.REUSE, out.length());
        out.seek(out.length());
    } else {
        out.seek((Long) ifd.get(IFD.REUSE));
    }
    ifd.putIFDValue(IFD.PLANAR_CONFIGURATION, interleaved || getSamplesPerPixel() == 1 ? 1 : 2);
    int sampleFormat = 1;
    if (FormatTools.isSigned(type))
        sampleFormat = 2;
    if (FormatTools.isFloatingPoint(type))
        sampleFormat = 3;
    ifd.putIFDValue(IFD.SAMPLE_FORMAT, sampleFormat);
    int channels = retrieve.getPixelsSizeC(series).getValue().intValue();
    int z = retrieve.getPixelsSizeZ(series).getValue().intValue();
    int t = retrieve.getPixelsSizeT(series).getValue().intValue();
    ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, "ImageJ=\nhyperstack=true\nimages=" + (channels * z * t) + "\nchannels=" + channels + "\nslices=" + z + "\nframes=" + t);
    int index = no;
    for (int i = 0; i < getSeries(); i++) {
        index += getPlaneCount(i);
    }
    return index;
}
Also used : TiffRational(loci.formats.tiff.TiffRational) FormatException(loci.formats.FormatException) Length(ome.units.quantity.Length) RandomAccessInputStream(loci.common.RandomAccessInputStream) MetadataRetrieve(loci.formats.meta.MetadataRetrieve)

Example 5 with TiffRational

use of loci.formats.tiff.TiffRational in project bioformats by openmicroscopy.

the class BaseTiffReader method initStandardMetadata.

/**
 * Parses standard metadata.
 *
 * NOTE: Absolutely <b>no</b> calls to the metadata store should be made in
 * this method or methods that override this method. Data <b>will</b> be
 * overwritten if you do so.
 */
protected void initStandardMetadata() throws FormatException, IOException {
    if (getMetadataOptions().getMetadataLevel() == MetadataLevel.MINIMUM) {
        return;
    }
    for (int i = 0; i < ifds.size(); i++) {
        put("PageName #" + i, ifds.get(i), IFD.PAGE_NAME);
    }
    IFD firstIFD = ifds.get(0);
    put("ImageWidth", firstIFD, IFD.IMAGE_WIDTH);
    put("ImageLength", firstIFD, IFD.IMAGE_LENGTH);
    put("BitsPerSample", firstIFD, IFD.BITS_PER_SAMPLE);
    if (ifds.get(0).containsKey(IFD.EXIF)) {
        IFDList exifIFDs = tiffParser.getExifIFDs();
        if (exifIFDs.size() > 0) {
            IFD exif = exifIFDs.get(0);
            tiffParser.fillInIFD(exif);
            for (Integer key : exif.keySet()) {
                int k = key.intValue();
                addGlobalMeta(getExifTagName(k), exif.get(key));
            }
        }
    }
    TiffCompression comp = firstIFD.getCompression();
    put("Compression", comp.getCodecName());
    PhotoInterp photo = firstIFD.getPhotometricInterpretation();
    String photoInterp = photo.getName();
    String metaDataPhotoInterp = photo.getMetadataType();
    put("PhotometricInterpretation", photoInterp);
    put("MetaDataPhotometricInterpretation", metaDataPhotoInterp);
    putInt("CellWidth", firstIFD, IFD.CELL_WIDTH);
    putInt("CellLength", firstIFD, IFD.CELL_LENGTH);
    int or = firstIFD.getIFDIntValue(IFD.ORIENTATION);
    // adjust the width and height if necessary
    if (or == 8) {
        put("ImageWidth", firstIFD, IFD.IMAGE_LENGTH);
        put("ImageLength", firstIFD, IFD.IMAGE_WIDTH);
    }
    String orientation = null;
    // there is no case 0
    switch(or) {
        case 1:
            orientation = "1st row -> top; 1st column -> left";
            break;
        case 2:
            orientation = "1st row -> top; 1st column -> right";
            break;
        case 3:
            orientation = "1st row -> bottom; 1st column -> right";
            break;
        case 4:
            orientation = "1st row -> bottom; 1st column -> left";
            break;
        case 5:
            orientation = "1st row -> left; 1st column -> top";
            break;
        case 6:
            orientation = "1st row -> right; 1st column -> top";
            break;
        case 7:
            orientation = "1st row -> right; 1st column -> bottom";
            break;
        case 8:
            orientation = "1st row -> left; 1st column -> bottom";
            break;
    }
    put("Orientation", orientation);
    putInt("SamplesPerPixel", firstIFD, IFD.SAMPLES_PER_PIXEL);
    put("Software", firstIFD, IFD.SOFTWARE);
    put("Instrument Make", firstIFD, IFD.MAKE);
    put("Instrument Model", firstIFD, IFD.MODEL);
    put("Document Name", firstIFD, IFD.DOCUMENT_NAME);
    put("DateTime", getImageCreationDate());
    put("Artist", firstIFD, IFD.ARTIST);
    put("HostComputer", firstIFD, IFD.HOST_COMPUTER);
    put("Copyright", firstIFD, IFD.COPYRIGHT);
    put("NewSubfileType", firstIFD, IFD.NEW_SUBFILE_TYPE);
    int thresh = firstIFD.getIFDIntValue(IFD.THRESHHOLDING);
    String threshholding = null;
    switch(thresh) {
        case 1:
            threshholding = "No dithering or halftoning";
            break;
        case 2:
            threshholding = "Ordered dithering or halftoning";
            break;
        case 3:
            threshholding = "Randomized error diffusion";
            break;
    }
    put("Threshholding", threshholding);
    int fill = firstIFD.getIFDIntValue(IFD.FILL_ORDER);
    String fillOrder = null;
    switch(fill) {
        case 1:
            fillOrder = "Pixels with lower column values are stored " + "in the higher order bits of a byte";
            break;
        case 2:
            fillOrder = "Pixels with lower column values are stored " + "in the lower order bits of a byte";
            break;
    }
    put("FillOrder", fillOrder);
    putInt("Make", firstIFD, IFD.MAKE);
    putInt("Model", firstIFD, IFD.MODEL);
    putInt("MinSampleValue", firstIFD, IFD.MIN_SAMPLE_VALUE);
    putInt("MaxSampleValue", firstIFD, IFD.MAX_SAMPLE_VALUE);
    TiffRational xResolution = firstIFD.getIFDRationalValue(IFD.X_RESOLUTION);
    TiffRational yResolution = firstIFD.getIFDRationalValue(IFD.Y_RESOLUTION);
    if (xResolution != null) {
        put("XResolution", xResolution.doubleValue());
    }
    if (yResolution != null) {
        put("YResolution", yResolution.doubleValue());
    }
    int planar = firstIFD.getIFDIntValue(IFD.PLANAR_CONFIGURATION);
    String planarConfig = null;
    switch(planar) {
        case 1:
            planarConfig = "Chunky";
            break;
        case 2:
            planarConfig = "Planar";
            break;
    }
    put("PlanarConfiguration", planarConfig);
    putInt("XPosition", firstIFD, IFD.X_POSITION);
    putInt("YPosition", firstIFD, IFD.Y_POSITION);
    putInt("FreeOffsets", firstIFD, IFD.FREE_OFFSETS);
    putInt("FreeByteCounts", firstIFD, IFD.FREE_BYTE_COUNTS);
    putInt("GrayResponseUnit", firstIFD, IFD.GRAY_RESPONSE_UNIT);
    putInt("GrayResponseCurve", firstIFD, IFD.GRAY_RESPONSE_CURVE);
    putInt("T4Options", firstIFD, IFD.T4_OPTIONS);
    putInt("T6Options", firstIFD, IFD.T6_OPTIONS);
    int res = firstIFD.getIFDIntValue(IFD.RESOLUTION_UNIT);
    String resUnit = null;
    switch(res) {
        case 1:
            resUnit = "None";
            break;
        case 2:
            resUnit = "Inch";
            break;
        case 3:
            resUnit = "Centimeter";
            break;
    }
    put("ResolutionUnit", resUnit);
    putString("PageNumber", firstIFD, IFD.PAGE_NUMBER);
    putInt("TransferFunction", firstIFD, IFD.TRANSFER_FUNCTION);
    int predict = firstIFD.getIFDIntValue(IFD.PREDICTOR);
    String predictor = null;
    switch(predict) {
        case 1:
            predictor = "No prediction scheme";
            break;
        case 2:
            predictor = "Horizontal differencing";
            break;
    }
    put("Predictor", predictor);
    putInt("WhitePoint", firstIFD, IFD.WHITE_POINT);
    putInt("PrimaryChromacities", firstIFD, IFD.PRIMARY_CHROMATICITIES);
    putInt("HalftoneHints", firstIFD, IFD.HALFTONE_HINTS);
    putInt("TileWidth", firstIFD, IFD.TILE_WIDTH);
    putInt("TileLength", firstIFD, IFD.TILE_LENGTH);
    putInt("TileOffsets", firstIFD, IFD.TILE_OFFSETS);
    putInt("TileByteCounts", firstIFD, IFD.TILE_BYTE_COUNTS);
    int ink = firstIFD.getIFDIntValue(IFD.INK_SET);
    String inkSet = null;
    switch(ink) {
        case 1:
            inkSet = "CMYK";
            break;
        case 2:
            inkSet = "Other";
            break;
    }
    put("InkSet", inkSet);
    putInt("InkNames", firstIFD, IFD.INK_NAMES);
    putInt("NumberOfInks", firstIFD, IFD.NUMBER_OF_INKS);
    putInt("DotRange", firstIFD, IFD.DOT_RANGE);
    put("TargetPrinter", firstIFD, IFD.TARGET_PRINTER);
    putInt("ExtraSamples", firstIFD, IFD.EXTRA_SAMPLES);
    int fmt = firstIFD.getIFDIntValue(IFD.SAMPLE_FORMAT);
    String sampleFormat = null;
    switch(fmt) {
        case 1:
            sampleFormat = "unsigned integer";
            break;
        case 2:
            sampleFormat = "two's complement signed integer";
            break;
        case 3:
            sampleFormat = "IEEE floating point";
            break;
        case 4:
            sampleFormat = "undefined";
            break;
    }
    put("SampleFormat", sampleFormat);
    putInt("SMinSampleValue", firstIFD, IFD.S_MIN_SAMPLE_VALUE);
    putInt("SMaxSampleValue", firstIFD, IFD.S_MAX_SAMPLE_VALUE);
    putInt("TransferRange", firstIFD, IFD.TRANSFER_RANGE);
    int jpeg = firstIFD.getIFDIntValue(IFD.JPEG_PROC);
    String jpegProc = null;
    switch(jpeg) {
        case 1:
            jpegProc = "baseline sequential process";
            break;
        case 14:
            jpegProc = "lossless process with Huffman coding";
            break;
    }
    put("JPEGProc", jpegProc);
    putInt("JPEGInterchangeFormat", firstIFD, IFD.JPEG_INTERCHANGE_FORMAT);
    putInt("JPEGRestartInterval", firstIFD, IFD.JPEG_RESTART_INTERVAL);
    putInt("JPEGLosslessPredictors", firstIFD, IFD.JPEG_LOSSLESS_PREDICTORS);
    putInt("JPEGPointTransforms", firstIFD, IFD.JPEG_POINT_TRANSFORMS);
    putInt("JPEGQTables", firstIFD, IFD.JPEG_Q_TABLES);
    putInt("JPEGDCTables", firstIFD, IFD.JPEG_DC_TABLES);
    putInt("JPEGACTables", firstIFD, IFD.JPEG_AC_TABLES);
    putInt("YCbCrCoefficients", firstIFD, IFD.Y_CB_CR_COEFFICIENTS);
    int ycbcr = firstIFD.getIFDIntValue(IFD.Y_CB_CR_SUB_SAMPLING);
    String subSampling = null;
    switch(ycbcr) {
        case 1:
            subSampling = "chroma image dimensions = luma image dimensions";
            break;
        case 2:
            subSampling = "chroma image dimensions are " + "half the luma image dimensions";
            break;
        case 4:
            subSampling = "chroma image dimensions are " + "1/4 the luma image dimensions";
            break;
    }
    put("YCbCrSubSampling", subSampling);
    putInt("YCbCrPositioning", firstIFD, IFD.Y_CB_CR_POSITIONING);
    putInt("ReferenceBlackWhite", firstIFD, IFD.REFERENCE_BLACK_WHITE);
    // bits per sample and number of channels
    int[] q = firstIFD.getBitsPerSample();
    int bps = q[0];
    int numC = q.length;
    if (photo == PhotoInterp.RGB_PALETTE || photo == PhotoInterp.CFA_ARRAY) {
        numC = 3;
    }
    put("BitsPerSample", bps);
    put("NumberOfChannels", numC);
}
Also used : IFD(loci.formats.tiff.IFD) TiffCompression(loci.formats.tiff.TiffCompression) IFDList(loci.formats.tiff.IFDList) PhotoInterp(loci.formats.tiff.PhotoInterp) TiffRational(loci.formats.tiff.TiffRational)

Aggregations

TiffRational (loci.formats.tiff.TiffRational)12 IFD (loci.formats.tiff.IFD)6 IFDList (loci.formats.tiff.IFDList)5 Test (org.testng.annotations.Test)5 IOException (java.io.IOException)3 FormatException (loci.formats.FormatException)3 PhotoInterp (loci.formats.tiff.PhotoInterp)3 Length (ome.units.quantity.Length)3 RandomAccessInputStream (loci.common.RandomAccessInputStream)2 CoreMetadata (loci.formats.CoreMetadata)2 MetadataStore (loci.formats.meta.MetadataStore)2 Timestamp (ome.xml.model.primitives.Timestamp)2 ArrayList (java.util.ArrayList)1 MetadataRetrieve (loci.formats.meta.MetadataRetrieve)1 TiffCompression (loci.formats.tiff.TiffCompression)1 TiffIFDEntry (loci.formats.tiff.TiffIFDEntry)1 TiffParser (loci.formats.tiff.TiffParser)1 Time (ome.units.quantity.Time)1