< prev index next >
src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java
Print this page
*** 154,163 ****
--- 154,168 ----
* {@code true} if the image is encoded using separate planes.
*/
protected boolean planar;
/**
+ * The planar band to decode; ignored for chunky (interleaved) images.
+ */
+ protected int planarBand = 0;
+
+ /**
* The value of the {@code SamplesPerPixel} tag.
*/
protected int samplesPerPixel;
/**
*** 444,471 ****
/**
* Create a {@code ComponentColorModel} for use in creating
* an {@code ImageTypeSpecifier}.
*/
! // This code was copied from javax.imageio.ImageTypeSpecifier.
static ColorModel createComponentCM(ColorSpace colorSpace,
int numBands,
int dataType,
boolean hasAlpha,
boolean isAlphaPremultiplied) {
int transparency =
hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
- int[] numBits = new int[numBands];
- int bits = DataBuffer.getDataTypeSize(dataType);
-
- for (int i = 0; i < numBands; i++) {
- numBits[i] = bits;
- }
-
return new ComponentColorModel(colorSpace,
! numBits,
hasAlpha,
isAlphaPremultiplied,
transparency,
dataType);
}
--- 449,471 ----
/**
* Create a {@code ComponentColorModel} for use in creating
* an {@code ImageTypeSpecifier}.
*/
! // This code was inspired by the method of the same name in
! // javax.imageio.ImageTypeSpecifier
static ColorModel createComponentCM(ColorSpace colorSpace,
int numBands,
+ int[] bitsPerSample,
int dataType,
boolean hasAlpha,
boolean isAlphaPremultiplied) {
int transparency =
hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
return new ComponentColorModel(colorSpace,
! bitsPerSample,
hasAlpha,
isAlphaPremultiplied,
transparency,
dataType);
}
*** 579,596 ****
/**
* Determines whether the {@code DataBuffer} is filled without
* any interspersed padding bits.
*/
! private static boolean isDataBufferBitContiguous(SampleModel sm)
throws IIOException {
int dataTypeSize = getDataTypeSize(sm.getDataType());
if(sm instanceof ComponentSampleModel) {
int numBands = sm.getNumBands();
for(int i = 0; i < numBands; i++) {
! if(sm.getSampleSize(i) != dataTypeSize) {
// Sample does not fill data element.
return false;
}
}
} else if(sm instanceof MultiPixelPackedSampleModel) {
--- 579,597 ----
/**
* Determines whether the {@code DataBuffer} is filled without
* any interspersed padding bits.
*/
! private static boolean isDataBufferBitContiguous(SampleModel sm,
! int[] bitsPerSample)
throws IIOException {
int dataTypeSize = getDataTypeSize(sm.getDataType());
if(sm instanceof ComponentSampleModel) {
int numBands = sm.getNumBands();
for(int i = 0; i < numBands; i++) {
! if(bitsPerSample[i] != dataTypeSize) {
// Sample does not fill data element.
return false;
}
}
} else if(sm instanceof MultiPixelPackedSampleModel) {
*** 680,699 ****
/**
* Reformats bit-discontiguous data into the {@code DataBuffer}
* of the supplied {@code WritableRaster}.
*/
private static void reformatDiscontiguousData(byte[] buf,
int stride,
int w,
int h,
WritableRaster raster)
throws IOException {
// Get SampleModel info.
SampleModel sm = raster.getSampleModel();
int numBands = sm.getNumBands();
- int[] sampleSize = sm.getSampleSize();
// Initialize input stream.
ByteArrayInputStream is = new ByteArrayInputStream(buf);
ImageInputStream iis = new MemoryCacheImageInputStream(is);
--- 681,700 ----
/**
* Reformats bit-discontiguous data into the {@code DataBuffer}
* of the supplied {@code WritableRaster}.
*/
private static void reformatDiscontiguousData(byte[] buf,
+ int[] bitsPerSample,
int stride,
int w,
int h,
WritableRaster raster)
throws IOException {
// Get SampleModel info.
SampleModel sm = raster.getSampleModel();
int numBands = sm.getNumBands();
// Initialize input stream.
ByteArrayInputStream is = new ByteArrayInputStream(buf);
ImageInputStream iis = new MemoryCacheImageInputStream(is);
*** 703,713 ****
for(int j = 0; j < h; j++, y++) {
iis.seek(iisPosition);
int x = raster.getMinX();
for(int i = 0; i < w; i++, x++) {
for(int b = 0; b < numBands; b++) {
! long bits = iis.readBits(sampleSize[b]);
raster.setSample(x, y, b, (int)bits);
}
}
iisPosition += stride;
}
--- 704,714 ----
for(int j = 0; j < h; j++, y++) {
iis.seek(iisPosition);
int x = raster.getMinX();
for(int i = 0; i < w; i++, x++) {
for(int b = 0; b < numBands; b++) {
! long bits = iis.readBits(bitsPerSample[b]);
raster.setSample(x, y, b, (int)bits);
}
}
iisPosition += stride;
}
*** 804,815 ****
redLut[i] = (byte)((colorMap[i]*255)/65535);
greenLut[i] = (byte)((colorMap[mapSize + i]*255)/65535);
blueLut[i] = (byte)((colorMap[2*mapSize + i]*255)/65535);
}
! int dataType = bitsPerSample[0] == 8 ?
! DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
return ImageTypeSpecifier.createIndexed(redLut,
greenLut,
blueLut,
alphaLut,
bitsPerSample[0],
--- 805,823 ----
redLut[i] = (byte)((colorMap[i]*255)/65535);
greenLut[i] = (byte)((colorMap[mapSize + i]*255)/65535);
blueLut[i] = (byte)((colorMap[2*mapSize + i]*255)/65535);
}
! int dataType;
! if (bitsPerSample[0] <= 8) {
! dataType = DataBuffer.TYPE_BYTE;
! } else if (sampleFormat[0] ==
! BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
! dataType = DataBuffer.TYPE_SHORT;
! } else {
! dataType = DataBuffer.TYPE_USHORT;
! }
return ImageTypeSpecifier.createIndexed(redLut,
greenLut,
blueLut,
alphaLut,
bitsPerSample[0],
*** 1080,1096 ****
--- 1088,1106 ----
alphaPremultiplied = true;
}
cm = createComponentCM(cs,
samplesPerPixel,
+ bitsPerSample,
dataType,
hasAlpha,
alphaPremultiplied);
} else {
ColorSpace cs = new BogusColorSpace(samplesPerPixel);
cm = createComponentCM(cs,
samplesPerPixel,
+ bitsPerSample,
dataType,
false, // hasAlpha
false); // alphaPremultiplied
}
return new ImageTypeSpecifier(cm, sm);
*** 1117,1137 ****
boolean isSigned =
(sampleFormat[0] ==
BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
// Grayscale
! if(samplesPerPixel == 1) {
! int dataType =
! getDataTypeFromNumBits(maxBitsPerSample, isSigned);
! return ImageTypeSpecifier.createGrayscale(maxBitsPerSample,
dataType,
isSigned);
}
// Gray-alpha
! if (samplesPerPixel == 2) {
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
--- 1127,1153 ----
boolean isSigned =
(sampleFormat[0] ==
BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
// Grayscale
! if(samplesPerPixel == 1 &&
! (bitsPerSample[0] == 1 || bitsPerSample[0] == 2 ||
! bitsPerSample[0] == 4 || bitsPerSample[0] == 8 ||
! bitsPerSample[0] == 16)) {
! int dataType = getDataTypeFromNumBits(maxBitsPerSample, isSigned);
! return ImageTypeSpecifier.createGrayscale(bitsPerSample[0],
dataType,
isSigned);
}
// Gray-alpha
! if (samplesPerPixel == 2 &&
! bitsPerSample[0] == bitsPerSample[1] &&
! (bitsPerSample[0] == 1 || bitsPerSample[0] == 2 ||
! bitsPerSample[0] == 4 || bitsPerSample[0] == 8 ||
! bitsPerSample[0] == 16)) {
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
*** 1145,1154 ****
--- 1161,1177 ----
false,
alphaPremultiplied);
}
if (samplesPerPixel == 3 || samplesPerPixel == 4) {
+ int dataType = getDataTypeFromNumBits(maxBitsPerSample, isSigned);
+ int dataTypeSize;
+ try {
+ dataTypeSize = getDataTypeSize(dataType);
+ } catch (IIOException ignored) {
+ dataTypeSize = maxBitsPerSample;
+ }
if(totalBits <= 32 && !isSigned) {
// Packed RGB or RGBA
int redMask = createMask(bitsPerSample, 0);
int greenMask = createMask(bitsPerSample, 1);
int blueMask = createMask(bitsPerSample, 2);
*** 1167,1191 ****
greenMask,
blueMask,
alphaMask,
transferType,
alphaPremultiplied);
! } else if(samplesPerPixel == 3) {
// Interleaved RGB
int[] bandOffsets = new int[] {0, 1, 2};
- int dataType =
- getDataTypeFromNumBits(maxBitsPerSample, isSigned);
return ImageTypeSpecifier.createInterleaved(rgb,
bandOffsets,
dataType,
false,
false);
! } else if(samplesPerPixel == 4) {
// Interleaved RGBA
int[] bandOffsets = new int[] {0, 1, 2, 3};
- int dataType =
- getDataTypeFromNumBits(maxBitsPerSample, isSigned);
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
--- 1190,1217 ----
greenMask,
blueMask,
alphaMask,
transferType,
alphaPremultiplied);
! } else if(samplesPerPixel == 3 &&
! dataTypeSize == bitsPerSample[0] &&
! bitsPerSample[0] == bitsPerSample[1] &&
! bitsPerSample[1] == bitsPerSample[2]) {
// Interleaved RGB
int[] bandOffsets = new int[] {0, 1, 2};
return ImageTypeSpecifier.createInterleaved(rgb,
bandOffsets,
dataType,
false,
false);
! } else if(samplesPerPixel == 4 &&
! dataTypeSize == bitsPerSample[0] &&
! bitsPerSample[0] == bitsPerSample[1] &&
! bitsPerSample[1] == bitsPerSample[2] &&
! bitsPerSample[2] == bitsPerSample[3]) {
// Interleaved RGBA
int[] bandOffsets = new int[] {0, 1, 2, 3};
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
*** 1194,1218 ****
bandOffsets,
dataType,
true,
alphaPremultiplied);
}
! } else {
// Arbitrary Interleaved.
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
SampleModel sm = createInterleavedSM(dataType,
samplesPerPixel);
! ColorSpace cs = new BogusColorSpace(samplesPerPixel);
ColorModel cm = createComponentCM(cs,
samplesPerPixel,
dataType,
false, // hasAlpha
false); // alphaPremultiplied
return new ImageTypeSpecifier(cm, sm);
}
- }
return null;
}
/**
--- 1220,1252 ----
bandOffsets,
dataType,
true,
alphaPremultiplied);
}
! }
!
// Arbitrary Interleaved.
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
SampleModel sm = createInterleavedSM(dataType,
samplesPerPixel);
! ColorSpace cs;
! if (samplesPerPixel <= 2) {
! cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
! } else if (samplesPerPixel <= 4) {
! cs = rgb;
! } else {
! cs = new BogusColorSpace(samplesPerPixel);
! }
ColorModel cm = createComponentCM(cs,
samplesPerPixel,
+ bitsPerSample,
dataType,
false, // hasAlpha
false); // alphaPremultiplied
return new ImageTypeSpecifier(cm, sm);
}
return null;
}
/**
*** 1283,1292 ****
--- 1317,1334 ----
public void setPlanar(boolean planar) {
this.planar = planar;
}
/**
+ * Sets the index of the planar configuration band to be decoded. This value
+ * is ignored for chunky (interleaved) images.
+ *
+ * @param the index of the planar band to decode
+ */
+ public void setPlanarBand(int planarBand) { this.planarBand = planarBand; }
+
+ /**
* Sets the value of the {@code samplesPerPixel} field.
*
* <p> If this method is called, the {@code beginDecoding}
* method must be called prior to calling any of the decode
* methods.
*** 2486,2496 ****
SampleModel sm = ras.getSampleModel();
// Branch based on whether data are bit-contiguous, i.e.,
// data are packaed as tightly as possible leaving no unused
// bits except at the end of a row.
! if(isDataBufferBitContiguous(sm)) {
// Use byte or float data directly.
if (byteData != null) {
decodeRaw(byteData, dstOffset,
pixelBitStride, scanlineStride);
} else if (floatData != null) {
--- 2528,2538 ----
SampleModel sm = ras.getSampleModel();
// Branch based on whether data are bit-contiguous, i.e.,
// data are packaed as tightly as possible leaving no unused
// bits except at the end of a row.
! if(isDataBufferBitContiguous(sm, bitsPerSample)) {
// Use byte or float data directly.
if (byteData != null) {
decodeRaw(byteData, dstOffset,
pixelBitStride, scanlineStride);
} else if (floatData != null) {
*** 2535,2549 ****
}
}
} else {
// Read discontiguous data into bytes and set the samples
// into the Raster.
! int bpp = getBitsPerPixel(sm);
int bytesPerRow = (bpp*srcWidth + 7)/8;
byte[] buf = new byte[bytesPerRow*srcHeight];
decodeRaw(buf, 0, bpp, bytesPerRow);
! reformatDiscontiguousData(buf, bytesPerRow,
srcWidth, srcHeight,
ras);
}
}
--- 2577,2599 ----
}
}
} else {
// Read discontiguous data into bytes and set the samples
// into the Raster.
! int bpp;
! if (planar) {
! bpp = bitsPerSample[planarBand];
! } else {
! bpp = 0;
! for (int bps : bitsPerSample) {
! bpp += bps;
! }
! }
int bytesPerRow = (bpp*srcWidth + 7)/8;
byte[] buf = new byte[bytesPerRow*srcHeight];
decodeRaw(buf, 0, bpp, bytesPerRow);
! reformatDiscontiguousData(buf, bitsPerSample, bytesPerRow,
srcWidth, srcHeight,
ras);
}
}
< prev index next >