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/TIFFIFD.java
/* * Copyright (c) 2005, 2016, 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.io.EOFException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.imageio.IIOException; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.TIFFDirectory; import javax.imageio.plugins.tiff.TIFFField; import javax.imageio.plugins.tiff.TIFFTag; import javax.imageio.plugins.tiff.TIFFTagSet; public class TIFFIFD extends TIFFDirectory { private static final long MAX_SAMPLES_PER_PIXEL = 0xffff; private static final long MAX_ASCII_SIZE = 0xffff; private long stripOrTileByteCountsPosition = -1; private long stripOrTileOffsetsPosition = -1; private long lastPosition = -1; // // A set of tag numbers corresponding to tags essential to decoding // the image and metadata required to interpret its samples. // private static volatile Set<Integer> essentialTags = null; private static void initializeEssentialTags() { Set<Integer> tags = essentialTags; if (tags == null) { essentialTags = tags = Set.of( BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE, BaselineTIFFTagSet.TAG_COLOR_MAP, BaselineTIFFTagSet.TAG_COMPRESSION, BaselineTIFFTagSet.TAG_EXTRA_SAMPLES, BaselineTIFFTagSet.TAG_FILL_ORDER, BaselineTIFFTagSet.TAG_ICC_PROFILE, BaselineTIFFTagSet.TAG_IMAGE_LENGTH, BaselineTIFFTagSet.TAG_IMAGE_WIDTH, BaselineTIFFTagSet.TAG_JPEG_AC_TABLES, BaselineTIFFTagSet.TAG_JPEG_DC_TABLES, BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT, BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, BaselineTIFFTagSet.TAG_JPEG_PROC, BaselineTIFFTagSet.TAG_JPEG_Q_TABLES, BaselineTIFFTagSet.TAG_JPEG_RESTART_INTERVAL, BaselineTIFFTagSet.TAG_JPEG_TABLES, BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION, BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION, BaselineTIFFTagSet.TAG_PREDICTOR, BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE, BaselineTIFFTagSet.TAG_ROWS_PER_STRIP, BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL, BaselineTIFFTagSet.TAG_SAMPLE_FORMAT, BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS, BaselineTIFFTagSet.TAG_STRIP_OFFSETS, BaselineTIFFTagSet.TAG_T4_OPTIONS, BaselineTIFFTagSet.TAG_T6_OPTIONS, BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS, BaselineTIFFTagSet.TAG_TILE_LENGTH, BaselineTIFFTagSet.TAG_TILE_OFFSETS, BaselineTIFFTagSet.TAG_TILE_WIDTH, BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS, BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING ); } } /** * Converts a {@code TIFFDirectory} to a {@code TIFFIFD}. */ public static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) { if(dir instanceof TIFFIFD) { return (TIFFIFD)dir; } TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()), dir.getParentTag()); TIFFField[] fields = dir.getTIFFFields(); int numFields = fields.length; for(int i = 0; i < numFields; i++) { TIFFField f = fields[i]; TIFFTag tag = f.getTag(); if(tag.isIFDPointer()) { TIFFDirectory subDir = null; if (f.hasDirectory()) { subDir = f.getDirectory(); } else if (f.getData() instanceof TIFFDirectory) { subDir = (TIFFDirectory)f.getData(); } if (subDir != null) { TIFFDirectory subIFD = getDirectoryAsIFD(subDir); f = new TIFFField(tag, f.getType(), (long)f.getCount(), subIFD); } else { f = null; } } if (f != null) { ifd.addTIFFField(f); } } return ifd; } public static TIFFTag getTag(int tagNumber, List<TIFFTagSet> tagSets) { Iterator<TIFFTagSet> iter = tagSets.iterator(); while (iter.hasNext()) { TIFFTagSet tagSet = iter.next(); TIFFTag tag = tagSet.getTag(tagNumber); if (tag != null) { return tag; } } return null; } public static TIFFTag getTag(String tagName, List<TIFFTagSet> tagSets) { Iterator<TIFFTagSet> iter = tagSets.iterator(); while (iter.hasNext()) { TIFFTagSet tagSet = iter.next(); TIFFTag tag = tagSet.getTag(tagName); if (tag != null) { return tag; } } return null; } private static void writeTIFFFieldToStream(TIFFField field, ImageOutputStream stream) throws IOException { int count = field.getCount(); Object data = field.getData(); switch (field.getType()) { case TIFFTag.TIFF_ASCII: for (int i = 0; i < count; i++) { String s = ((String[])data)[i]; int length = s.length(); for (int j = 0; j < length; j++) { stream.writeByte(s.charAt(j) & 0xff); } stream.writeByte(0); } break; case TIFFTag.TIFF_UNDEFINED: case TIFFTag.TIFF_BYTE: case TIFFTag.TIFF_SBYTE: stream.write((byte[])data); break; case TIFFTag.TIFF_SHORT: stream.writeChars((char[])data, 0, ((char[])data).length); break; case TIFFTag.TIFF_SSHORT: stream.writeShorts((short[])data, 0, ((short[])data).length); break; case TIFFTag.TIFF_SLONG: stream.writeInts((int[])data, 0, ((int[])data).length); break; case TIFFTag.TIFF_LONG: for (int i = 0; i < count; i++) { stream.writeInt((int)(((long[])data)[i])); } break; case TIFFTag.TIFF_IFD_POINTER: stream.writeInt(0); // will need to be backpatched break; case TIFFTag.TIFF_FLOAT: stream.writeFloats((float[])data, 0, ((float[])data).length); break; case TIFFTag.TIFF_DOUBLE: stream.writeDoubles((double[])data, 0, ((double[])data).length); break; case TIFFTag.TIFF_SRATIONAL: for (int i = 0; i < count; i++) { stream.writeInt(((int[][])data)[i][0]); stream.writeInt(((int[][])data)[i][1]); } break; case TIFFTag.TIFF_RATIONAL: for (int i = 0; i < count; i++) { long num = ((long[][])data)[i][0]; long den = ((long[][])data)[i][1]; stream.writeInt((int)num); stream.writeInt((int)den); } break; default: // error } } public TIFFIFD(List<TIFFTagSet> tagSets, TIFFTag parentTag) { super(tagSets.toArray(new TIFFTagSet[tagSets.size()]), parentTag); } public TIFFIFD(List<TIFFTagSet> tagSets) { this(tagSets, null); } public List<TIFFTagSet> getTagSetList() { return Arrays.asList(getTagSets()); } /** * Returns an {@code Iterator} over the TIFF fields. The * traversal is in the order of increasing tag number. */ // Note: the sort is guaranteed for low fields by the use of an // array wherein the index corresponds to the tag number and for // the high fields by the use of a TreeMap with tag number keys. public Iterator<TIFFField> iterator() { return Arrays.asList(getTIFFFields()).iterator(); } /** * Read the value of a field. The {@code data} parameter should be * an array of length 1 of Object. * * @param stream the input stream * @param type the type as read from the stream * @param count the count read from the stream * @param data a container for the data * @return the updated count * @throws IOException */ private static int readFieldValue(ImageInputStream stream, int type, int count, Object[] data) throws IOException { Object obj; switch (type) { case TIFFTag.TIFF_BYTE: case TIFFTag.TIFF_SBYTE: case TIFFTag.TIFF_UNDEFINED: case TIFFTag.TIFF_ASCII: byte[] bvalues = new byte[count]; stream.readFully(bvalues, 0, count); if (type == TIFFTag.TIFF_ASCII) { // Can be multiple strings ArrayList<String> v = new ArrayList<>(); boolean inString = false; int prevIndex = 0; for (int index = 0; index <= count; index++) { if (index < count && bvalues[index] != 0) { if (!inString) { // start of string prevIndex = index; inString = true; } } else { // null or special case at end of string if (inString) { // end of string String s = new String(bvalues, prevIndex, index - prevIndex, StandardCharsets.US_ASCII); v.add(s); inString = false; } } } count = v.size(); String[] strings; if (count != 0) { strings = new String[count]; for (int c = 0; c < count; c++) { strings[c] = v.get(c); } } else { // This case has been observed when the value of // 'count' recorded in the field is non-zero but // the value portion contains all nulls. count = 1; strings = new String[]{""}; } obj = strings; } else { obj = bvalues; } break; case TIFFTag.TIFF_SHORT: char[] cvalues = new char[count]; for (int j = 0; j < count; j++) { cvalues[j] = (char) (stream.readUnsignedShort()); } obj = cvalues; break; case TIFFTag.TIFF_LONG: case TIFFTag.TIFF_IFD_POINTER: long[] lvalues = new long[count]; for (int j = 0; j < count; j++) { lvalues[j] = stream.readUnsignedInt(); } obj = lvalues; break; case TIFFTag.TIFF_RATIONAL: long[][] llvalues = new long[count][2]; for (int j = 0; j < count; j++) { llvalues[j][0] = stream.readUnsignedInt(); llvalues[j][1] = stream.readUnsignedInt(); } obj = llvalues; break; case TIFFTag.TIFF_SSHORT: short[] svalues = new short[count]; for (int j = 0; j < count; j++) { svalues[j] = stream.readShort(); } obj = svalues; break; case TIFFTag.TIFF_SLONG: int[] ivalues = new int[count]; for (int j = 0; j < count; j++) { ivalues[j] = stream.readInt(); } obj = ivalues; break; case TIFFTag.TIFF_SRATIONAL: int[][] iivalues = new int[count][2]; for (int j = 0; j < count; j++) { iivalues[j][0] = stream.readInt(); iivalues[j][1] = stream.readInt(); } obj = iivalues; break; case TIFFTag.TIFF_FLOAT: float[] fvalues = new float[count]; for (int j = 0; j < count; j++) { fvalues[j] = stream.readFloat(); } obj = fvalues; break; case TIFFTag.TIFF_DOUBLE: double[] dvalues = new double[count]; for (int j = 0; j < count; j++) { dvalues[j] = stream.readDouble(); } obj = dvalues; break; default: obj = null; break; } data[0] = obj; return count; } // // Class to represent an IFD entry where the actual content is at an offset // in the stream somewhere outside the IFD itself. This occurs when the // value cannot be contained within four bytes. Seeking is required to read // such field values. // private static class TIFFIFDEntry { public final TIFFTag tag; public final int type; public final int count; public final long offset; TIFFIFDEntry(TIFFTag tag, int type, int count, long offset) { this.tag = tag; this.type = type; this.count = count; this.offset = offset; } } // // Retrieve the value of a baseline field as a long. // private long getFieldAsLong(int tagNumber) { TIFFField f = getTIFFField(tagNumber); return f == null ? -1 : f.getAsLong(0); } // // Retrieve the value of a baseline field as an int. // private int getFieldAsInt(int tagNumber) { TIFFField f = getTIFFField(tagNumber); return f == null ? -1 : f.getAsInt(0); } // // Calculate the number of bytes in each strip or tile. This method // is to be used if and only if no fields exist which provide this // information. The parameter must be empty and if the method succeeds // will contain a single element. // private boolean calculateByteCounts(int expectedSize, List<TIFFField> byteCounts) { if (!byteCounts.isEmpty()) { throw new IllegalArgumentException("byteCounts is not empty"); } // must be interleaved if (getFieldAsInt(BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION) == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) { return false; } // must be uncompressed if (getFieldAsInt(BaselineTIFFTagSet.TAG_COMPRESSION) != BaselineTIFFTagSet.COMPRESSION_NONE) { return false; } // must have image dimensions long w = getFieldAsLong(BaselineTIFFTagSet.TAG_IMAGE_WIDTH); if (w < 0) { return false; } long h = getFieldAsLong(BaselineTIFFTagSet.TAG_IMAGE_LENGTH); if (h < 0) { return false; } long tw = getFieldAsLong(BaselineTIFFTagSet.TAG_TILE_WIDTH); if (tw < 0) { tw = w; } long th = getFieldAsLong(BaselineTIFFTagSet.TAG_TILE_LENGTH); if (th < 0) { th = getFieldAsLong(BaselineTIFFTagSet.TAG_ROWS_PER_STRIP); if (th < 0) { th = h; } } int[] bitsPerSample = null; TIFFField f = getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE); if (f != null) { bitsPerSample = f.getAsInts(); } else { int samplesPerPixel = getFieldAsInt(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL); if (samplesPerPixel < 0) { samplesPerPixel = 1; } bitsPerSample = new int[samplesPerPixel]; Arrays.fill(bitsPerSample, 8); } int bitsPerPixel = 0; for (int bps : bitsPerSample) { bitsPerPixel += bps; } int bytesPerRow = (int)(tw*bitsPerPixel + 7)/8; int bytesPerPacket = (int)th*bytesPerRow; long nx = (w + tw - 1)/tw; long ny = (h + th - 1)/th; if (nx*ny != expectedSize) { return false; } boolean isTiled = getTIFFField(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS) != null; int tagNumber; if (isTiled) { tagNumber = BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS; } else { tagNumber = BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS; } TIFFTag t = BaselineTIFFTagSet.getInstance().getTag(tagNumber); f = getTIFFField(tagNumber); if (f != null) { removeTIFFField(tagNumber); } int numPackets = (int)(nx*ny); long[] packetByteCounts = new long[numPackets]; Arrays.fill(packetByteCounts, bytesPerPacket); // if the strip or tile width does not exceed the image width and the // image height is not a multiple of the strip or tile height, then // truncate the estimate of the byte count of the last strip to avoid // reading past the end of the data if (tw <= w && h % th != 0) { int numRowsInLastStrip = (int)(h - (ny - 1)*th); packetByteCounts[numPackets - 1] = numRowsInLastStrip*bytesPerRow; } f = new TIFFField(t, TIFFTag.TIFF_LONG, numPackets, packetByteCounts); addTIFFField(f); byteCounts.add(f); return true; } // // Verify that data pointed to outside of the IFD itself are within the // stream. To be called after all fields have been read and populated. // private void checkFieldOffsets(long streamLength) throws IIOException { if (streamLength < 0) { return; } // StripOffsets List<TIFFField> offsets = new ArrayList<>(); TIFFField f = getTIFFField(BaselineTIFFTagSet.TAG_STRIP_OFFSETS); int count = 0; if (f != null) { count = f.getCount(); offsets.add(f); } // TileOffsets f = getTIFFField(BaselineTIFFTagSet.TAG_TILE_OFFSETS); if (f != null) { int sz = offsets.size(); int newCount = f.getCount(); if (sz > 0 && newCount != count) { throw new IIOException ("StripOffsets count != TileOffsets count"); } if (sz == 0) { count = newCount; } offsets.add(f); } List<TIFFField> byteCounts = new ArrayList<>(); if (offsets.size() > 0) { // StripByteCounts f = getTIFFField(BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS); if (f != null) { if (f.getCount() != count) { throw new IIOException ("StripByteCounts count != number of offsets"); } byteCounts.add(f); } // TileByteCounts f = getTIFFField(BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS); if (f != null) { if (f.getCount() != count) { throw new IIOException ("TileByteCounts count != number of offsets"); } byteCounts.add(f); } if (byteCounts.size() > 0) { for (TIFFField offset : offsets) { for (TIFFField byteCount : byteCounts) { for (int i = 0; i < count; i++) { long dataOffset = offset.getAsLong(i); long dataByteCount = byteCount.getAsLong(i); if (dataOffset + dataByteCount > streamLength) { throw new IIOException ("Data segment out of stream"); } } } } } } // JPEGInterchangeFormat and JPEGInterchangeFormatLength TIFFField jpegOffset = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT); if (jpegOffset != null) { TIFFField jpegLength = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); if (jpegLength != null) { if (jpegOffset.getAsLong(0) + jpegLength.getAsLong(0) > streamLength) { throw new IIOException ("JPEGInterchangeFormat data out of stream"); } } } // Ensure there is at least a data pointer for JPEG interchange format or // both data offsets and byte counts for other compression types. if (jpegOffset == null && (offsets.size() == 0 || byteCounts.size() == 0)) { boolean throwException = true; if (offsets.size() != 0 && byteCounts.size() == 0) { // Attempt to calculate missing byte counts int expectedSize = offsets.get(0).getCount(); throwException = !calculateByteCounts(expectedSize, byteCounts); } if (throwException) { throw new IIOException ("Insufficient data offsets or byte counts"); } } // JPEGQTables - one 64-byte table for each offset. f = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_Q_TABLES); if (f != null) { long[] tableOffsets = f.getAsLongs(); for (long off : tableOffsets) { if (off + 64 > streamLength) { throw new IIOException("JPEGQTables data out of stream"); } } } // JPEGDCTables f = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_DC_TABLES); if (f != null) { long[] tableOffsets = f.getAsLongs(); for (long off : tableOffsets) { if (off + 16 > streamLength) { throw new IIOException("JPEGDCTables data out of stream"); } } } // JPEGACTables f = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_AC_TABLES); if (f != null) { long[] tableOffsets = f.getAsLongs(); for (long off : tableOffsets) { if (off + 16 > streamLength) { throw new IIOException("JPEGACTables data out of stream"); } } } } // Stream position initially at beginning, left at end // if readUnknownTags is false, do not load fields for which // a tag cannot be found in an allowed TagSet. public void initialize(ImageInputStream stream, boolean isPrimaryIFD, boolean ignoreMetadata, boolean readUnknownTags) throws IOException { removeTIFFFields(); long streamLength = stream.length(); boolean haveStreamLength = streamLength != -1; List<TIFFTagSet> tagSetList = getTagSetList(); // Configure essential tag variables if this is the primary IFD and // either all metadata are being ignored, or metadata are not being // ignored but both unknown tags are being ignored and the tag set // list does not contain the baseline tags. boolean ensureEssentialTags = false; TIFFTagSet baselineTagSet = null; if (isPrimaryIFD && (ignoreMetadata || (!readUnknownTags && !tagSetList.contains(BaselineTIFFTagSet.getInstance())))) { ensureEssentialTags = true; initializeEssentialTags(); baselineTagSet = BaselineTIFFTagSet.getInstance(); } List<Object> entries = new ArrayList<>(); Object[] entryData = new Object[1]; // allocate once for later reuse. // Read the IFD entries, loading the field values which are no more than // four bytes long, and storing the 4-byte offsets for the others. int numEntries = stream.readUnsignedShort(); for (int i = 0; i < numEntries; i++) { // Read tag number, value type, and value count. int tagNumber = stream.readUnsignedShort(); int type = stream.readUnsignedShort(); int sizeOfType; try { sizeOfType = TIFFTag.getSizeOfType(type); } catch (IllegalArgumentException ignored) { // Continue with the next IFD entry. stream.skipBytes(4); continue; } long longCount = stream.readUnsignedInt(); // Get the associated TIFFTag. TIFFTag tag = getTag(tagNumber, tagSetList); if (tag == null && ensureEssentialTags && essentialTags.contains(tagNumber)) { tag = baselineTagSet.getTag(tagNumber); } // Ignore non-essential fields, unknown fields unless forcibly // being read, fields with unknown type, and fields // with count out of int range. if((ignoreMetadata && (!ensureEssentialTags || !essentialTags.contains(tagNumber))) || (tag == null && !readUnknownTags) || (tag != null && !tag.isDataTypeOK(type)) || longCount > Integer.MAX_VALUE) { // Skip the value/offset so as to leave the stream // position at the start of the next IFD entry. stream.skipBytes(4); // Continue with the next IFD entry. continue; } int count = (int)longCount; if (tag == null) { tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type, count); } else { int expectedCount = tag.getCount(); if (expectedCount > 0) { // If the tag count is positive then the tag defines a // specific, fixed count that the field must match. if (count != expectedCount) { throw new IIOException("Unexpected count " + count + " for " + tag.getName() + " field"); } } else if (type == TIFFTag.TIFF_ASCII) { // Clamp the size of ASCII fields of unspecified length // to a maximum value. int asciiSize = TIFFTag.getSizeOfType(TIFFTag.TIFF_ASCII); if (count*asciiSize > MAX_ASCII_SIZE) { count = (int)(MAX_ASCII_SIZE/asciiSize); } } } long longSize = longCount*sizeOfType; if (longSize > Integer.MAX_VALUE) { // Continue with the next IFD entry. stream.skipBytes(4); continue; } int size = (int)longSize; if (size > 4 || tag.isIFDPointer()) { // The IFD entry value is a pointer to the actual field value. long offset = stream.readUnsignedInt(); // Check whether the the field value is within the stream. if (haveStreamLength && offset + size > streamLength) { continue; } // Add a TIFFIFDEntry as a placeholder. This avoids a mark, // seek to the data, and a reset. entries.add(new TIFFIFDEntry(tag, type, count, offset)); } else { // The IFD entry value is the actual field value of no more than // four bytes. Object obj = null; try { // Read the field value and update the count. count = readFieldValue(stream, type, count, entryData); obj = entryData[0]; } catch (EOFException eofe) { // The TIFF 6.0 fields have tag numbers less than or equal // to 532 (ReferenceBlackWhite) or equal to 33432 (Copyright). // If there is an error reading a baseline tag, then re-throw // the exception and fail; otherwise continue with the next // field. if (BaselineTIFFTagSet.getInstance().getTag(tagNumber) == null) { throw eofe; } } // If the field value is smaller than four bytes then skip // the remaining, unused bytes. if (size < 4) { stream.skipBytes(4 - size); } // Add the populated TIFFField to the list of entries. entries.add(new TIFFField(tag, type, count, obj)); } } // After reading the IFD entries the stream is positioned at an unsigned // four byte integer containing either the offset of the next IFD or // zero if this is the last IFD. long nextIFDOffset = stream.getStreamPosition(); Object[] fieldData = new Object[1]; for (Object entry : entries) { if (entry instanceof TIFFField) { // Add the populated field directly. addTIFFField((TIFFField)entry); } else { TIFFIFDEntry e = (TIFFIFDEntry)entry; TIFFTag tag = e.tag; int tagNumber = tag.getNumber(); int type = e.type; int count = e.count; stream.seek(e.offset); if (tag.isIFDPointer()) { List<TIFFTagSet> tagSets = new ArrayList<TIFFTagSet>(1); tagSets.add(tag.getTagSet()); TIFFIFD subIFD = new TIFFIFD(tagSets); subIFD.initialize(stream, false, ignoreMetadata, readUnknownTags); TIFFField f = new TIFFField(tag, type, e.offset, subIFD); addTIFFField(f); } else { if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) { this.stripOrTileByteCountsPosition = stream.getStreamPosition(); } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) { this.stripOrTileOffsetsPosition = stream.getStreamPosition(); } Object obj = null; try { count = readFieldValue(stream, type, count, fieldData); obj = fieldData[0]; } catch (EOFException eofe) { // The TIFF 6.0 fields have tag numbers less than or equal // to 532 (ReferenceBlackWhite) or equal to 33432 (Copyright). // If there is an error reading a baseline tag, then re-throw // the exception and fail; otherwise continue with the next // field. if (BaselineTIFFTagSet.getInstance().getTag(tagNumber) == null) { throw eofe; } } if (obj == null) { continue; } TIFFField f = new TIFFField(tag, type, count, obj); addTIFFField(f); } } } if(isPrimaryIFD && haveStreamLength) { checkFieldOffsets(streamLength); } stream.seek(nextIFDOffset); this.lastPosition = stream.getStreamPosition(); } public void writeToStream(ImageOutputStream stream) throws IOException { int numFields = getNumTIFFFields(); stream.writeShort(numFields); long nextSpace = stream.getStreamPosition() + 12*numFields + 4; Iterator<TIFFField> iter = iterator(); while (iter.hasNext()) { TIFFField f = iter.next(); TIFFTag tag = f.getTag(); int type = f.getType(); int count = f.getCount(); // Deal with unknown tags if (type == 0) { type = TIFFTag.TIFF_UNDEFINED; } int size = count*TIFFTag.getSizeOfType(type); if (type == TIFFTag.TIFF_ASCII) { int chars = 0; for (int i = 0; i < count; i++) { chars += f.getAsString(i).length() + 1; } count = chars; size = count; } int tagNumber = f.getTagNumber(); stream.writeShort(tagNumber); stream.writeShort(type); stream.writeInt(count); // Write a dummy value to fill space stream.writeInt(0); stream.mark(); // Mark beginning of next field stream.skipBytes(-4); long pos; if (size > 4 || tag.isIFDPointer()) { // Ensure IFD or value is written on a word boundary nextSpace = (nextSpace + 3) & ~0x3; stream.writeInt((int)nextSpace); stream.seek(nextSpace); pos = nextSpace; if (tag.isIFDPointer() && f.hasDirectory()) { TIFFIFD subIFD = getDirectoryAsIFD(f.getDirectory()); subIFD.writeToStream(stream); nextSpace = subIFD.lastPosition; } else { writeTIFFFieldToStream(f, stream); nextSpace = stream.getStreamPosition(); } } else { pos = stream.getStreamPosition(); writeTIFFFieldToStream(f, stream); } // If we are writing the data for the // StripByteCounts, TileByteCounts, StripOffsets, // TileOffsets, JPEGInterchangeFormat, or // JPEGInterchangeFormatLength fields, record the current stream // position for backpatching if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) { this.stripOrTileByteCountsPosition = pos; } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) { this.stripOrTileOffsetsPosition = pos; } stream.reset(); // Go to marked position of next field } this.lastPosition = nextSpace; } public long getStripOrTileByteCountsPosition() { return stripOrTileByteCountsPosition; } public long getStripOrTileOffsetsPosition() { return stripOrTileOffsetsPosition; } public long getLastPosition() { return lastPosition; } void setPositions(long stripOrTileOffsetsPosition, long stripOrTileByteCountsPosition, long lastPosition) { this.stripOrTileOffsetsPosition = stripOrTileOffsetsPosition; this.stripOrTileByteCountsPosition = stripOrTileByteCountsPosition; this.lastPosition = lastPosition; } /** * Returns a {@code TIFFIFD} wherein all fields from the * {@code BaselineTIFFTagSet} are copied by value and all other * fields copied by reference. */ public TIFFIFD getShallowClone() { // Get the baseline TagSet. TIFFTagSet baselineTagSet = BaselineTIFFTagSet.getInstance(); // If the baseline TagSet is not included just return. List<TIFFTagSet> tagSetList = getTagSetList(); if(!tagSetList.contains(baselineTagSet)) { return this; } // Create a new object. TIFFIFD shallowClone = new TIFFIFD(tagSetList, getParentTag()); // Get the tag numbers in the baseline set. Set<Integer> baselineTagNumbers = baselineTagSet.getTagNumbers(); // Iterate over the fields in this IFD. Iterator<TIFFField> fields = iterator(); while(fields.hasNext()) { // Get the next field. TIFFField field = fields.next(); // Get its tag number. Integer tagNumber = Integer.valueOf(field.getTagNumber()); // Branch based on membership in baseline set. TIFFField fieldClone; if(baselineTagNumbers.contains(tagNumber)) { // Copy by value. Object fieldData = field.getData(); int fieldType = field.getType(); try { switch (fieldType) { case TIFFTag.TIFF_BYTE: case TIFFTag.TIFF_SBYTE: case TIFFTag.TIFF_UNDEFINED: fieldData = ((byte[])fieldData).clone(); break; case TIFFTag.TIFF_ASCII: fieldData = ((String[])fieldData).clone(); break; case TIFFTag.TIFF_SHORT: fieldData = ((char[])fieldData).clone(); break; case TIFFTag.TIFF_LONG: case TIFFTag.TIFF_IFD_POINTER: fieldData = ((long[])fieldData).clone(); break; case TIFFTag.TIFF_RATIONAL: fieldData = ((long[][])fieldData).clone(); break; case TIFFTag.TIFF_SSHORT: fieldData = ((short[])fieldData).clone(); break; case TIFFTag.TIFF_SLONG: fieldData = ((int[])fieldData).clone(); break; case TIFFTag.TIFF_SRATIONAL: fieldData = ((int[][])fieldData).clone(); break; case TIFFTag.TIFF_FLOAT: fieldData = ((float[])fieldData).clone(); break; case TIFFTag.TIFF_DOUBLE: fieldData = ((double[])fieldData).clone(); break; default: // Shouldn't happen but do nothing ... } } catch(Exception e) { // Ignore it and copy by reference ... } fieldClone = new TIFFField(field.getTag(), fieldType, field.getCount(), fieldData); } else { // Copy by reference. fieldClone = field; } // Add the field to the clone. shallowClone.addTIFFField(fieldClone); } // Set positions. shallowClone.setPositions(stripOrTileOffsetsPosition, stripOrTileByteCountsPosition, lastPosition); return shallowClone; } }
⏎ com/sun/imageio/plugins/tiff/TIFFIFD.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, 195060👍, 5💬
Popular Posts:
What Is jaxb-api-2.1.6.jar? Java Architecture for XML Binding (JAXB) is a Java API that allows Java ...
JDK 17 java.desktop.jmod is the JMOD file for JDK 17 Desktop module. JDK 17 Desktop module compiled ...
JDK 11 java.base.jmod is the JMOD file for JDK 11 Base module. JDK 11 Base module compiled class fil...
XOM™ is a new XML object model. It is an open source (LGPL), tree-based API for processing XML with ...
Apache Neethi provides general framework for the programmers to use WS Policy. It is compliant with ...