/** * Invokes the superclass method and then sets instance variables on the basis of the metadata set * on this decompressor. */ public void beginDecoding() { super.beginDecoding(); if (metadata instanceof TIFFImageMetadata) { TIFFImageMetadata tmetadata = (TIFFImageMetadata) metadata; TIFFField f; f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER); this.fillOrder = f == null ? BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT : f.getAsInt(0); f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION); this.compression = f == null ? BaselineTIFFTagSet.COMPRESSION_CCITT_RLE : f.getAsInt(0); f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_T4_OPTIONS); this.t4Options = f == null ? 0 : f.getAsInt(0); this.oneD = (t4Options & 0x01); // uncompressedMode - haven't dealt with this yet. this.uncompressedMode = ((t4Options & 0x02) >> 1); this.fillBits = ((t4Options & 0x04) >> 2); f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_T6_OPTIONS); this.t6Options = f == null ? 0 : f.getAsInt(0); } else { this.fillOrder = BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT; this.compression = BaselineTIFFTagSet.COMPRESSION_CCITT_RLE; // RLE this.t4Options = 0; // Irrelevant as applies to T.4 only this.oneD = 0; // One-dimensional this.uncompressedMode = 0; // Not uncompressed mode this.fillBits = 0; // No fill bits this.t6Options = 0; } }
private int getPlanarConfiguration() { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION); if (f != null) { int planarConfigurationValue = f.getAsInt(0); if (planarConfigurationValue == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) { // Some writers (e.g. Kofax standard Multi-Page TIFF // Storage Filter v2.01.000; cf. bug 4929147) do not // correctly set the value of this field. Attempt to // ascertain whether the value is correctly Planar. if (getCompression() == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG && imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) != null) { // JPEG interchange format cannot have // PlanarConfiguration value Chunky so reset. processWarningOccurred( "PlanarConfiguration \"Planar\" value inconsistent with JPEGInterchangeFormat; resetting to \"Chunky\"."); planarConfigurationValue = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; } else { TIFFField offsetField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_OFFSETS); if (offsetField == null) { // Tiles offsetField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS); int tw = getTileOrStripWidth(); int th = getTileOrStripHeight(); int tAcross = (getWidth() + tw - 1) / tw; int tDown = (getHeight() + th - 1) / th; int tilesPerImage = tAcross * tDown; long[] offsetArray = offsetField.getAsLongs(); if (offsetArray != null && offsetArray.length == tilesPerImage) { // Length of offsets array is // TilesPerImage for Chunky and // SamplesPerPixel*TilesPerImage for Planar. processWarningOccurred( "PlanarConfiguration \"Planar\" value inconsistent with TileOffsets field value count; resetting to \"Chunky\"."); planarConfigurationValue = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; } } else { // Strips int rowsPerStrip = getTileOrStripHeight(); int stripsPerImage = (getHeight() + rowsPerStrip - 1) / rowsPerStrip; long[] offsetArray = offsetField.getAsLongs(); if (offsetArray != null && offsetArray.length == stripsPerImage) { // Length of offsets array is // StripsPerImage for Chunky and // SamplesPerPixel*StripsPerImage for Planar. processWarningOccurred( "PlanarConfiguration \"Planar\" value inconsistent with StripOffsets field value count; resetting to \"Chunky\"."); planarConfigurationValue = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; } } } } return planarConfigurationValue; } return BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; }
// Returns tile height if image is tiled, else strip height private int getTileOrStripHeight() { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_LENGTH); if (f != null) { return f.getAsInt(0); } f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP); // Default for ROWS_PER_STRIP is 2^32 - 1, i.e., infinity int h = (f == null) ? -1 : f.getAsInt(0); return (h == -1) ? getHeight() : h; }
private long getTileOrStripOffset(int tileIndex) throws IIOException { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_OFFSETS); if (f == null) { f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS); } if (f == null) { f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT); } if (f == null) { throw new IIOException("Missing required strip or tile offsets field."); } return f.getAsLong(tileIndex); }
private int getCompression() { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION); if (f == null) { return BaselineTIFFTagSet.COMPRESSION_NONE; } else { return f.getAsInt(0); } }
public TIFFYCbCrColorConverter(TIFFImageMetadata metadata) { TIFFImageMetadata tmetadata = (TIFFImageMetadata) metadata; TIFFField f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS); if (f != null && f.getCount() == 3) { this.LumaRed = f.getAsFloat(0); this.LumaGreen = f.getAsFloat(1); this.LumaBlue = f.getAsFloat(2); } f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE); if (f != null && f.getCount() == 6) { this.referenceBlackY = f.getAsFloat(0); this.referenceWhiteY = f.getAsFloat(1); this.referenceBlackCb = f.getAsFloat(2); this.referenceWhiteCb = f.getAsFloat(3); this.referenceBlackCr = f.getAsFloat(4); this.referenceWhiteCr = f.getAsFloat(5); } }
private long getTileOrStripByteCount(int tileIndex) throws IOException { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS); if (f == null) { f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS); } if (f == null) { f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); } long tileOrStripByteCount; if (f != null) { tileOrStripByteCount = f.getAsLong(tileIndex); } else { processWarningOccurred( "TIFF directory contains neither StripByteCounts nor TileByteCounts field: attempting to calculate from strip or tile width and height."); // Initialize to number of bytes per strip or tile assuming // no compression. int bitsPerPixel = bitsPerSample[0]; for (int i = 1; i < samplesPerPixel; i++) { bitsPerPixel += bitsPerSample[i]; } int bytesPerRow = (getTileOrStripWidth() * bitsPerPixel + 7) / 8; tileOrStripByteCount = bytesPerRow * getTileOrStripHeight(); // Clamp to end of stream if possible. long streamLength = stream.length(); if (streamLength != -1) { tileOrStripByteCount = Math.min(tileOrStripByteCount, streamLength - getTileOrStripOffset(tileIndex)); } else { processWarningOccurred( "Stream length is unknown: cannot clamp estimated strip or tile byte count to EOF."); } } return tileOrStripByteCount; }
public boolean isImageTiled(int imageIndex) throws IOException { seekToImage(imageIndex); TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_WIDTH); return f != null; }
public Iterator getImageTypes(int imageIndex) throws IIOException { List l; // List of ImageTypeSpecifiers Integer imageIndexInteger = new Integer(imageIndex); if (imageTypeMap.containsKey(imageIndexInteger)) { // Return the cached ITS List. l = (List) imageTypeMap.get(imageIndexInteger); } else { // Create a new ITS List. l = new ArrayList(1); // Create the ITS and cache if for later use so that this method // always returns an Iterator containing the same ITS objects. seekToImage(imageIndex); ImageTypeSpecifier itsRaw = TIFFDecompressor.getRawImageTypeSpecifier( photometricInterpretation, compression, samplesPerPixel, bitsPerSample, sampleFormat, extraSamples, colorMap); // Check for an ICCProfile field. TIFFField iccProfileField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_ICC_PROFILE); // If an ICCProfile field is present change the ImageTypeSpecifier // to use it if the data layout is component type. if (iccProfileField != null && itsRaw.getColorModel() instanceof ComponentColorModel) { // Create a ColorSpace from the profile. byte[] iccProfileValue = iccProfileField.getAsBytes(); ICC_Profile iccProfile = ICC_Profile.getInstance(iccProfileValue); ICC_ColorSpace iccColorSpace = new ICC_ColorSpace(iccProfile); // Get the raw sample and color information. ColorModel cmRaw = itsRaw.getColorModel(); ColorSpace csRaw = cmRaw.getColorSpace(); SampleModel smRaw = itsRaw.getSampleModel(); // Get the number of samples per pixel and the number // of color components. int numBands = smRaw.getNumBands(); int numComponents = iccColorSpace.getNumComponents(); // Replace the ColorModel with the ICC ColorModel if the // numbers of samples and color components are amenable. if (numBands == numComponents || numBands == numComponents + 1) { // Set alpha flags. boolean hasAlpha = numComponents != numBands; boolean isAlphaPre = hasAlpha && cmRaw.isAlphaPremultiplied(); // Create a ColorModel of the same class and with // the same transfer type. ColorModel iccColorModel = new ComponentColorModel( iccColorSpace, cmRaw.getComponentSize(), hasAlpha, isAlphaPre, cmRaw.getTransparency(), cmRaw.getTransferType()); // Prepend the ICC profile-based ITS to the List. The // ColorModel and SampleModel are guaranteed to be // compatible as the old and new ColorModels are both // ComponentColorModels with the same transfer type // and the same number of components. l.add(new ImageTypeSpecifier(iccColorModel, smRaw)); // Append the raw ITS to the List if and only if its // ColorSpace has the same type and number of components // as the ICC ColorSpace. if (csRaw.getType() == iccColorSpace.getType() && csRaw.getNumComponents() == iccColorSpace.getNumComponents()) { l.add(itsRaw); } } else { // ICCProfile not compatible with SampleModel. // Append the raw ITS to the List. l.add(itsRaw); } } else { // No ICCProfile field or raw ColorModel not component. // Append the raw ITS to the List. l.add(itsRaw); } // Cache the ITS List. imageTypeMap.put(imageIndexInteger, l); } return l.iterator(); }
/** * Initializes these instance variables from the image metadata: * * <pre> * compression * width * height * samplesPerPixel * numBands * colorMap * photometricInterpretation * sampleFormat * bitsPerSample * extraSamples * tileOrStripWidth * tileOrStripHeight * </pre> */ private void initializeFromMetadata() { TIFFField f; // Compression f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION); if (f == null) { processWarningOccurred("Compression field is missing; assuming no compression"); compression = BaselineTIFFTagSet.COMPRESSION_NONE; } else { compression = f.getAsInt(0); } // Whether key dimensional information is absent. boolean isMissingDimension = false; // ImageWidth -> width f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH); if (f != null) { this.width = f.getAsInt(0); } else { processWarningOccurred("ImageWidth field is missing."); isMissingDimension = true; } // ImageLength -> height f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH); if (f != null) { this.height = f.getAsInt(0); } else { processWarningOccurred("ImageLength field is missing."); isMissingDimension = true; } // SamplesPerPixel f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL); if (f != null) { samplesPerPixel = f.getAsInt(0); } else { samplesPerPixel = 1; isMissingDimension = true; } // If any dimension is missing and there is a JPEG stream available // get the information from it. int defaultBitDepth = 1; if (isMissingDimension && (f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT)) != null) { Iterator iter = ImageIO.getImageReadersByFormatName("JPEG"); if (iter != null && iter.hasNext()) { ImageReader jreader = (ImageReader) iter.next(); try { stream.mark(); stream.seek(f.getAsLong(0)); jreader.setInput(stream); if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH) == null) { this.width = jreader.getWidth(0); } if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH) == null) { this.height = jreader.getHeight(0); } ImageTypeSpecifier imageType = jreader.getRawImageType(0); if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL) == null) { this.samplesPerPixel = imageType.getSampleModel().getNumBands(); } stream.reset(); defaultBitDepth = imageType.getColorModel().getComponentSize(0); } catch (IOException e) { // Ignore it and proceed: an error will occur later. } jreader.dispose(); } } if (samplesPerPixel < 1) { processWarningOccurred("Samples per pixel < 1!"); } // SamplesPerPixel -> numBands numBands = samplesPerPixel; // ColorMap this.colorMap = null; f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COLOR_MAP); if (f != null) { // Grab color map colorMap = f.getAsChars(); } // PhotometricInterpretation f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION); if (f == null) { if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4 || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) { processWarningOccurred( "PhotometricInterpretation field is missing; " + "assuming WhiteIsZero"); photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO; } else if (this.colorMap != null) { photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR; } else if (samplesPerPixel == 3 || samplesPerPixel == 4) { photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB; } else { processWarningOccurred( "PhotometricInterpretation field is missing; " + "assuming BlackIsZero"); photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO; } } else { photometricInterpretation = f.getAsInt(0); } // SampleFormat boolean replicateFirst = false; int first = -1; f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT); sampleFormat = new int[samplesPerPixel]; replicateFirst = false; if (f == null) { replicateFirst = true; first = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED; } else if (f.getCount() != samplesPerPixel) { replicateFirst = true; first = f.getAsInt(0); } for (int i = 0; i < samplesPerPixel; i++) { sampleFormat[i] = replicateFirst ? first : f.getAsInt(i); if (sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED) { processWarningOccurred("Illegal value for SAMPLE_FORMAT, assuming SAMPLE_FORMAT_UNDEFINED"); sampleFormat[i] = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED; } } // BitsPerSample f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE); this.bitsPerSample = new int[samplesPerPixel]; replicateFirst = false; if (f == null) { replicateFirst = true; first = defaultBitDepth; } else if (f.getCount() != samplesPerPixel) { replicateFirst = true; first = f.getAsInt(0); } for (int i = 0; i < samplesPerPixel; i++) { // Replicate initial value if not enough values provided bitsPerSample[i] = replicateFirst ? first : f.getAsInt(i); if (DEBUG) { System.out.println("bitsPerSample[" + i + "] = " + bitsPerSample[i]); } } // ExtraSamples this.extraSamples = null; f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES); if (f != null) { extraSamples = f.getAsInts(); } // System.out.println("colorMap = " + colorMap); // if (colorMap != null) { // for (int i = 0; i < colorMap.length; i++) { // System.out.println("colorMap[" + i + "] = " + (int)(colorMap[i])); // } // } }
// Returns tile width if image is tiled, else image width private int getTileOrStripWidth() { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_WIDTH); return (f == null) ? getWidth() : f.getAsInt(0); }
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { prepareRead(imageIndex, param); this.theImage = getDestination(param, getImageTypes(imageIndex), width, height); srcXSubsampling = imageReadParam.getSourceXSubsampling(); srcYSubsampling = imageReadParam.getSourceYSubsampling(); Point p = imageReadParam.getDestinationOffset(); dstXOffset = p.x; dstYOffset = p.y; // This could probably be made more efficient... Rectangle srcRegion = new Rectangle(0, 0, 0, 0); Rectangle destRegion = new Rectangle(0, 0, 0, 0); computeRegions(imageReadParam, width, height, theImage, srcRegion, destRegion); // Initial source pixel, taking source region and source // subsamplimg offsets into account sourceXOffset = srcRegion.x; sourceYOffset = srcRegion.y; pixelsToRead = destRegion.width * destRegion.height; pixelsRead = 0; processImageStarted(imageIndex); processImageProgress(0.0f); tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth; tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight; int compression = getCompression(); // Attempt to get decompressor and color converted from the read param TIFFColorConverter colorConverter = null; if (imageReadParam instanceof TIFFImageReadParam) { TIFFImageReadParam tparam = (TIFFImageReadParam) imageReadParam; this.decompressor = tparam.getTIFFDecompressor(); colorConverter = tparam.getColorConverter(); } // If we didn't find one, use a standard decompressor if (this.decompressor == null) { if (compression == BaselineTIFFTagSet.COMPRESSION_NONE) { // Get the fillOrder field. TIFFField fillOrderField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER); // Set the decompressor based on the fill order. if (fillOrderField != null && fillOrderField.getAsInt(0) == 2) { this.decompressor = new TIFFLSBDecompressor(); } else { this.decompressor = new TIFFNullDecompressor(); } } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) { this.decompressor = new TIFFFaxDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4) { this.decompressor = new TIFFFaxDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) { this.decompressor = new TIFFFaxDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_PACKBITS) { if (DEBUG) { System.out.println("Using TIFFPackBitsDecompressor"); } this.decompressor = new TIFFPackBitsDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_LZW) { if (DEBUG) { System.out.println("Using TIFFLZWDecompressor"); } TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR); int predictor = ((predictorField == null) ? BaselineTIFFTagSet.PREDICTOR_NONE : predictorField.getAsInt(0)); this.decompressor = new TIFFLZWDecompressor(predictor); } else if (compression == BaselineTIFFTagSet.COMPRESSION_JPEG) { this.decompressor = new TIFFJPEGDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_ZLIB || compression == BaselineTIFFTagSet.COMPRESSION_DEFLATE) { TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR); int predictor = ((predictorField == null) ? BaselineTIFFTagSet.PREDICTOR_NONE : predictorField.getAsInt(0)); this.decompressor = new TIFFDeflateDecompressor(predictor); } else if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) { TIFFField JPEGProcField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_PROC); if (JPEGProcField == null) { processWarningOccurred( "JPEGProc field missing; assuming baseline sequential JPEG process."); } else if (JPEGProcField.getAsInt(0) != BaselineTIFFTagSet.JPEG_PROC_BASELINE) { throw new IIOException( "Old-style JPEG supported for baseline sequential JPEG process only!"); } this.decompressor = new TIFFOldJPEGDecompressor(); // throw new IIOException("Old-style JPEG not supported!"); } else { throw new IIOException("Unsupported compression type (tag number = " + compression + ")!"); } if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR && compression != BaselineTIFFTagSet.COMPRESSION_JPEG && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) { boolean convertYCbCrToRGB = theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB; TIFFDecompressor wrappedDecompressor = this.decompressor instanceof TIFFNullDecompressor ? null : this.decompressor; this.decompressor = new TIFFYCbCrDecompressor(wrappedDecompressor, convertYCbCrToRGB); } } if (DEBUG) { System.out.println("\nDecompressor class = " + decompressor.getClass().getName() + "\n"); } if (colorConverter == null) { if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB && theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB) { colorConverter = new TIFFCIELabColorConverter(); } else if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR && !(this.decompressor instanceof TIFFYCbCrDecompressor) && compression != BaselineTIFFTagSet.COMPRESSION_JPEG && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) { colorConverter = new TIFFYCbCrColorConverter(imageMetadata); } } decompressor.setReader(this); decompressor.setMetadata(imageMetadata); decompressor.setImage(theImage); decompressor.setPhotometricInterpretation(photometricInterpretation); decompressor.setCompression(compression); decompressor.setSamplesPerPixel(samplesPerPixel); decompressor.setBitsPerSample(bitsPerSample); decompressor.setSampleFormat(sampleFormat); decompressor.setExtraSamples(extraSamples); decompressor.setColorMap(colorMap); decompressor.setColorConverter(colorConverter); decompressor.setSourceXOffset(sourceXOffset); decompressor.setSourceYOffset(sourceYOffset); decompressor.setSubsampleX(srcXSubsampling); decompressor.setSubsampleY(srcYSubsampling); decompressor.setDstXOffset(dstXOffset); decompressor.setDstYOffset(dstYOffset); decompressor.setSourceBands(sourceBands); decompressor.setDestinationBands(destinationBands); // Compute bounds on the tile indices for this source region. int minTileX = TIFFImageWriter.XToTileX(srcRegion.x, 0, tileOrStripWidth); int minTileY = TIFFImageWriter.YToTileY(srcRegion.y, 0, tileOrStripHeight); int maxTileX = TIFFImageWriter.XToTileX(srcRegion.x + srcRegion.width - 1, 0, tileOrStripWidth); int maxTileY = TIFFImageWriter.YToTileY(srcRegion.y + srcRegion.height - 1, 0, tileOrStripHeight); boolean isAbortRequested = false; if (planarConfiguration == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) { decompressor.setPlanar(true); int[] sb = new int[1]; int[] db = new int[1]; for (int tj = minTileY; tj <= maxTileY; tj++) { for (int ti = minTileX; ti <= maxTileX; ti++) { for (int band = 0; band < numBands; band++) { sb[0] = sourceBands[band]; decompressor.setSourceBands(sb); db[0] = destinationBands[band]; decompressor.setDestinationBands(db); // XXX decompressor.beginDecoding(); // The method abortRequested() is synchronized // so check it only once per loop just before // doing any actual decoding. if (abortRequested()) { isAbortRequested = true; break; } decodeTile(ti, tj, band); } if (isAbortRequested) break; reportProgress(); } if (isAbortRequested) break; } } else { // XXX decompressor.beginDecoding(); for (int tj = minTileY; tj <= maxTileY; tj++) { for (int ti = minTileX; ti <= maxTileX; ti++) { // The method abortRequested() is synchronized // so check it only once per loop just before // doing any actual decoding. if (abortRequested()) { isAbortRequested = true; break; } decodeTile(ti, tj, -1); reportProgress(); } if (isAbortRequested) break; } } if (isAbortRequested) { processReadAborted(); } else { processImageComplete(); } return theImage; }