< 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 >