524 for (long off : tableOffsets) {
525 if (off + 16 > streamLength) {
526 throw new IIOException("JPEGDCTables data out of stream");
527 }
528 }
529 }
530
531 // JPEGACTables
532 f = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_AC_TABLES);
533 if (f != null) {
534 long[] tableOffsets = f.getAsLongs();
535 for (long off : tableOffsets) {
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();
613 if (expectedCount > 0) {
614 // If the tag count is positive then the tag defines a
615 // specific, fixed count that the field must match.
684
685 Object[] fieldData = new Object[1];
686 for (Object entry : entries) {
687 if (entry instanceof TIFFField) {
688 // Add the populated field directly.
689 addTIFFField((TIFFField)entry);
690 } else {
691 TIFFIFDEntry e = (TIFFIFDEntry)entry;
692 TIFFTag tag = e.tag;
693 int tagNumber = tag.getNumber();
694 int type = e.type;
695 int count = e.count;
696
697 stream.seek(e.offset);
698
699 if (tag.isIFDPointer()) {
700 List<TIFFTagSet> tagSets = new ArrayList<TIFFTagSet>(1);
701 tagSets.add(tag.getTagSet());
702 TIFFIFD subIFD = new TIFFIFD(tagSets);
703
704 subIFD.initialize(stream, false, ignoreUnknownFields);
705 TIFFField f = new TIFFField(tag, type, e.offset, subIFD);
706 addTIFFField(f);
707 } else {
708 if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS
709 || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS
710 || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
711 this.stripOrTileByteCountsPosition
712 = stream.getStreamPosition();
713 } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS
714 || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS
715 || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
716 this.stripOrTileOffsetsPosition
717 = stream.getStreamPosition();
718 }
719
720 Object obj = null;
721 try {
722 count = readFieldValue(stream, type, count, fieldData);
723 obj = fieldData[0];
724 } catch (EOFException eofe) {
|
524 for (long off : tableOffsets) {
525 if (off + 16 > streamLength) {
526 throw new IIOException("JPEGDCTables data out of stream");
527 }
528 }
529 }
530
531 // JPEGACTables
532 f = getTIFFField(BaselineTIFFTagSet.TAG_JPEG_AC_TABLES);
533 if (f != null) {
534 long[] tableOffsets = f.getAsLongs();
535 for (long off : tableOffsets) {
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 readUnknownTags is false, 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 ignoreMetadata, boolean readUnknownTags) throws IOException {
548
549 removeTIFFFields();
550
551 long streamLength = stream.length();
552 boolean haveStreamLength = streamLength != -1;
553
554 List<TIFFTagSet> tagSetList = getTagSetList();
555
556 // Configure essential tag variables if this is the primary IFD and
557 // either all metadata are being ignored, or metadata are not being
558 // ignored but both unknown tags are being ignored and the tag set
559 // list does not contain the baseline tags.
560 boolean ensureEssentialTags = false;
561 TIFFTagSet baselineTagSet = null;
562 if (isPrimaryIFD &&
563 (ignoreMetadata ||
564 (!readUnknownTags &&
565 !tagSetList.contains(BaselineTIFFTagSet.getInstance())))) {
566 ensureEssentialTags = true;
567 initializeEssentialTags();
568 baselineTagSet = BaselineTIFFTagSet.getInstance();
569 }
570
571 List<Object> entries = new ArrayList<>();
572 Object[] entryData = new Object[1]; // allocate once for later reuse.
573
574 // Read the IFD entries, loading the field values which are no more than
575 // four bytes long, and storing the 4-byte offsets for the others.
576 int numEntries = stream.readUnsignedShort();
577 for (int i = 0; i < numEntries; i++) {
578 // Read tag number, value type, and value count.
579 int tagNumber = stream.readUnsignedShort();
580 int type = stream.readUnsignedShort();
581 int sizeOfType;
582 try {
583 sizeOfType = TIFFTag.getSizeOfType(type);
584 } catch (IllegalArgumentException ignored) {
585 // Continue with the next IFD entry.
586 stream.skipBytes(4);
587 continue;
588 }
589 long longCount = stream.readUnsignedInt();
590
591 // Get the associated TIFFTag.
592 TIFFTag tag = getTag(tagNumber, tagSetList);
593
594 if (tag == null && ensureEssentialTags
595 && essentialTags.contains(tagNumber)) {
596 tag = baselineTagSet.getTag(tagNumber);
597 }
598
599 // Ignore non-essential fields, unknown fields unless forcibly
600 // being read, fields with unknown type, and fields
601 // with count out of int range.
602 if((ignoreMetadata &&
603 (!ensureEssentialTags || !essentialTags.contains(tagNumber)))
604 || (tag == null && !readUnknownTags)
605 || (tag != null && !tag.isDataTypeOK(type))
606 || longCount > Integer.MAX_VALUE) {
607 // Skip the value/offset so as to leave the stream
608 // position at the start of the next IFD entry.
609 stream.skipBytes(4);
610
611 // Continue with the next IFD entry.
612 continue;
613 }
614
615 int count = (int)longCount;
616
617 if (tag == null) {
618 tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber,
619 1 << type, count);
620 } else {
621 int expectedCount = tag.getCount();
622 if (expectedCount > 0) {
623 // If the tag count is positive then the tag defines a
624 // specific, fixed count that the field must match.
693
694 Object[] fieldData = new Object[1];
695 for (Object entry : entries) {
696 if (entry instanceof TIFFField) {
697 // Add the populated field directly.
698 addTIFFField((TIFFField)entry);
699 } else {
700 TIFFIFDEntry e = (TIFFIFDEntry)entry;
701 TIFFTag tag = e.tag;
702 int tagNumber = tag.getNumber();
703 int type = e.type;
704 int count = e.count;
705
706 stream.seek(e.offset);
707
708 if (tag.isIFDPointer()) {
709 List<TIFFTagSet> tagSets = new ArrayList<TIFFTagSet>(1);
710 tagSets.add(tag.getTagSet());
711 TIFFIFD subIFD = new TIFFIFD(tagSets);
712
713 subIFD.initialize(stream, false, ignoreMetadata,
714 readUnknownTags);
715 TIFFField f = new TIFFField(tag, type, e.offset, subIFD);
716 addTIFFField(f);
717 } else {
718 if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS
719 || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS
720 || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
721 this.stripOrTileByteCountsPosition
722 = stream.getStreamPosition();
723 } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS
724 || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS
725 || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
726 this.stripOrTileOffsetsPosition
727 = stream.getStreamPosition();
728 }
729
730 Object obj = null;
731 try {
732 count = readFieldValue(stream, type, count, fieldData);
733 obj = fieldData[0];
734 } catch (EOFException eofe) {
|