/** * Parses standard metadata. * * <p>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); // retrieve EXIF values, if available 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", firstIFD, IFD.DATE_TIME); 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); putInt("XResolution", firstIFD, IFD.X_RESOLUTION); putInt("YResolution", firstIFD, IFD.Y_RESOLUTION); 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); putInt("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; // numC isn't set properly if we have an indexed color image, so we need // to reset it here if (photo == PhotoInterp.RGB_PALETTE || photo == PhotoInterp.CFA_ARRAY) { numC = 3; } put("BitsPerSample", bps); put("NumberOfChannels", numC); }
protected void putInt(String key, IFD ifd, int tag) { put(key, ifd.getIFDIntValue(tag)); }
/* @see loci.formats.FormatReader#initFile(String) */ protected void initFile(String id) throws FormatException, IOException { super.initFile(id); if (!checkSuffix(id, "vsi")) { Location current = new Location(id).getAbsoluteFile(); Location parent = current.getParentFile(); parent = parent.getParentFile(); Location grandparent = parent.getParentFile(); String vsi = parent.getName(); vsi = vsi.substring(1, vsi.length() - 1) + ".vsi"; Location vsiFile = new Location(grandparent, vsi); if (!vsiFile.exists()) { throw new FormatException("Could not find .vsi file."); } else { id = vsiFile.getAbsolutePath(); } } parser = new TiffParser(id); ifds = parser.getIFDs(); RandomAccessInputStream vsi = new RandomAccessInputStream(id); vsi.order(parser.getStream().isLittleEndian()); vsi.seek(8); readTags(vsi); vsi.seek(parser.getStream().getFilePointer()); vsi.skipBytes(273); ArrayList<String> files = new ArrayList<String>(); Location file = new Location(id).getAbsoluteFile(); Location dir = file.getParentFile(); String name = file.getName(); name = name.substring(0, name.lastIndexOf(".")); Location pixelsDir = new Location(dir, "_" + name + "_"); String[] stackDirs = pixelsDir.list(true); if (stackDirs != null) { for (String f : stackDirs) { Location stackDir = new Location(pixelsDir, f); String[] pixelsFiles = stackDir.list(true); if (pixelsFiles != null) { for (String pixelsFile : pixelsFiles) { if (checkSuffix(pixelsFile, "ets")) { files.add(new Location(stackDir, pixelsFile).getAbsolutePath()); } } } } } files.add(file.getAbsolutePath()); usedFiles = files.toArray(new String[files.size()]); core = new CoreMetadata[files.size() - 1 + ifds.size()]; tileOffsets = new Long[files.size() - 1][]; rows = new int[files.size() - 1]; cols = new int[files.size() - 1]; nDimensions = new int[core.length]; IFDList exifs = parser.getExifIFDs(); compressionType = new int[core.length]; tileX = new int[core.length]; tileY = new int[core.length]; tileMap = new HashMap[core.length]; for (int s = 0; s < core.length; s++) { core[s] = new CoreMetadata(); } for (int s = 0; s < core.length; s++) { tileMap[s] = new HashMap<TileCoordinate, Integer>(); if (s == 0 && !hasFlattenedResolutions()) { core[s].resolutionCount = ifds.size() + (files.size() == 1 ? 0 : 1); } if (s < files.size() - 1) { setSeries(s); parseETSFile(files.get(s), s); core[s].littleEndian = compressionType[s] == RAW; core[s].interleaved = core[s].rgb; if (s == 0 && exifs.size() > 0) { IFD exif = exifs.get(0); int newX = exif.getIFDIntValue(IFD.PIXEL_X_DIMENSION); int newY = exif.getIFDIntValue(IFD.PIXEL_Y_DIMENSION); if (getSizeX() > newX || getSizeY() > newY) { core[s].sizeX = newX; core[s].sizeY = newY; } } setSeries(0); } else { IFD ifd = ifds.get(s - files.size() + 1); PhotoInterp p = ifd.getPhotometricInterpretation(); int samples = ifd.getSamplesPerPixel(); core[s].rgb = samples > 1 || p == PhotoInterp.RGB; core[s].sizeX = (int) ifd.getImageWidth(); core[s].sizeY = (int) ifd.getImageLength(); core[s].sizeZ = 1; core[s].sizeT = 1; core[s].sizeC = core[s].rgb ? samples : 1; core[s].littleEndian = ifd.isLittleEndian(); core[s].indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null); core[s].imageCount = 1; core[s].pixelType = ifd.getPixelType(); core[s].interleaved = false; core[s].falseColor = false; core[s].thumbnail = s != 0; } core[s].metadataComplete = true; core[s].dimensionOrder = "XYCZT"; } vsi.close(); MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); }