mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 12:05:29 -04:00
#184 Support for PlanarConfiguration 2 + bonus changes.
This commit is contained in:
parent
867ca61755
commit
b6e44c5bff
@ -193,6 +193,8 @@ final class EXIFEntry extends AbstractEntry {
|
|||||||
return "Flash";
|
return "Flash";
|
||||||
case EXIF.TAG_FOCAL_LENGTH:
|
case EXIF.TAG_FOCAL_LENGTH:
|
||||||
return "FocalLength";
|
return "FocalLength";
|
||||||
|
case EXIF.TAG_SENSING_METHOD:
|
||||||
|
return "SensingMethod";
|
||||||
case EXIF.TAG_FILE_SOURCE:
|
case EXIF.TAG_FILE_SOURCE:
|
||||||
return "FileSource";
|
return "FileSource";
|
||||||
case EXIF.TAG_SCENE_TYPE:
|
case EXIF.TAG_SCENE_TYPE:
|
||||||
@ -219,6 +221,8 @@ final class EXIFEntry extends AbstractEntry {
|
|||||||
return "Saturation";
|
return "Saturation";
|
||||||
case EXIF.TAG_SHARPNESS:
|
case EXIF.TAG_SHARPNESS:
|
||||||
return "Sharpness";
|
return "Sharpness";
|
||||||
|
case EXIF.TAG_IMAGE_UNIQUE_ID:
|
||||||
|
return "ImageUniqueID";
|
||||||
|
|
||||||
case EXIF.TAG_FLASHPIX_VERSION:
|
case EXIF.TAG_FLASHPIX_VERSION:
|
||||||
return "FlashpixVersion";
|
return "FlashpixVersion";
|
||||||
|
@ -115,7 +115,6 @@ import java.util.zip.InflaterInputStream;
|
|||||||
public class TIFFImageReader extends ImageReaderBase {
|
public class TIFFImageReader extends ImageReaderBase {
|
||||||
// TODOs ImageIO basic functionality:
|
// TODOs ImageIO basic functionality:
|
||||||
// TODO: Thumbnail support
|
// TODO: Thumbnail support
|
||||||
// TODO: TIFFImageWriter + Spi
|
|
||||||
|
|
||||||
// TODOs Full BaseLine support:
|
// TODOs Full BaseLine support:
|
||||||
// TODO: Support ExtraSamples (an array, if multiple extra samples!)
|
// TODO: Support ExtraSamples (an array, if multiple extra samples!)
|
||||||
@ -129,10 +128,7 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
// http://download.java.net/media/jai-imageio/javadoc/1.1/com/sun/media/imageio/plugins/tiff/package-summary.html#ImageMetadata
|
// http://download.java.net/media/jai-imageio/javadoc/1.1/com/sun/media/imageio/plugins/tiff/package-summary.html#ImageMetadata
|
||||||
|
|
||||||
// TODOs Extension support
|
// TODOs Extension support
|
||||||
// TODO: Support PlanarConfiguration 2, look at PCXImageReader
|
|
||||||
// TODO: Auto-rotate based on Orientation
|
// TODO: Auto-rotate based on Orientation
|
||||||
// TODO: Support ICCProfile (fully)
|
|
||||||
// TODO: Support Compression 3 & 4 (CCITT T.4 & T.6)
|
|
||||||
// TODO: Support Compression 34712 (JPEG2000)? Depends on JPEG2000 ImageReader
|
// TODO: Support Compression 34712 (JPEG2000)? Depends on JPEG2000 ImageReader
|
||||||
// TODO: Support Compression 34661 (JBIG)? Depends on JBIG ImageReader
|
// TODO: Support Compression 34661 (JBIG)? Depends on JBIG ImageReader
|
||||||
|
|
||||||
@ -143,6 +139,9 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
// Source region
|
// Source region
|
||||||
// Subsampling
|
// Subsampling
|
||||||
// IIOMetadata (stay close to Sun's TIFF metadata)
|
// IIOMetadata (stay close to Sun's TIFF metadata)
|
||||||
|
// Support ICCProfile
|
||||||
|
// Support PlanarConfiguration 2
|
||||||
|
// Support Compression 3 & 4 (CCITT T.4 & T.6)
|
||||||
|
|
||||||
final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.tiff.debug"));
|
final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.tiff.debug"));
|
||||||
|
|
||||||
@ -317,7 +316,23 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
int bitsPerSample = getBitsPerSample();
|
int bitsPerSample = getBitsPerSample();
|
||||||
int dataType = getDataType(sampleFormat, bitsPerSample);
|
int dataType = getDataType(sampleFormat, bitsPerSample);
|
||||||
|
|
||||||
// TODO: Validate CS using ColorSpaces.validateProfile
|
int opaqueSamplesPerPixel = getOpaqueSamplesPerPixel(interpretation);
|
||||||
|
|
||||||
|
// Spec says ExtraSamples are mandatory of extra samples, however known encoders
|
||||||
|
// (ie. SeaShore) writes ARGB TIFFs without ExtraSamples.
|
||||||
|
long[] extraSamples = getValueAsLongArray(TIFF.TAG_EXTRA_SAMPLES, "ExtraSamples", false);
|
||||||
|
if (extraSamples == null && samplesPerPixel > opaqueSamplesPerPixel) {
|
||||||
|
// TODO: Log warning!
|
||||||
|
// First extra is alpha, rest is "unspecified"
|
||||||
|
extraSamples = new long[samplesPerPixel - opaqueSamplesPerPixel];
|
||||||
|
extraSamples[0] = TIFFBaseline.EXTRASAMPLE_UNASSOCIATED_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine alpha
|
||||||
|
boolean hasAlpha = extraSamples != null;
|
||||||
|
boolean isAlphaPremultiplied = hasAlpha && extraSamples[0] == TIFFBaseline.EXTRASAMPLE_ASSOCIATED_ALPHA;
|
||||||
|
int significantSamples = opaqueSamplesPerPixel + (hasAlpha ? 1 : 0);
|
||||||
|
|
||||||
// Read embedded cs
|
// Read embedded cs
|
||||||
ICC_Profile profile = getICCProfile();
|
ICC_Profile profile = getICCProfile();
|
||||||
ColorSpace cs;
|
ColorSpace cs;
|
||||||
@ -327,11 +342,10 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
case TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO:
|
case TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO:
|
||||||
// WhiteIsZero
|
// WhiteIsZero
|
||||||
// NOTE: We handle this by inverting the values when reading, as Java has no ColorModel that easily supports this.
|
// NOTE: We handle this by inverting the values when reading, as Java has no ColorModel that easily supports this.
|
||||||
// TODO: Consider returning null?
|
|
||||||
case TIFFBaseline.PHOTOMETRIC_BLACK_IS_ZERO:
|
case TIFFBaseline.PHOTOMETRIC_BLACK_IS_ZERO:
|
||||||
// BlackIsZero
|
// BlackIsZero
|
||||||
// Gray scale or B/W
|
// Gray scale or B/W
|
||||||
switch (samplesPerPixel) {
|
switch (significantSamples) {
|
||||||
case 1:
|
case 1:
|
||||||
// TIFF 6.0 Spec says: 1, 4 or 8 for baseline (1 for bi-level, 4/8 for gray)
|
// TIFF 6.0 Spec says: 1, 4 or 8 for baseline (1 for bi-level, 4/8 for gray)
|
||||||
// ImageTypeSpecifier supports 1, 2, 4, 8 or 16 bits per sample, we'll support 32 bits as well.
|
// ImageTypeSpecifier supports 1, 2, 4, 8 or 16 bits per sample, we'll support 32 bits as well.
|
||||||
@ -347,6 +361,7 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType);
|
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType);
|
||||||
}
|
}
|
||||||
else if (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 || bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
else if (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 || bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
||||||
|
// TODO: Should use packed format for 1/2/4
|
||||||
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0}, dataType, false, false);
|
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0}, dataType, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,28 +379,26 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
cs = profile == null ? ColorSpace.getInstance(ColorSpace.CS_GRAY) : ColorSpaces.createColorSpace(profile);
|
cs = profile == null ? ColorSpace.getInstance(ColorSpace.CS_GRAY) : ColorSpaces.createColorSpace(profile);
|
||||||
|
|
||||||
// ExtraSamples 0=unspecified, 1=associated (pre-multiplied), 2=unassociated (TODO: Support unspecified, not alpha)
|
|
||||||
long[] extraSamples = getValueAsLongArray(TIFF.TAG_EXTRA_SAMPLES, "ExtraSamples", true);
|
|
||||||
|
|
||||||
if (cs == ColorSpace.getInstance(ColorSpace.CS_GRAY) && (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32)) {
|
if (cs == ColorSpace.getInstance(ColorSpace.CS_GRAY) && (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32)) {
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
||||||
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType, isAlphaPremultiplied);
|
||||||
case TIFFExtension.PLANARCONFIG_PLANAR:
|
case TIFFExtension.PLANARCONFIG_PLANAR:
|
||||||
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, dataType, true, isAlphaPremultiplied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
else if (/*bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 ||*/ bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
||||||
|
// TODO: Should use packed format for 1/2/4 chunky.
|
||||||
|
// TODO: For 1/2/4 bit planar, we might need to fix while reading... Look at IFFImageReader?
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
||||||
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1}, dataType, true, isAlphaPremultiplied);
|
||||||
case TIFFExtension.PLANARCONFIG_PLANAR:
|
case TIFFExtension.PLANARCONFIG_PLANAR:
|
||||||
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1}, new int[] {0, 0}, dataType, true, isAlphaPremultiplied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IIOException(String.format("Unsupported BitsPerSample for Gray + Alpha TIFF (expected 8, 16 or 32): %d", bitsPerSample));
|
throw new IIOException(String.format("Unsupported BitsPerSample for Gray + Alpha TIFF (expected 8, 16 or 32): %d", bitsPerSample));
|
||||||
// TODO: More samples might be ok, if multiple alpha or unknown samples
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IIOException(String.format("Unsupported SamplesPerPixel/BitsPerSample combination for Bi-level/Gray TIFF (expected 1/1, 1/2, 1/4, 1/8, 1/16 or 1/32, or 2/8, 2/16 or 2/32): %d/%d", samplesPerPixel, bitsPerSample));
|
throw new IIOException(String.format("Unsupported SamplesPerPixel/BitsPerSample combination for Bi-level/Gray TIFF (expected 1/1, 1/2, 1/4, 1/8, 1/16 or 1/32, or 2/8, 2/16 or 2/32): %d/%d", samplesPerPixel, bitsPerSample));
|
||||||
@ -403,15 +416,12 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
cs = profile == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : ColorSpaces.createColorSpace(profile);
|
cs = profile == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : ColorSpaces.createColorSpace(profile);
|
||||||
|
|
||||||
switch (samplesPerPixel) {
|
switch (significantSamples) {
|
||||||
case 3:
|
case 3:
|
||||||
if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
||||||
if (bitsPerSample == 8 && cs.isCS_sRGB()) {
|
// "TYPE_3_BYTE_RGB" if cs.isCS_sRGB()
|
||||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2}, dataType, false, false);
|
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2}, dataType, false, false);
|
||||||
|
|
||||||
case TIFFExtension.PLANARCONFIG_PLANAR:
|
case TIFFExtension.PLANARCONFIG_PLANAR:
|
||||||
@ -420,27 +430,18 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
if (bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32) {
|
||||||
// ExtraSamples 0=unspecified, 1=associated (pre-multiplied), 2=unassociated (TODO: Support unspecified, not alpha)
|
|
||||||
long[] extraSamples = getValueAsLongArray(TIFF.TAG_EXTRA_SAMPLES, "ExtraSamples", true);
|
|
||||||
|
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
||||||
if (bitsPerSample == 8 && cs.isCS_sRGB()) {
|
// "TYPE_4_BYTE_RGBA" if cs.isCS_sRGB()
|
||||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_4BYTE_ABGR);
|
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3}, dataType, true, isAlphaPremultiplied);
|
||||||
}
|
|
||||||
|
|
||||||
return ImageTypeSpecifiers.createInterleaved(cs, new int[]{ 0, 1, 2, 3}, dataType, true, extraSamples[0] == 1);
|
|
||||||
|
|
||||||
case TIFFExtension.PLANARCONFIG_PLANAR:
|
case TIFFExtension.PLANARCONFIG_PLANAR:
|
||||||
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3}, new int[] {0, 0, 0, 0}, dataType, true, isAlphaPremultiplied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bitsPerSample == 4) {
|
else if (bitsPerSample == 4) {
|
||||||
long[] extraSamples = getValueAsLongArray(TIFF.TAG_EXTRA_SAMPLES, "ExtraSamples", true);
|
return ImageTypeSpecifiers.createPacked(cs, 0xF000, 0xF00, 0xF0, 0xF, DataBuffer.TYPE_USHORT, isAlphaPremultiplied);
|
||||||
|
|
||||||
return ImageTypeSpecifier.createPacked(cs, 0xF000, 0xF00, 0xF0, 0xF, DataBuffer.TYPE_USHORT, extraSamples[0] == 1);
|
|
||||||
}
|
}
|
||||||
// TODO: More samples might be ok, if multiple alpha or unknown samples
|
|
||||||
default:
|
default:
|
||||||
throw new IIOException(String.format("Unsupported SamplesPerPixels/BitsPerSample combination for RGB TIFF (expected 3/8, 4/8, 3/16 or 4/16): %d/%d", samplesPerPixel, bitsPerSample));
|
throw new IIOException(String.format("Unsupported SamplesPerPixels/BitsPerSample combination for RGB TIFF (expected 3/8, 4/8, 3/16 or 4/16): %d/%d", samplesPerPixel, bitsPerSample));
|
||||||
}
|
}
|
||||||
@ -452,8 +453,8 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
else if (bitsPerSample <= 0 || bitsPerSample > 16) {
|
else if (bitsPerSample <= 0 || bitsPerSample > 16) {
|
||||||
throw new IIOException("Bad BitsPerSample value for Palette TIFF (expected <= 16): " + bitsPerSample);
|
throw new IIOException("Bad BitsPerSample value for Palette TIFF (expected <= 16): " + bitsPerSample);
|
||||||
}
|
}
|
||||||
// NOTE: If ExtraSamples is used, PlanarConfiguration must be taken into account also for pixel data
|
|
||||||
|
|
||||||
|
// NOTE: If ExtraSamples is used, PlanarConfiguration must be taken into account also for pixel data
|
||||||
Entry colorMap = currentIFD.getEntryById(TIFF.TAG_COLOR_MAP);
|
Entry colorMap = currentIFD.getEntryById(TIFF.TAG_COLOR_MAP);
|
||||||
if (colorMap == null) {
|
if (colorMap == null) {
|
||||||
throw new IIOException("Missing ColorMap for Palette TIFF");
|
throw new IIOException("Missing ColorMap for Palette TIFF");
|
||||||
@ -483,7 +484,7 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
cs = profile == null ? ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK) : ColorSpaces.createColorSpace(profile);
|
cs = profile == null ? ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK) : ColorSpaces.createColorSpace(profile);
|
||||||
|
|
||||||
switch (samplesPerPixel) {
|
switch (significantSamples) {
|
||||||
case 4:
|
case 4:
|
||||||
if (bitsPerSample == 8 || bitsPerSample == 16) {
|
if (bitsPerSample == 8 || bitsPerSample == 16) {
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
@ -495,19 +496,14 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
if (bitsPerSample == 8 || bitsPerSample == 16) {
|
if (bitsPerSample == 8 || bitsPerSample == 16) {
|
||||||
// ExtraSamples 0=unspecified, 1=associated (pre-multiplied), 2=unassociated (TODO: Support unspecified, not alpha)
|
|
||||||
long[] extraSamples = getValueAsLongArray(TIFF.TAG_EXTRA_SAMPLES, "ExtraSamples", true);
|
|
||||||
|
|
||||||
switch (planarConfiguration) {
|
switch (planarConfiguration) {
|
||||||
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
case TIFFBaseline.PLANARCONFIG_CHUNKY:
|
||||||
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3, 4}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createInterleaved(cs, new int[] {0, 1, 2, 3, 4}, dataType, true, isAlphaPremultiplied);
|
||||||
case TIFFExtension.PLANARCONFIG_PLANAR:
|
case TIFFExtension.PLANARCONFIG_PLANAR:
|
||||||
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3, 4}, new int[] {0, 0, 0, 0, 0}, dataType, true, extraSamples[0] == 1);
|
return ImageTypeSpecifiers.createBanded(cs, new int[] {0, 1, 2, 3, 4}, new int[] {0, 0, 0, 0, 0}, dataType, true, isAlphaPremultiplied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: More samples might be ok, if multiple alpha or unknown samples, consult ExtraSamples
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IIOException(
|
throw new IIOException(
|
||||||
String.format("Unsupported TIFF SamplesPerPixels/BitsPerSample combination for Separated TIFF (expected 4/8, 4/16, 5/8 or 5/16): %d/%s", samplesPerPixel, bitsPerSample)
|
String.format("Unsupported TIFF SamplesPerPixels/BitsPerSample combination for Separated TIFF (expected 4/8, 4/16, 5/8 or 5/16): %d/%s", samplesPerPixel, bitsPerSample)
|
||||||
@ -515,13 +511,42 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
case TIFFBaseline.PHOTOMETRIC_MASK:
|
case TIFFBaseline.PHOTOMETRIC_MASK:
|
||||||
// Transparency mask
|
// Transparency mask
|
||||||
|
case TIFFExtension.PHOTOMETRIC_CIELAB:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_ICCLAB:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_ITULAB:
|
||||||
|
// L*a*b* color. Handled using conversion to linear RGB
|
||||||
|
case TIFFCustom.PHOTOMETRIC_LOGL:
|
||||||
|
case TIFFCustom.PHOTOMETRIC_LOGLUV:
|
||||||
|
// Log
|
||||||
|
case TIFFCustom.PHOTOMETRIC_CFA:
|
||||||
|
case TIFFCustom.PHOTOMETRIC_LINEAR_RAW:
|
||||||
|
// RAW (DNG)
|
||||||
throw new IIOException("Unsupported TIFF PhotometricInterpretation value: " + interpretation);
|
throw new IIOException("Unsupported TIFF PhotometricInterpretation value: " + interpretation);
|
||||||
default:
|
default:
|
||||||
throw new IIOException("Unknown TIFF PhotometricInterpretation value: " + interpretation);
|
throw new IIOException("Unknown TIFF PhotometricInterpretation value: " + interpretation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getOpaqueSamplesPerPixel(final int photometricInterpretation) throws IIOException {
|
||||||
|
switch (photometricInterpretation) {
|
||||||
|
case TIFFBaseline.PHOTOMETRIC_WHITE_IS_ZERO:
|
||||||
|
case TIFFBaseline.PHOTOMETRIC_BLACK_IS_ZERO:
|
||||||
|
case TIFFBaseline.PHOTOMETRIC_PALETTE:
|
||||||
|
case TIFFBaseline.PHOTOMETRIC_MASK:
|
||||||
|
return 1;
|
||||||
|
case TIFFBaseline.PHOTOMETRIC_RGB:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_YCBCR:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_CIELAB:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_ICCLAB:
|
||||||
|
case TIFFExtension.PHOTOMETRIC_ITULAB:
|
||||||
|
return 3;
|
||||||
|
case TIFFExtension.PHOTOMETRIC_SEPARATED:
|
||||||
|
return getValueAsIntWithDefault(TIFF.TAG_NUMBER_OF_INKS, 4);
|
||||||
|
default:
|
||||||
|
throw new IIOException("Unknown TIFF PhotometricInterpretation value: " + photometricInterpretation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getDataType(int sampleFormat, int bitsPerSample) throws IIOException {
|
private int getDataType(int sampleFormat, int bitsPerSample) throws IIOException {
|
||||||
switch (sampleFormat) {
|
switch (sampleFormat) {
|
||||||
case TIFFBaseline.SAMPLEFORMAT_UINT:
|
case TIFFBaseline.SAMPLEFORMAT_UINT:
|
||||||
@ -623,11 +648,16 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
else {
|
else {
|
||||||
int bitsPerSample = (int) value[0];
|
int bitsPerSample = (int) value[0];
|
||||||
|
|
||||||
|
if (value.length == 3 && (value[0] == 5 && value[1] == 6 && value[2] == 5)) {
|
||||||
|
// Special case for UINT_565. We're good.
|
||||||
|
}
|
||||||
|
else {
|
||||||
for (int i = 1; i < value.length; i++) {
|
for (int i = 1; i < value.length; i++) {
|
||||||
if (value[i] != bitsPerSample) {
|
if (value[i] != bitsPerSample) {
|
||||||
throw new IIOException("Variable BitsPerSample not supported: " + Arrays.toString(value));
|
throw new IIOException("Variable BitsPerSample not supported: " + Arrays.toString(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return bitsPerSample;
|
return bitsPerSample;
|
||||||
}
|
}
|
||||||
@ -719,7 +749,7 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
int tilesAcross = (width + stripTileWidth - 1) / stripTileWidth;
|
int tilesAcross = (width + stripTileWidth - 1) / stripTileWidth;
|
||||||
int tilesDown = (height + stripTileHeight - 1) / stripTileHeight;
|
int tilesDown = (height + stripTileHeight - 1) / stripTileHeight;
|
||||||
// WritableRaster rowRaster = rawType.getColorModel().createCompatibleWritableRaster(stripTileWidth, 1);
|
// TODO: If extrasamples, we might need to create a raster with more samples...
|
||||||
WritableRaster rowRaster = rawType.createBufferedImage(stripTileWidth, 1).getRaster();
|
WritableRaster rowRaster = rawType.createBufferedImage(stripTileWidth, 1).getRaster();
|
||||||
Rectangle clip = new Rectangle(srcRegion);
|
Rectangle clip = new Rectangle(srcRegion);
|
||||||
int row = 0;
|
int row = 0;
|
||||||
@ -1310,9 +1340,21 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
final int colsInTile, final int rowsInTile, final DataInput input)
|
final int colsInTile, final int rowsInTile, final DataInput input)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
|
DataBuffer dataBuffer = tileRowRaster.getDataBuffer();
|
||||||
|
int bands = dataBuffer.getNumBanks();
|
||||||
|
boolean banded = bands > 1;
|
||||||
|
|
||||||
switch (tileRowRaster.getTransferType()) {
|
switch (tileRowRaster.getTransferType()) {
|
||||||
case DataBuffer.TYPE_BYTE:
|
case DataBuffer.TYPE_BYTE:
|
||||||
byte[] rowDataByte = ((DataBufferByte) tileRowRaster.getDataBuffer()).getData();
|
|
||||||
|
for (int band = 0; band < bands; band++) {
|
||||||
|
byte[] rowDataByte = ((DataBufferByte) dataBuffer).getData(band);
|
||||||
|
WritableRaster destChannel = banded
|
||||||
|
? raster.createWritableChild(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight(), 0, 0, new int[] {band})
|
||||||
|
: raster;
|
||||||
|
Raster srcChannel = banded
|
||||||
|
? tileRowRaster.createChild(tileRowRaster.getMinX(), 0, tileRowRaster.getWidth(), 1, 0, 0, new int[] {band})
|
||||||
|
: tileRowRaster;
|
||||||
|
|
||||||
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
||||||
if (row >= srcRegion.y + srcRegion.height) {
|
if (row >= srcRegion.y + srcRegion.height) {
|
||||||
@ -1331,17 +1373,26 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raster.setDataElements(startCol, (row - srcRegion.y) / ySub, tileRowRaster);
|
destChannel.setDataElements(startCol, (row - srcRegion.y) / ySub, srcChannel);
|
||||||
}
|
}
|
||||||
// Else skip data
|
// Else skip data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DataBuffer.TYPE_USHORT:
|
case DataBuffer.TYPE_USHORT:
|
||||||
case DataBuffer.TYPE_SHORT:
|
case DataBuffer.TYPE_SHORT:
|
||||||
short[] rowDataShort = tileRowRaster.getTransferType() == DataBuffer.TYPE_USHORT
|
for (int band = 0; band < bands; band++) {
|
||||||
? ((DataBufferUShort) tileRowRaster.getDataBuffer()).getData()
|
short[] rowDataShort = dataBuffer.getDataType() == DataBuffer.TYPE_USHORT
|
||||||
: ((DataBufferShort) tileRowRaster.getDataBuffer()).getData();
|
? ((DataBufferUShort) dataBuffer).getData(band)
|
||||||
|
: ((DataBufferShort) dataBuffer).getData(band);
|
||||||
|
|
||||||
|
WritableRaster destChannel = banded
|
||||||
|
? raster.createWritableChild(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight(), 0, 0, new int[] {band})
|
||||||
|
: raster;
|
||||||
|
Raster srcChannel = banded
|
||||||
|
? tileRowRaster.createChild(tileRowRaster.getMinX(), 0, tileRowRaster.getWidth(), 1, 0, 0, new int[] {band})
|
||||||
|
: tileRowRaster;
|
||||||
|
|
||||||
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
||||||
if (row >= srcRegion.y + srcRegion.height) {
|
if (row >= srcRegion.y + srcRegion.height) {
|
||||||
@ -1360,16 +1411,25 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raster.setDataElements(startCol, row - srcRegion.y, tileRowRaster);
|
destChannel.setDataElements(startCol, row - srcRegion.y, srcChannel);
|
||||||
// TODO: Possible speedup ~30%!:
|
// TODO: Possible speedup ~30%!:
|
||||||
// raster.setDataElements(startCol, row - srcRegion.y, colsInTile, 1, rowDataShort);
|
// raster.setDataElements(startCol, row - srcRegion.y, colsInTile, 1, rowDataShort);
|
||||||
}
|
}
|
||||||
// Else skip data
|
// Else skip data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DataBuffer.TYPE_INT:
|
case DataBuffer.TYPE_INT:
|
||||||
int[] rowDataInt = ((DataBufferInt) tileRowRaster.getDataBuffer()).getData();
|
for (int band = 0; band < bands; band++) {
|
||||||
|
int[] rowDataInt = ((DataBufferInt) dataBuffer).getData(band);
|
||||||
|
|
||||||
|
WritableRaster destChannel = banded
|
||||||
|
? raster.createWritableChild(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight(), 0, 0, new int[] {band})
|
||||||
|
: raster;
|
||||||
|
Raster srcChannel = banded
|
||||||
|
? tileRowRaster.createChild(tileRowRaster.getMinX(), 0, tileRowRaster.getWidth(), 1, 0, 0, new int[] {band})
|
||||||
|
: tileRowRaster;
|
||||||
|
|
||||||
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
||||||
if (row >= srcRegion.y + srcRegion.height) {
|
if (row >= srcRegion.y + srcRegion.height) {
|
||||||
@ -1388,15 +1448,24 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raster.setDataElements(startCol, row - srcRegion.y, tileRowRaster);
|
destChannel.setDataElements(startCol, row - srcRegion.y, srcChannel);
|
||||||
}
|
}
|
||||||
// Else skip data
|
// Else skip data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DataBuffer.TYPE_FLOAT:
|
case DataBuffer.TYPE_FLOAT:
|
||||||
float[] rowDataFloat = ((DataBufferFloat) tileRowRaster.getDataBuffer()).getData();
|
for (int band = 0; band < bands; band++) {
|
||||||
|
float[] rowDataFloat = ((DataBufferFloat) tileRowRaster.getDataBuffer()).getData(band);
|
||||||
|
|
||||||
|
WritableRaster destChannel = banded
|
||||||
|
? raster.createWritableChild(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight(), 0, 0, new int[] {band})
|
||||||
|
: raster;
|
||||||
|
Raster srcChannel = banded
|
||||||
|
? tileRowRaster.createChild(tileRowRaster.getMinX(), 0, tileRowRaster.getWidth(), 1, 0, 0, new int[] {band})
|
||||||
|
: tileRowRaster;
|
||||||
|
|
||||||
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
for (int row = startRow; row < startRow + rowsInTile; row++) {
|
||||||
if (row >= srcRegion.y + srcRegion.height) {
|
if (row >= srcRegion.y + srcRegion.height) {
|
||||||
@ -1406,7 +1475,8 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
readFully(input, rowDataFloat);
|
readFully(input, rowDataFloat);
|
||||||
|
|
||||||
if (row >= srcRegion.y) {
|
if (row >= srcRegion.y) {
|
||||||
// normalizeBlack(interpretation, rowDataFloat);
|
// TODO: Allow param to decide tone mapping strategy, like in the HDRImageReader
|
||||||
|
clamp(rowDataFloat);
|
||||||
|
|
||||||
// Subsample horizontal
|
// Subsample horizontal
|
||||||
if (xSub != 1) {
|
if (xSub != 1) {
|
||||||
@ -1415,15 +1485,24 @@ public class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raster.setDataElements(startCol, row - srcRegion.y, tileRowRaster);
|
destChannel.setDataElements(startCol, row - srcRegion.y, srcChannel);
|
||||||
}
|
}
|
||||||
// Else skip data
|
// Else skip data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clamp(float[] rowDataFloat) {
|
||||||
|
for (int i = 0; i < rowDataFloat.length; i++) {
|
||||||
|
if (rowDataFloat[i] > 1) {
|
||||||
|
rowDataFloat[i] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Candidate util method (with off/len + possibly byte order)
|
// TODO: Candidate util method (with off/len + possibly byte order)
|
||||||
private void readFully(final DataInput input, final float[] rowDataFloat) throws IOException {
|
private void readFully(final DataInput input, final float[] rowDataFloat) throws IOException {
|
||||||
if (input instanceof ImageInputStream) {
|
if (input instanceof ImageInputStream) {
|
||||||
|
@ -50,8 +50,8 @@ final class TIFFProviderInfo extends ReaderWriterProviderInfo {
|
|||||||
new String[] {"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi"},
|
new String[] {"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi"},
|
||||||
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter",
|
"com.twelvemonkeys.imageio.plugins.tiff.TIFFImageWriter",
|
||||||
new String[] {"com.twelvemkonkeys.imageio.plugins.tif.TIFFImageWriterSpi"},
|
new String[] {"com.twelvemkonkeys.imageio.plugins.tif.TIFFImageWriterSpi"},
|
||||||
false, TIFFMedataFormat.SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, "com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadata", null, null,
|
false, TIFFMedataFormat.SUN_NATIVE_STREAM_METADATA_FORMAT_NAME, "TODO", null, null,
|
||||||
true, TIFFMedataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME, "TODO", null, null
|
true, TIFFMedataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME, "com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadata", null, null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,32 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
|||||||
new TestData(getClassLoaderResource("/tiff/ccitt/group3_2d_fill.tif"), new Dimension(6, 4)), // B/W, CCITT T4 2D
|
new TestData(getClassLoaderResource("/tiff/ccitt/group3_2d_fill.tif"), new Dimension(6, 4)), // B/W, CCITT T4 2D
|
||||||
new TestData(getClassLoaderResource("/tiff/ccitt/group3_2d_lsb2msb.tif"), new Dimension(6, 4)), // B/W, CCITT T4 2D, LSB
|
new TestData(getClassLoaderResource("/tiff/ccitt/group3_2d_lsb2msb.tif"), new Dimension(6, 4)), // B/W, CCITT T4 2D, LSB
|
||||||
new TestData(getClassLoaderResource("/tiff/ccitt/group4.tif"), new Dimension(6, 4)), // B/W, CCITT T6 1D
|
new TestData(getClassLoaderResource("/tiff/ccitt/group4.tif"), new Dimension(6, 4)), // B/W, CCITT T6 1D
|
||||||
new TestData(getClassLoaderResource("/tiff/fivepages-scan-causingerrors.tif"), new Dimension(2480, 3518)) // B/W, CCITT T4
|
new TestData(getClassLoaderResource("/tiff/fivepages-scan-causingerrors.tif"), new Dimension(2480, 3518)), // B/W, CCITT T4
|
||||||
|
// Gray
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-02.tif"), new Dimension(73, 43)), // Gray 2 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-04.tif"), new Dimension(73, 43)), // Gray 4 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-08.tif"), new Dimension(73, 43)), // Gray 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-16.tif"), new Dimension(73, 43)), // Gray 16 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-32.tif"), new Dimension(73, 43)), // Gray 32 bit/sample
|
||||||
|
// Palette
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-02.tif"), new Dimension(73, 43)), // Palette 2 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-04.tif"), new Dimension(73, 43)), // Palette 4 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-08.tif"), new Dimension(73, 43)), // Palette 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-16.tif"), new Dimension(73, 43)), // Palette 16 bit/sample
|
||||||
|
// RGB Interleaved (PlanarConfiguration: 1)
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-08.tif"), new Dimension(73, 43)), // RGB 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-16.tif"), new Dimension(73, 43)), // RGB 16 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-32.tif"), new Dimension(73, 43)), // RGB 32 bit/sample
|
||||||
|
// RGB Planar (PlanarConfiguration: 2)
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-08.tif"), new Dimension(73, 43)), // RGB 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-16.tif"), new Dimension(73, 43)), // RGB 16 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-32.tif"), new Dimension(73, 43)), // RGB 32 bit FP samples!
|
||||||
|
// Separated (CMYK) Interleaved (PlanarConfiguration: 1)
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-08.tif"), new Dimension(73, 43)), // CMYK 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-16.tif"), new Dimension(73, 43)), // CMYK 16 bit/sample
|
||||||
|
// Separated (CMYK) Planar (PlanarConfiguration: 2)
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-08.tif"), new Dimension(73, 43)), // CMYK 8 bit/sample
|
||||||
|
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-16.tif"), new Dimension(73, 43)) // CMYK 16 bit/sample
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,4 +253,77 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
|||||||
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ICC profile"));
|
verify(warningListener, atLeastOnce()).warningOccurred(eq(reader), contains("ICC profile"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlanarEqualInterleavedRGB() throws IOException {
|
||||||
|
TestData expectedData = new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-08.tif"), new Dimension(73, 43));
|
||||||
|
TestData testData = new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-08.tif"), new Dimension(73, 43));
|
||||||
|
|
||||||
|
try (ImageInputStream expectedStream = expectedData.getInputStream(); ImageInputStream stream = testData.getInputStream()) {
|
||||||
|
TIFFImageReader reader = createReader();
|
||||||
|
|
||||||
|
reader.setInput(expectedStream);
|
||||||
|
BufferedImage expected = reader.read(0, null);
|
||||||
|
|
||||||
|
reader.setInput(stream);
|
||||||
|
BufferedImage actual = reader.read(0, null);
|
||||||
|
|
||||||
|
assertImageDataEquals("", expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlanarEqualInterleavedRGB16() throws IOException {
|
||||||
|
TestData expectedData = new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-16.tif"), new Dimension(73, 43));
|
||||||
|
TestData testData = new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-16.tif"), new Dimension(73, 43));
|
||||||
|
|
||||||
|
try (ImageInputStream expectedStream = expectedData.getInputStream(); ImageInputStream stream = testData.getInputStream()) {
|
||||||
|
TIFFImageReader reader = createReader();
|
||||||
|
|
||||||
|
reader.setInput(expectedStream);
|
||||||
|
BufferedImage expected = reader.read(0, null);
|
||||||
|
|
||||||
|
reader.setInput(stream);
|
||||||
|
BufferedImage actual = reader.read(0, null);
|
||||||
|
|
||||||
|
assertImageDataEquals("", expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlanarEqualInterleavedSeparated() throws IOException {
|
||||||
|
TestData expectedData = new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-08.tif"), new Dimension(73, 43));
|
||||||
|
TestData testData = new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-08.tif"), new Dimension(73, 43));
|
||||||
|
|
||||||
|
try (ImageInputStream expectedStream = expectedData.getInputStream(); ImageInputStream stream = testData.getInputStream()) {
|
||||||
|
TIFFImageReader reader = createReader();
|
||||||
|
|
||||||
|
reader.setInput(expectedStream);
|
||||||
|
BufferedImage expected = reader.read(0, null);
|
||||||
|
|
||||||
|
reader.setInput(stream);
|
||||||
|
BufferedImage actual = reader.read(0, null);
|
||||||
|
|
||||||
|
assertImageDataEquals("", expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlanarEqualInterleavedSeparated16() throws IOException {
|
||||||
|
TestData expectedData = new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-16.tif"), new Dimension(73, 43));
|
||||||
|
TestData testData = new TestData(getClassLoaderResource("/tiff/depth/flower-separated-planar-16.tif"), new Dimension(73, 43));
|
||||||
|
|
||||||
|
try (ImageInputStream expectedStream = expectedData.getInputStream(); ImageInputStream stream = testData.getInputStream()) {
|
||||||
|
TIFFImageReader reader = createReader();
|
||||||
|
|
||||||
|
reader.setInput(expectedStream);
|
||||||
|
BufferedImage expected = reader.read(0, null);
|
||||||
|
|
||||||
|
reader.setInput(stream);
|
||||||
|
BufferedImage actual = reader.read(0, null);
|
||||||
|
|
||||||
|
assertImageDataEquals("", expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
These sample TIFF image files are prepared by Bob Friesenhahn
|
||||||
|
<bfriesen@simple.dallas.tx.us> using a development version of
|
||||||
|
GraphicsMagick 1.2.
|
||||||
|
|
||||||
|
See the file summary.txt for a description of the images.
|
||||||
|
|
||||||
|
These files are hereby placed in the public domain.
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
flower-minisblack-02.tif 73x43 2-bit minisblack gray image
|
||||||
|
flower-minisblack-04.tif 73x43 4-bit minisblack gray image
|
||||||
|
flower-minisblack-06.tif 73x43 6-bit minisblack gray image
|
||||||
|
flower-minisblack-08.tif 73x43 8-bit minisblack gray image
|
||||||
|
flower-minisblack-10.tif 73x43 10-bit minisblack gray image
|
||||||
|
flower-minisblack-12.tif 73x43 12-bit minisblack gray image
|
||||||
|
flower-minisblack-14.tif 73x43 14-bit minisblack gray image
|
||||||
|
flower-minisblack-16.tif 73x43 16-bit minisblack gray image
|
||||||
|
flower-minisblack-24.tif 73x43 24-bit minisblack gray image
|
||||||
|
flower-minisblack-32.tif 73x43 32-bit minisblack gray image
|
||||||
|
flower-palette-02.tif 73x43 4-entry colormapped image
|
||||||
|
flower-palette-04.tif 73x43 16-entry colormapped image
|
||||||
|
flower-palette-08.tif 73x43 256-entry colormapped image
|
||||||
|
flower-palette-16.tif 73x43 65536-entry colormapped image
|
||||||
|
flower-rgb-contig-02.tif 73x43 2-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-04.tif 73x43 4-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-08.tif 73x43 8-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-10.tif 73x43 10-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-12.tif 73x43 12-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-14.tif 73x43 14-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-16.tif 73x43 16-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-24.tif 73x43 24-bit contiguous RGB image
|
||||||
|
flower-rgb-contig-32.tif 73x43 32-bit contiguous RGB image
|
||||||
|
flower-rgb-planar-02.tif 73x43 2-bit seperated RGB image
|
||||||
|
flower-rgb-planar-04.tif 73x43 4-bit seperated RGB image
|
||||||
|
flower-rgb-planar-08.tif 73x43 8-bit seperated RGB image
|
||||||
|
flower-rgb-planar-10.tif 73x43 10-bit seperated RGB image
|
||||||
|
flower-rgb-planar-12.tif 73x43 12-bit seperated RGB image
|
||||||
|
flower-rgb-planar-14.tif 73x43 14-bit seperated RGB image
|
||||||
|
flower-rgb-planar-16.tif 73x43 16-bit seperated RGB image
|
||||||
|
flower-rgb-planar-24.tif 73x43 24-bit seperated RGB image
|
||||||
|
flower-rgb-planar-32.tif 73x43 32-bit seperated RGB image
|
||||||
|
flower-separated-contig-08.tif 73x43 8-bit contiguous CMYK image
|
||||||
|
flower-separated-contig-16.tif 73x43 16-bit contiguous CMYK image
|
||||||
|
flower-separated-planar-08.tif 73x43 8-bit separated CMYK image
|
||||||
|
flower-separated-planar-16.tif 73x43 16-bit separated CMYK image
|
Loading…
x
Reference in New Issue
Block a user