protected void put(String key, short value) { put(key, new Short(value)); }
protected void putInt(String key, IFD ifd, int tag) { put(key, ifd.getIFDIntValue(tag)); }
protected void put(String key, float value) { put(key, new Float(value)); }
protected void put(String key, long value) { put(key, new Long(value)); }
protected void put(String key, double value) { put(key, new Double(value)); }
protected void put(String key, char value) { put(key, new Character(value)); }
protected void put(String key, byte value) { put(key, new Byte(value)); }
protected void put(String key, boolean value) { put(key, new Boolean(value)); }
/** * 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); }