in src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java [743:897]
TiffRasterData getRasterData(
final TiffDirectory directory,
final ByteOrder byteOrder,
TiffImagingParameters params)
throws ImagingException, IOException {
if (params == null) {
params = this.getDefaultParameters();
}
final short[] sSampleFmt = directory.getFieldValue(
TiffTagConstants.TIFF_TAG_SAMPLE_FORMAT, true);
if (sSampleFmt == null || sSampleFmt.length < 1) {
throw new ImagingException(
"Directory does not specify numeric raster data");
}
int samplesPerPixel = 1;
final TiffField samplesPerPixelField = directory.findField(
TiffTagConstants.TIFF_TAG_SAMPLES_PER_PIXEL);
if (samplesPerPixelField != null) {
samplesPerPixel = samplesPerPixelField.getIntValue();
}
int[] bitsPerSample = {1};
int bitsPerPixel = samplesPerPixel;
final TiffField bitsPerSampleField = directory.findField(
TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE);
if (bitsPerSampleField != null) {
bitsPerSample = bitsPerSampleField.getIntArrayValue();
bitsPerPixel = bitsPerSampleField.getIntValueOrArraySum();
}
final short compressionFieldValue;
if (directory.findField(TiffTagConstants.TIFF_TAG_COMPRESSION) != null) {
compressionFieldValue
= directory.getFieldValue(TiffTagConstants.TIFF_TAG_COMPRESSION);
} else {
compressionFieldValue = TIFF_COMPRESSION_UNCOMPRESSED_1;
}
final int compression = 0xffff & compressionFieldValue;
final int width
= directory.getSingleFieldValue(TiffTagConstants.TIFF_TAG_IMAGE_WIDTH);
final int height
= directory.getSingleFieldValue(TiffTagConstants.TIFF_TAG_IMAGE_LENGTH);
Rectangle subImage = checkForSubImage(params);
if (subImage != null) {
// Check for valid subimage specification. The following checks
// are consistent with BufferedImage.getSubimage()
if (subImage.width <= 0) {
throw new ImagingException("Negative or zero subimage width.");
}
if (subImage.height <= 0) {
throw new ImagingException("Negative or zero subimage height.");
}
if (subImage.x < 0 || subImage.x >= width) {
throw new ImagingException("Subimage x is outside raster.");
}
if (subImage.x + subImage.width > width) {
throw new ImagingException("Subimage (x+width) is outside raster.");
}
if (subImage.y < 0 || subImage.y >= height) {
throw new ImagingException("Subimage y is outside raster.");
}
if (subImage.y + subImage.height > height) {
throw new ImagingException("Subimage (y+height) is outside raster.");
}
// if the subimage is just the same thing as the whole
// image, suppress the subimage processing
if (subImage.x == 0
&& subImage.y == 0
&& subImage.width == width
&& subImage.height == height) {
subImage = null;
}
}
// int bitsPerPixel = getTagAsValueOrArraySum(entries,
// TIFF_TAG_BITS_PER_SAMPLE);
int predictor = -1;
{
// dumpOptionalNumberTag(entries, TIFF_TAG_FILL_ORDER);
// dumpOptionalNumberTag(entries, TIFF_TAG_FREE_BYTE_COUNTS);
// dumpOptionalNumberTag(entries, TIFF_TAG_FREE_OFFSETS);
// dumpOptionalNumberTag(entries, TIFF_TAG_ORIENTATION);
// dumpOptionalNumberTag(entries, TIFF_TAG_PLANAR_CONFIGURATION);
final TiffField predictorField = directory.findField(
TiffTagConstants.TIFF_TAG_PREDICTOR);
if (null != predictorField) {
predictor = predictorField.getIntValueOrArraySum();
}
}
// Obtain the planar configuration
final TiffField pcField = directory.findField(
TiffTagConstants.TIFF_TAG_PLANAR_CONFIGURATION);
final TiffPlanarConfiguration planarConfiguration
= pcField == null
? TiffPlanarConfiguration.CHUNKY
: TiffPlanarConfiguration.lenientValueOf(pcField.getIntValue());
if (sSampleFmt[0] == TiffTagConstants.SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT) {
if (bitsPerSample[0] != 32 && bitsPerSample[0] != 64) {
throw new ImagingException(
"TIFF floating-point data uses unsupported bits-per-sample: "
+ bitsPerSample[0]);
}
if (predictor != -1
&& predictor != TiffTagConstants.PREDICTOR_VALUE_NONE
&& predictor != TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) {
throw new ImagingException(
"TIFF floating-point data uses unsupported horizontal-differencing predictor");
}
} else if (sSampleFmt[0] == TiffTagConstants.SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER) {
if (samplesPerPixel != 1) {
throw new ImagingException(
"TIFF integer data uses unsupported samples per pixel: "
+ samplesPerPixel);
}
if (bitsPerPixel != 16 && bitsPerPixel != 32) {
throw new ImagingException(
"TIFF integer data uses unsupported bits-per-pixel: "
+ bitsPerPixel);
}
if (predictor != -1
&& predictor != TiffTagConstants.PREDICTOR_VALUE_NONE
&& predictor != TiffTagConstants.PREDICTOR_VALUE_HORIZONTAL_DIFFERENCING) {
throw new ImagingException(
"TIFF integer data uses unsupported horizontal-differencing predictor");
}
} else {
throw new ImagingException("TIFF does not provide a supported raster-data format");
}
// The photometric interpreter is not used, but the image-based
// data reader classes require one. So we create a dummy interpreter.
final PhotometricInterpreter photometricInterpreter
= new PhotometricInterpreterBiLevel(samplesPerPixel,
bitsPerSample, predictor, width, height, false);
final TiffImageData imageData = directory.getTiffImageData();
final ImageDataReader dataReader = imageData.getDataReader(directory,
photometricInterpreter, bitsPerPixel, bitsPerSample, predictor,
samplesPerPixel, width, height, compression,
planarConfiguration, byteOrder);
return dataReader.readRasterData(subImage);
}