in src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java [398:579]
public ImageInfo getImageInfo(final ByteSource byteSource, final TiffImagingParameters params) throws ImagingException, IOException {
final FormatCompliance formatCompliance = FormatCompliance.getDefault();
final TiffContents contents = new TiffReader(params != null && params.isStrict()).readDirectories(byteSource, false, formatCompliance);
final TiffDirectory directory = contents.directories.get(0);
final TiffField widthField = directory.findField(TiffTagConstants.TIFF_TAG_IMAGE_WIDTH, true);
final TiffField heightField = directory.findField(TiffTagConstants.TIFF_TAG_IMAGE_LENGTH, true);
if (widthField == null || heightField == null) {
throw new ImagingException("TIFF image missing size info.");
}
final int height = heightField.getIntValue();
final int width = widthField.getIntValue();
final TiffField resolutionUnitField = directory.findField(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT);
int resolutionUnit = 2; // Inch
if (resolutionUnitField != null && resolutionUnitField.getValue() != null) {
resolutionUnit = resolutionUnitField.getIntValue();
}
double unitsPerInch = -1;
switch (resolutionUnit) {
case 1:
break;
case 2: // Inch
unitsPerInch = 1.0;
break;
case 3: // Centimeter
unitsPerInch = 2.54;
break;
default:
break;
}
int physicalWidthDpi = -1;
float physicalWidthInch = -1;
int physicalHeightDpi = -1;
float physicalHeightInch = -1;
if (unitsPerInch > 0) {
final TiffField xResolutionField = directory.findField(TiffTagConstants.TIFF_TAG_XRESOLUTION);
final TiffField yResolutionField = directory.findField(TiffTagConstants.TIFF_TAG_YRESOLUTION);
if (xResolutionField != null && xResolutionField.getValue() != null) {
final double xResolutionPixelsPerUnit = xResolutionField.getDoubleValue();
physicalWidthDpi = (int) Math.round(xResolutionPixelsPerUnit * unitsPerInch);
physicalWidthInch = (float) (width / (xResolutionPixelsPerUnit * unitsPerInch));
}
if (yResolutionField != null && yResolutionField.getValue() != null) {
final double yResolutionPixelsPerUnit = yResolutionField.getDoubleValue();
physicalHeightDpi = (int) Math.round(yResolutionPixelsPerUnit * unitsPerInch);
physicalHeightInch = (float) (height / (yResolutionPixelsPerUnit * unitsPerInch));
}
}
final TiffField bitsPerSampleField = directory.findField(TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE);
int bitsPerSample = 1;
if (bitsPerSampleField != null && bitsPerSampleField.getValue() != null) {
bitsPerSample = bitsPerSampleField.getIntValueOrArraySum();
}
final int bitsPerPixel = bitsPerSample; // assume grayscale;
// dunno if this handles colormapped images correctly.
final List<String> comments = Allocator.arrayList(directory.size());
for (final TiffField field : directory) {
comments.add(field.toString());
}
final ImageFormat format = ImageFormats.TIFF;
final String formatName = "TIFF Tag-based Image File Format";
final String mimeType = "image/tiff";
final int numberOfImages = contents.directories.size();
// not accurate ... only reflects first
final boolean progressive = false;
// is TIFF ever interlaced/progressive?
final String formatDetails = "TIFF v." + contents.header.tiffVersion;
boolean transparent = false; // TODO: wrong
boolean usesPalette = false;
final TiffField colorMapField = directory.findField(TiffTagConstants.TIFF_TAG_COLOR_MAP);
if (colorMapField != null) {
usesPalette = true;
}
final int photoInterp = 0xffff & directory.getFieldValue(TiffTagConstants.TIFF_TAG_PHOTOMETRIC_INTERPRETATION);
final TiffField extraSamplesField = directory.findField(TiffTagConstants.TIFF_TAG_EXTRA_SAMPLES);
final int extraSamples;
if (extraSamplesField == null) {
extraSamples = 0; // no extra samples value
} else {
extraSamples = extraSamplesField.getIntValue();
}
final TiffField samplesPerPixelField = directory.findField(TiffTagConstants.TIFF_TAG_SAMPLES_PER_PIXEL);
final int samplesPerPixel;
if (samplesPerPixelField == null) {
samplesPerPixel = 1;
} else {
samplesPerPixel = samplesPerPixelField.getIntValue();
}
final ImageInfo.ColorType colorType;
switch (photoInterp) {
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_BLACK_IS_ZERO:
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_WHITE_IS_ZERO:
// the ImageInfo.ColorType enumeration does not distinguish
// between monotone white is zero or black is zero
colorType = ImageInfo.ColorType.BW;
break;
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_RGB:
colorType = ImageInfo.ColorType.RGB;
// even if 4 samples per pixel are included, TIFF
// doesn't specify transparent unless the optional "extra samples"
// field is supplied with a non-zero value
transparent = samplesPerPixel == 4 && extraSamples != 0;
break;
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_RGB_PALETTE:
colorType = ImageInfo.ColorType.RGB;
usesPalette = true;
break;
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_CMYK:
colorType = ImageInfo.ColorType.CMYK;
break;
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_YCB_CR:
colorType = ImageInfo.ColorType.YCbCr;
break;
default:
colorType = ImageInfo.ColorType.UNKNOWN;
}
final short compressionFieldValue;
if (directory.findField(TiffTagConstants.TIFF_TAG_COMPRESSION) != null) {
compressionFieldValue = directory.getFieldValue(TiffTagConstants.TIFF_TAG_COMPRESSION);
} else {
compressionFieldValue = TiffConstants.COMPRESSION_UNCOMPRESSED_1;
}
final int compression = 0xffff & compressionFieldValue;
final ImageInfo.CompressionAlgorithm compressionAlgorithm;
switch (compression) {
case TiffConstants.COMPRESSION_UNCOMPRESSED_1:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.NONE;
break;
case TiffConstants.COMPRESSION_CCITT_1D:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.CCITT_1D;
break;
case TiffConstants.COMPRESSION_CCITT_GROUP_3:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.CCITT_GROUP_3;
break;
case TiffConstants.COMPRESSION_CCITT_GROUP_4:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.CCITT_GROUP_4;
break;
case TiffConstants.COMPRESSION_LZW:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.LZW;
break;
case TiffConstants.COMPRESSION_JPEG_OBSOLETE:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.JPEG_TIFF_OBSOLETE;
break;
case TiffConstants.COMPRESSION_JPEG:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.JPEG;
break;
case TiffConstants.COMPRESSION_UNCOMPRESSED_2:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.NONE;
break;
case TiffConstants.COMPRESSION_PACKBITS:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.PACKBITS;
break;
case TiffConstants.COMPRESSION_DEFLATE_PKZIP:
case TiffConstants.COMPRESSION_DEFLATE_ADOBE:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.DEFLATE;
break;
default:
compressionAlgorithm = ImageInfo.CompressionAlgorithm.UNKNOWN;
break;
}
return new ImageInfo(formatDetails, bitsPerPixel, comments, format, formatName, height, mimeType, numberOfImages, physicalHeightDpi, physicalHeightInch,
physicalWidthDpi, physicalWidthInch, width, progressive, transparent, usesPalette, colorType, compressionAlgorithm);
}