< prev index next >

src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java

Print this page




  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Set;
  35 import javax.imageio.IIOException;
  36 import javax.imageio.stream.ImageInputStream;
  37 import javax.imageio.stream.ImageOutputStream;
  38 import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
  39 import javax.imageio.plugins.tiff.TIFFDirectory;
  40 import javax.imageio.plugins.tiff.TIFFField;
  41 import javax.imageio.plugins.tiff.TIFFTag;
  42 import javax.imageio.plugins.tiff.TIFFTagSet;
  43 
  44 public class TIFFIFD extends TIFFDirectory {
  45     private static final long MAX_SAMPLES_PER_PIXEL = 0xffff;
  46     private static final long MAX_ASCII_SIZE  = 0xffff;
  47 
  48     private long stripOrTileByteCountsPosition = -1;
  49     private long stripOrTileOffsetsPosition = -1;
  50     private long lastPosition = -1;
  51 














































  52 
  53     /**
  54      * Converts a {@code TIFFDirectory} to a {@code TIFFIFD}.
  55      */
  56     public static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) {
  57         if(dir instanceof TIFFIFD) {
  58             return (TIFFIFD)dir;
  59         }
  60 
  61         TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()),
  62                                   dir.getParentTag());
  63         TIFFField[] fields = dir.getTIFFFields();
  64         int numFields = fields.length;
  65         for(int i = 0; i < numFields; i++) {
  66             TIFFField f = fields[i];
  67             TIFFTag tag = f.getTag();
  68             if(tag.isIFDPointer()) {
  69                 TIFFDirectory subDir = null;
  70                 if (f.hasDirectory()) {
  71                     subDir = f.getDirectory();


 490                 if (off + 16 > streamLength) {
 491                     throw new IIOException("JPEGACTables data out of stream");
 492                 }
 493             }
 494         }
 495     }
 496 
 497     // Stream position initially at beginning, left at end
 498     // if ignoreUnknownFields is true, do not load fields for which
 499     // a tag cannot be found in an allowed TagSet.
 500     public void initialize(ImageInputStream stream, boolean isPrimaryIFD,
 501         boolean ignoreUnknownFields) throws IOException {
 502 
 503         removeTIFFFields();
 504 
 505         long streamLength = stream.length();
 506         boolean haveStreamLength = streamLength != -1;
 507 
 508         List<TIFFTagSet> tagSetList = getTagSetList();
 509 









 510         List<Object> entries = new ArrayList<>();
 511         Object[] entryData = new Object[1]; // allocate once for later reuse.
 512 
 513         // Read the IFD entries, loading the field values which are no more than
 514         // four bytes long, and storing the 4-byte offsets for the others.
 515         int numEntries = stream.readUnsignedShort();
 516         for (int i = 0; i < numEntries; i++) {
 517             // Read tag number, value type, and value count.
 518             int tagNumber = stream.readUnsignedShort();
 519             int type = stream.readUnsignedShort();
 520             int sizeOfType;
 521             try {
 522                 sizeOfType = TIFFTag.getSizeOfType(type);
 523             } catch (IllegalArgumentException ignored) {
 524                 // Continue with the next IFD entry.
 525                 stream.skipBytes(4);
 526                 continue;
 527             }
 528             long longCount = stream.readUnsignedInt();
 529 
 530             // Get the associated TIFFTag.
 531             TIFFTag tag = getTag(tagNumber, tagSetList);
 532 





 533             // Ignore unknown fields, fields with unknown type, and fields
 534             // with count out of int range.
 535             if((tag == null && ignoreUnknownFields)
 536                 || (tag != null && !tag.isDataTypeOK(type))
 537                 || longCount > Integer.MAX_VALUE) {
 538                 // Skip the value/offset so as to leave the stream
 539                 // position at the start of the next IFD entry.
 540                 stream.skipBytes(4);
 541 
 542                 // Continue with the next IFD entry.
 543                 continue;
 544             }
 545 
 546             int count = (int)longCount;
 547 
 548             if (tag == null) {
 549                 tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber,
 550                     1 << type, count);
 551             } else {
 552                 int expectedCount = tag.getCount();




  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Set;
  35 import javax.imageio.IIOException;
  36 import javax.imageio.stream.ImageInputStream;
  37 import javax.imageio.stream.ImageOutputStream;
  38 import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
  39 import javax.imageio.plugins.tiff.TIFFDirectory;
  40 import javax.imageio.plugins.tiff.TIFFField;
  41 import javax.imageio.plugins.tiff.TIFFTag;
  42 import javax.imageio.plugins.tiff.TIFFTagSet;
  43 
  44 public class TIFFIFD extends TIFFDirectory {
  45     private static final long MAX_SAMPLES_PER_PIXEL = 0xffff;
  46     private static final long MAX_ASCII_SIZE  = 0xffff;
  47 
  48     private long stripOrTileByteCountsPosition = -1;
  49     private long stripOrTileOffsetsPosition = -1;
  50     private long lastPosition = -1;
  51 
  52     //
  53     // A set of tag numbers corresponding to tags essential to decoding
  54     // the image and metadata required to interpret its samples.
  55     //
  56     private static volatile Set<Integer> essentialTags = null;
  57 
  58     private static void initializeEssentialTags() {
  59         Set<Integer> tags = essentialTags;
  60         if (tags == null) {
  61             essentialTags = tags = Set.of(
  62                 BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE,
  63                 BaselineTIFFTagSet.TAG_COLOR_MAP,
  64                 BaselineTIFFTagSet.TAG_COMPRESSION,
  65                 BaselineTIFFTagSet.TAG_EXTRA_SAMPLES,
  66                 BaselineTIFFTagSet.TAG_FILL_ORDER,
  67                 BaselineTIFFTagSet.TAG_ICC_PROFILE,
  68                 BaselineTIFFTagSet.TAG_IMAGE_LENGTH,
  69                 BaselineTIFFTagSet.TAG_IMAGE_WIDTH,
  70                 BaselineTIFFTagSet.TAG_JPEG_AC_TABLES,
  71                 BaselineTIFFTagSet.TAG_JPEG_DC_TABLES,
  72                 BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT,
  73                 BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
  74                 BaselineTIFFTagSet.TAG_JPEG_PROC,
  75                 BaselineTIFFTagSet.TAG_JPEG_Q_TABLES,
  76                 BaselineTIFFTagSet.TAG_JPEG_RESTART_INTERVAL,
  77                 BaselineTIFFTagSet.TAG_JPEG_TABLES,
  78                 BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION,
  79                 BaselineTIFFTagSet.TAG_PLANAR_CONFIGURATION,
  80                 BaselineTIFFTagSet.TAG_PREDICTOR,
  81                 BaselineTIFFTagSet.TAG_REFERENCE_BLACK_WHITE,
  82                 BaselineTIFFTagSet.TAG_ROWS_PER_STRIP,
  83                 BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL,
  84                 BaselineTIFFTagSet.TAG_SAMPLE_FORMAT,
  85                 BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS,
  86                 BaselineTIFFTagSet.TAG_STRIP_OFFSETS,
  87                 BaselineTIFFTagSet.TAG_T4_OPTIONS,
  88                 BaselineTIFFTagSet.TAG_T6_OPTIONS,
  89                 BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS,
  90                 BaselineTIFFTagSet.TAG_TILE_LENGTH,
  91                 BaselineTIFFTagSet.TAG_TILE_OFFSETS,
  92                 BaselineTIFFTagSet.TAG_TILE_WIDTH,
  93                 BaselineTIFFTagSet.TAG_Y_CB_CR_COEFFICIENTS,
  94                 BaselineTIFFTagSet.TAG_Y_CB_CR_SUBSAMPLING
  95             );
  96         }
  97     }
  98 
  99     /**
 100      * Converts a {@code TIFFDirectory} to a {@code TIFFIFD}.
 101      */
 102     public static TIFFIFD getDirectoryAsIFD(TIFFDirectory dir) {
 103         if(dir instanceof TIFFIFD) {
 104             return (TIFFIFD)dir;
 105         }
 106 
 107         TIFFIFD ifd = new TIFFIFD(Arrays.asList(dir.getTagSets()),
 108                                   dir.getParentTag());
 109         TIFFField[] fields = dir.getTIFFFields();
 110         int numFields = fields.length;
 111         for(int i = 0; i < numFields; i++) {
 112             TIFFField f = fields[i];
 113             TIFFTag tag = f.getTag();
 114             if(tag.isIFDPointer()) {
 115                 TIFFDirectory subDir = null;
 116                 if (f.hasDirectory()) {
 117                     subDir = f.getDirectory();


 536                 if (off + 16 > streamLength) {
 537                     throw new IIOException("JPEGACTables data out of stream");
 538                 }
 539             }
 540         }
 541     }
 542 
 543     // Stream position initially at beginning, left at end
 544     // if ignoreUnknownFields is true, do not load fields for which
 545     // a tag cannot be found in an allowed TagSet.
 546     public void initialize(ImageInputStream stream, boolean isPrimaryIFD,
 547         boolean ignoreUnknownFields) throws IOException {
 548 
 549         removeTIFFFields();
 550 
 551         long streamLength = stream.length();
 552         boolean haveStreamLength = streamLength != -1;
 553 
 554         List<TIFFTagSet> tagSetList = getTagSetList();
 555 
 556         boolean ensureEssentialTags = false;
 557         TIFFTagSet baselineTagSet = null;
 558         if (isPrimaryIFD && ignoreUnknownFields
 559             && !tagSetList.contains(BaselineTIFFTagSet.getInstance())) {
 560             ensureEssentialTags = true;
 561             initializeEssentialTags();
 562             baselineTagSet = BaselineTIFFTagSet.getInstance();
 563         }
 564 
 565         List<Object> entries = new ArrayList<>();
 566         Object[] entryData = new Object[1]; // allocate once for later reuse.
 567 
 568         // Read the IFD entries, loading the field values which are no more than
 569         // four bytes long, and storing the 4-byte offsets for the others.
 570         int numEntries = stream.readUnsignedShort();
 571         for (int i = 0; i < numEntries; i++) {
 572             // Read tag number, value type, and value count.
 573             int tagNumber = stream.readUnsignedShort();
 574             int type = stream.readUnsignedShort();
 575             int sizeOfType;
 576             try {
 577                 sizeOfType = TIFFTag.getSizeOfType(type);
 578             } catch (IllegalArgumentException ignored) {
 579                 // Continue with the next IFD entry.
 580                 stream.skipBytes(4);
 581                 continue;
 582             }
 583             long longCount = stream.readUnsignedInt();
 584 
 585             // Get the associated TIFFTag.
 586             TIFFTag tag = getTag(tagNumber, tagSetList);
 587 
 588             if (tag == null && ensureEssentialTags
 589                 && essentialTags.contains(tagNumber)) {
 590                 tag = baselineTagSet.getTag(tagNumber);
 591             }
 592 
 593             // Ignore unknown fields, fields with unknown type, and fields
 594             // with count out of int range.
 595             if((tag == null && ignoreUnknownFields)
 596                 || (tag != null && !tag.isDataTypeOK(type))
 597                 || longCount > Integer.MAX_VALUE) {
 598                 // Skip the value/offset so as to leave the stream
 599                 // position at the start of the next IFD entry.
 600                 stream.skipBytes(4);
 601 
 602                 // Continue with the next IFD entry.
 603                 continue;
 604             }
 605 
 606             int count = (int)longCount;
 607 
 608             if (tag == null) {
 609                 tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber,
 610                     1 << type, count);
 611             } else {
 612                 int expectedCount = tag.getCount();


< prev index next >