Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
JDK 11 java.desktop.jmod - Desktop Module
JDK 11 java.desktop.jmod is the JMOD file for JDK 11 Desktop module.
JDK 11 Desktop module compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\java.desktop.jmod.
JDK 11 Desktop module compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 Desktop module source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\java.desktop.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ com/sun/imageio/plugins/tiff/TIFFImageReader.java
/* * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.imageio.plugins.tiff; import java.awt.Point; import java.awt.Rectangle; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.io.EOFException; import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.ImageReadParam; import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOMetadata; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; import org.w3c.dom.Node; import com.sun.imageio.plugins.common.ImageUtil; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.TIFFField; import javax.imageio.plugins.tiff.TIFFImageReadParam; import javax.imageio.plugins.tiff.TIFFTagSet; public class TIFFImageReader extends ImageReader { // A somewhat arbitrary upper bound on SamplesPerPixel. Hyperspectral // images as of this writing appear to be under 300 bands so this should // account for those cases should they arise. private static final int SAMPLES_PER_PIXEL_MAX = 1024; // In baseline TIFF the largest data types are 64-bit long and double. private static final int BITS_PER_SAMPLE_MAX = 64; // The current ImageInputStream source. private ImageInputStream stream = null; // True if the file header has been read. private boolean gotHeader = false; private ImageReadParam imageReadParam = getDefaultReadParam(); // Stream metadata, or null. private TIFFStreamMetadata streamMetadata = null; // The current image index. private int currIndex = -1; // Metadata for image at 'currIndex', or null. private TIFFImageMetadata imageMetadata = null; // A {@code List} of {@code Long}s indicating the stream // positions of the start of the IFD for each image. Entries // are added as needed. private List<Long> imageStartPosition = new ArrayList<Long>(); // The number of images in the stream, if known, otherwise -1. private int numImages = -1; // The ImageTypeSpecifiers of the images in the stream. // Contains a map of Integers to Lists. private HashMap<Integer, List<ImageTypeSpecifier>> imageTypeMap = new HashMap<Integer, List<ImageTypeSpecifier>>(); private BufferedImage theImage = null; private int width = -1; private int height = -1; private int numBands = -1; private int tileOrStripWidth = -1, tileOrStripHeight = -1; private int planarConfiguration = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; private int compression; private int photometricInterpretation; private int samplesPerPixel; private int[] sampleFormat; private int[] bitsPerSample; private int[] extraSamples; private char[] colorMap; private int sourceXOffset; private int sourceYOffset; private int srcXSubsampling; private int srcYSubsampling; private int dstWidth; private int dstHeight; private int dstMinX; private int dstMinY; private int dstXOffset; private int dstYOffset; private int tilesAcross; private int tilesDown; private int pixelsRead; private int pixelsToRead; public TIFFImageReader(ImageReaderSpi originatingProvider) { super(originatingProvider); } public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) { super.setInput(input, seekForwardOnly, ignoreMetadata); // Clear all local values based on the previous stream contents. resetLocal(); if (input != null) { if (!(input instanceof ImageInputStream)) { throw new IllegalArgumentException("input not an ImageInputStream!"); } this.stream = (ImageInputStream) input; } else { this.stream = null; } } // Do not seek to the beginning of the stream so as to allow users to // point us at an IFD within some other file format private void readHeader() throws IIOException { if (gotHeader) { return; } if (stream == null) { throw new IllegalStateException("Input not set!"); } // Create an object to store the stream metadata this.streamMetadata = new TIFFStreamMetadata(); try { int byteOrder = stream.readUnsignedShort(); if (byteOrder == 0x4d4d) { streamMetadata.byteOrder = ByteOrder.BIG_ENDIAN; stream.setByteOrder(ByteOrder.BIG_ENDIAN); } else if (byteOrder == 0x4949) { streamMetadata.byteOrder = ByteOrder.LITTLE_ENDIAN; stream.setByteOrder(ByteOrder.LITTLE_ENDIAN); } else { processWarningOccurred( "Bad byte order in header, assuming little-endian"); streamMetadata.byteOrder = ByteOrder.LITTLE_ENDIAN; stream.setByteOrder(ByteOrder.LITTLE_ENDIAN); } int magic = stream.readUnsignedShort(); if (magic != 42) { processWarningOccurred( "Bad magic number in header, continuing"); } // Seek to start of first IFD long offset = stream.readUnsignedInt(); stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); } catch (IOException e) { throw new IIOException("I/O error reading header!", e); } gotHeader = true; } private int locateImage(int imageIndex) throws IIOException { readHeader(); // Find closest known index int index = Math.min(imageIndex, imageStartPosition.size() - 1); try { // Seek to that position Long l = imageStartPosition.get(index); stream.seek(l.longValue()); // Skip IFDs until at desired index or last image found while (index < imageIndex) { int count = stream.readUnsignedShort(); // If zero-entry IFD, decrement the index and exit the loop if (count == 0) { imageIndex = index > 0 ? index - 1 : 0; break; } stream.skipBytes(12 * count); long offset = stream.readUnsignedInt(); if (offset == 0) { return index; } stream.seek(offset); imageStartPosition.add(Long.valueOf(offset)); ++index; } } catch (EOFException eofe) { forwardWarningMessage("Ignored " + eofe); // Ran off the end of stream: decrement index imageIndex = index > 0 ? index - 1 : 0; } catch (IOException ioe) { throw new IIOException("Couldn't seek!", ioe); } if (currIndex != imageIndex) { imageMetadata = null; } currIndex = imageIndex; return imageIndex; } public int getNumImages(boolean allowSearch) throws IOException { if (stream == null) { throw new IllegalStateException("Input not set!"); } if (seekForwardOnly && allowSearch) { throw new IllegalStateException("seekForwardOnly and allowSearch can't both be true!"); } if (numImages > 0) { return numImages; } if (allowSearch) { this.numImages = locateImage(Integer.MAX_VALUE) + 1; } return numImages; } public IIOMetadata getStreamMetadata() throws IIOException { readHeader(); return streamMetadata; } // Throw an IndexOutOfBoundsException if index < minIndex, // and bump minIndex if required. private void checkIndex(int imageIndex) { if (imageIndex < minIndex) { throw new IndexOutOfBoundsException("imageIndex < minIndex!"); } if (seekForwardOnly) { minIndex = imageIndex; } } // Verify that imageIndex is in bounds, find the image IFD, read the // image metadata, initialize instance variables from the metadata. private void seekToImage(int imageIndex) throws IIOException { checkIndex(imageIndex); int index = locateImage(imageIndex); if (index != imageIndex) { throw new IndexOutOfBoundsException("imageIndex out of bounds!"); } readMetadata(); initializeFromMetadata(); } // Stream must be positioned at start of IFD for 'currIndex' private void readMetadata() throws IIOException { if (stream == null) { throw new IllegalStateException("Input not set!"); } if (imageMetadata != null) { return; } try { // Create an object to store the image metadata List<TIFFTagSet> tagSets; boolean readUnknownTags = false; if (imageReadParam instanceof TIFFImageReadParam) { TIFFImageReadParam tp = (TIFFImageReadParam)imageReadParam; tagSets = tp.getAllowedTagSets(); readUnknownTags = tp.getReadUnknownTags(); } else { tagSets = new ArrayList<TIFFTagSet>(1); tagSets.add(BaselineTIFFTagSet.getInstance()); } this.imageMetadata = new TIFFImageMetadata(tagSets); imageMetadata.initializeFromStream(stream, ignoreMetadata, readUnknownTags); } catch (IIOException iioe) { throw iioe; } catch (IOException ioe) { throw new IIOException("I/O error reading image metadata!", ioe); } } private int getWidth() { return this.width; } private int getHeight() { return this.height; } // 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); } // 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 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; } 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 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; } private int getCompression() { TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION); if (f == null) { return BaselineTIFFTagSet.COMPRESSION_NONE; } else { return f.getAsInt(0); } } public int getWidth(int imageIndex) throws IOException { seekToImage(imageIndex); return getWidth(); } public int getHeight(int imageIndex) throws IOException { seekToImage(imageIndex); return getHeight(); } /** * 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() throws IIOException { 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<ImageReader> iter = ImageIO.getImageReadersByFormatName("JPEG"); if (iter != null && iter.hasNext()) { ImageReader jreader = 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 != null ? imageType.getSampleModel().getNumBands() : 3; } stream.reset(); defaultBitDepth = imageType != null ? imageType.getColorModel().getComponentSize(0) : 8; } catch (IOException e) { // Ignore it and proceed: an error will occur later. } jreader.dispose(); } } if (samplesPerPixel < 1) { throw new IIOException("Samples per pixel < 1!"); } else if (samplesPerPixel > SAMPLES_PER_PIXEL_MAX) { throw new IIOException ("Samples per pixel (" + samplesPerPixel + ") greater than allowed maximum (" + SAMPLES_PER_PIXEL_MAX + ")"); } // 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 (bitsPerSample[i] > BITS_PER_SAMPLE_MAX) { throw new IIOException ("Bits per sample (" + bitsPerSample[i] + ") greater than allowed maximum (" + BITS_PER_SAMPLE_MAX + ")"); } } // ExtraSamples this.extraSamples = null; f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES); if (f != null) { extraSamples = f.getAsInts(); } } public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IIOException { List<ImageTypeSpecifier> l; // List of ImageTypeSpecifiers Integer imageIndexInteger = Integer.valueOf(imageIndex); if (imageTypeMap.containsKey(imageIndexInteger)) { // Return the cached ITS List. l = imageTypeMap.get(imageIndexInteger); } else { // Create a new ITS List. l = new ArrayList<ImageTypeSpecifier>(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) { // Get the raw sample and color information. ColorModel cmRaw = itsRaw.getColorModel(); ColorSpace csRaw = cmRaw.getColorSpace(); SampleModel smRaw = itsRaw.getSampleModel(); ColorSpace iccColorSpace = null; try { // Create a ColorSpace from the profile. byte[] iccProfileValue = iccProfileField.getAsBytes(); ICC_Profile iccProfile = ICC_Profile.getInstance(iccProfileValue); iccColorSpace = new ICC_ColorSpace(iccProfile); // Workaround for JDK-8145241: test a conversion and fall // back to a standard ColorSpace if it fails. This // workaround could be removed if JDK-8145241 is fixed. float[] rgb = iccColorSpace.toRGB(new float[] {1.0F, 1.0F, 1.0F}); } catch (Exception iccProfileException) { processWarningOccurred("Superseding bad ICC profile: " + iccProfileException.getMessage()); if (iccColorSpace != null) { switch (iccColorSpace.getType()) { case ColorSpace.TYPE_GRAY: iccColorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY); break; case ColorSpace.TYPE_RGB: iccColorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); break; default: iccColorSpace = csRaw; break; } } else { iccColorSpace = csRaw; } } // 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(); } public IIOMetadata getImageMetadata(int imageIndex) throws IIOException { seekToImage(imageIndex); TIFFImageMetadata im = new TIFFImageMetadata(imageMetadata.getRootIFD().getTagSetList()); Node root = imageMetadata.getAsTree(TIFFImageMetadata.NATIVE_METADATA_FORMAT_NAME); im.setFromTree(TIFFImageMetadata.NATIVE_METADATA_FORMAT_NAME, root); return im; } public IIOMetadata getStreamMetadata(int imageIndex) throws IIOException { readHeader(); TIFFStreamMetadata sm = new TIFFStreamMetadata(); Node root = sm.getAsTree(TIFFStreamMetadata.NATIVE_METADATA_FORMAT_NAME); sm.setFromTree(TIFFStreamMetadata.NATIVE_METADATA_FORMAT_NAME, root); return sm; } public boolean isRandomAccessEasy(int imageIndex) throws IOException { if (currIndex != -1) { seekToImage(currIndex); return getCompression() == BaselineTIFFTagSet.COMPRESSION_NONE; } else { return false; } } // Thumbnails public boolean readSupportsThumbnails() { return false; } public boolean hasThumbnails(int imageIndex) { return false; } public int getNumThumbnails(int imageIndex) throws IOException { return 0; } public ImageReadParam getDefaultReadParam() { return new TIFFImageReadParam(); } public boolean isImageTiled(int imageIndex) throws IOException { seekToImage(imageIndex); TIFFField f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_TILE_WIDTH); return f != null; } public int getTileWidth(int imageIndex) throws IOException { seekToImage(imageIndex); return getTileOrStripWidth(); } public int getTileHeight(int imageIndex) throws IOException { seekToImage(imageIndex); return getTileOrStripHeight(); } public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException { int w = getWidth(imageIndex); int h = getHeight(imageIndex); int tw = getTileWidth(imageIndex); int th = getTileHeight(imageIndex); int x = tw * tileX; int y = th * tileY; if (tileX < 0 || tileY < 0 || x >= w || y >= h) { throw new IllegalArgumentException("Tile indices are out of bounds!"); } if (x + tw > w) { tw = w - x; } if (y + th > h) { th = h - y; } ImageReadParam param = getDefaultReadParam(); Rectangle tileRect = new Rectangle(x, y, tw, th); param.setSourceRegion(tileRect); return read(imageIndex, param); } public boolean canReadRaster() { return false; } public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException { throw new UnsupportedOperationException(); } private int[] sourceBands; private int[] destinationBands; private TIFFDecompressor decompressor; // floor(num/den) private static int ifloor(int num, int den) { if (num < 0) { num -= den - 1; } return num / den; } // ceil(num/den) private static int iceil(int num, int den) { if (num > 0) { num += den - 1; } return num / den; } private void prepareRead(int imageIndex, ImageReadParam param) throws IOException { if (stream == null) { throw new IllegalStateException("Input not set!"); } // A null ImageReadParam means we use the default if (param == null) { param = getDefaultReadParam(); } this.imageReadParam = param; seekToImage(imageIndex); this.tileOrStripWidth = getTileOrStripWidth(); this.tileOrStripHeight = getTileOrStripHeight(); this.planarConfiguration = getPlanarConfiguration(); this.sourceBands = param.getSourceBands(); if (sourceBands == null) { sourceBands = new int[numBands]; for (int i = 0; i < numBands; i++) { sourceBands[i] = i; } } // Initialize the destination image Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex); ImageTypeSpecifier theImageType = ImageUtil.getDestinationType(param, imageTypes); int destNumBands = theImageType.getSampleModel().getNumBands(); this.destinationBands = param.getDestinationBands(); if (destinationBands == null) { destinationBands = new int[destNumBands]; for (int i = 0; i < destNumBands; i++) { destinationBands[i] = i; } } if (sourceBands.length != destinationBands.length) { throw new IllegalArgumentException( "sourceBands.length != destinationBands.length"); } for (int i = 0; i < sourceBands.length; i++) { int sb = sourceBands[i]; if (sb < 0 || sb >= numBands) { throw new IllegalArgumentException( "Source band out of range!"); } int db = destinationBands[i]; if (db < 0 || db >= destNumBands) { throw new IllegalArgumentException( "Destination band out of range!"); } } } public RenderedImage readAsRenderedImage(int imageIndex, ImageReadParam param) throws IOException { prepareRead(imageIndex, param); return new TIFFRenderedImage(this, imageIndex, imageReadParam, width, height); } private void decodeTile(int ti, int tj, int band) throws IOException { // Compute the region covered by the strip or tile Rectangle tileRect = new Rectangle(ti * tileOrStripWidth, tj * tileOrStripHeight, tileOrStripWidth, tileOrStripHeight); // Clip against the image bounds if the image is not tiled. If it // is tiled, the tile may legally extend beyond the image bounds. if (!isImageTiled(currIndex)) { tileRect = tileRect.intersection(new Rectangle(0, 0, width, height)); } // Return if the intersection is empty. if (tileRect.width <= 0 || tileRect.height <= 0) { return; } int srcMinX = tileRect.x; int srcMinY = tileRect.y; int srcWidth = tileRect.width; int srcHeight = tileRect.height; // Determine dest region that can be derived from the // source region dstMinX = iceil(srcMinX - sourceXOffset, srcXSubsampling); int dstMaxX = ifloor(srcMinX + srcWidth - 1 - sourceXOffset, srcXSubsampling); dstMinY = iceil(srcMinY - sourceYOffset, srcYSubsampling); int dstMaxY = ifloor(srcMinY + srcHeight - 1 - sourceYOffset, srcYSubsampling); dstWidth = dstMaxX - dstMinX + 1; dstHeight = dstMaxY - dstMinY + 1; dstMinX += dstXOffset; dstMinY += dstYOffset; // Clip against image bounds Rectangle dstRect = new Rectangle(dstMinX, dstMinY, dstWidth, dstHeight); dstRect = dstRect.intersection(theImage.getRaster().getBounds()); dstMinX = dstRect.x; dstMinY = dstRect.y; dstWidth = dstRect.width; dstHeight = dstRect.height; if (dstWidth <= 0 || dstHeight <= 0) { return; } // Backwards map dest region to source to determine // active source region int activeSrcMinX = (dstMinX - dstXOffset) * srcXSubsampling + sourceXOffset; int sxmax = (dstMinX + dstWidth - 1 - dstXOffset) * srcXSubsampling + sourceXOffset; int activeSrcWidth = sxmax - activeSrcMinX + 1; int activeSrcMinY = (dstMinY - dstYOffset) * srcYSubsampling + sourceYOffset; int symax = (dstMinY + dstHeight - 1 - dstYOffset) * srcYSubsampling + sourceYOffset; int activeSrcHeight = symax - activeSrcMinY + 1; decompressor.setSrcMinX(srcMinX); decompressor.setSrcMinY(srcMinY); decompressor.setSrcWidth(srcWidth); decompressor.setSrcHeight(srcHeight); decompressor.setDstMinX(dstMinX); decompressor.setDstMinY(dstMinY); decompressor.setDstWidth(dstWidth); decompressor.setDstHeight(dstHeight); decompressor.setActiveSrcMinX(activeSrcMinX); decompressor.setActiveSrcMinY(activeSrcMinY); decompressor.setActiveSrcWidth(activeSrcWidth); decompressor.setActiveSrcHeight(activeSrcHeight); int tileIndex = tj * tilesAcross + ti; if (planarConfiguration == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) { tileIndex += band * tilesAcross * tilesDown; } long offset = getTileOrStripOffset(tileIndex); long byteCount = getTileOrStripByteCount(tileIndex); decompressor.setPlanarBand(band); decompressor.setStream(stream); decompressor.setOffset(offset); decompressor.setByteCount((int) byteCount); decompressor.beginDecoding(); stream.mark(); decompressor.decode(); stream.reset(); } private void reportProgress() { // Report image progress/update to listeners after each tile pixelsRead += dstWidth * dstHeight; processImageProgress(100.0f * pixelsRead / pixelsToRead); processImageUpdate(theImage, dstMinX, dstMinY, dstWidth, dstHeight, 1, 1, destinationBands); } 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; clearAbortRequest(); processImageStarted(imageIndex); if (abortRequested()) { processReadAborted(); return theImage; } tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth; tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight; int compression = getCompression(); // Set the decompressor 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) { this.decompressor = new TIFFPackBitsDecompressor(); } else if (compression == BaselineTIFFTagSet.COMPRESSION_LZW) { TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR); int predictor = ((predictorField == null) ? BaselineTIFFTagSet.PREDICTOR_NONE : predictorField.getAsInt(0)); TIFFField fillOrderField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER); int fillOrder = ((fillOrderField == null) ? BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT : fillOrderField.getAsInt(0)); this.decompressor = new TIFFLZWDecompressor(predictor, fillOrder); } 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 value = " + 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); } TIFFColorConverter 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); 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); decodeTile(ti, tj, band); } reportProgress(); if (abortRequested()) { processReadAborted(); return theImage; } } } } else { for (int tj = minTileY; tj <= maxTileY; tj++) { for (int ti = minTileX; ti <= maxTileX; ti++) { decodeTile(ti, tj, -1); reportProgress(); if (abortRequested()) { processReadAborted(); return theImage; } } } } processImageComplete(); return theImage; } public void reset() { super.reset(); resetLocal(); } protected void resetLocal() { stream = null; gotHeader = false; imageReadParam = getDefaultReadParam(); streamMetadata = null; currIndex = -1; imageMetadata = null; imageStartPosition = new ArrayList<Long>(); numImages = -1; imageTypeMap = new HashMap<Integer, List<ImageTypeSpecifier>>(); width = -1; height = -1; numBands = -1; tileOrStripWidth = -1; tileOrStripHeight = -1; planarConfiguration = BaselineTIFFTagSet.PLANAR_CONFIGURATION_CHUNKY; } /** * Package scope method to allow decompressors, for example, to emit warning * messages. */ void forwardWarningMessage(String warning) { processWarningOccurred(warning); } }
⏎ com/sun/imageio/plugins/tiff/TIFFImageReader.java
Or download all of them as a single archive file:
File name: java.desktop-11.0.1-src.zip File size: 7974380 bytes Release date: 2018-11-04 Download
⇒ JDK 11 java.instrument.jmod - Instrument Module
2022-08-06, 160181👍, 5💬
Popular Posts:
Guava is a suite of core and expanded libraries that include utility classes, google's collections, ...
How to read XML document from socket connections with the socket\DelayedInput.java provided in the A...
What is the sax\Counter.java provided in the Apache Xerces package? I have Apache Xerces 2.11.0 inst...
JSP(tm) Standard Tag Library 1.1 implementation - Jakarta Taglibs hosts the Standard Taglib 1.1, an ...
How to download and install ojdbc11.jar for Oracle 21c? ojdbc11.jar for Oracle 21c is a Java JDBC Dr...