private void validateIfd(IFD ifd, int n) {
    boolean hasSubIfd = ifd.hasSubIFD();
    boolean thumbnail = hasSubIfd && ifd.getsubIFD().getImageSize() > ifd.getImageSize();
    boolean structureOk = false;

    IfdTags metadata;
    if (!hasSubIfd) {
      validation.addErrorLoc("Missing Sub IFD", "IFD" + n);
      metadata = ifd.getMetadata();
    } else if (!thumbnail) {
      validation.addErrorLoc("Sub IFD image is not bigger than the main image", "IFD" + n);
      metadata = ifd.getMetadata();
    } else {
      metadata = ifd.getsubIFD().getMetadata();
      structureOk = true;
    }

    checkRequiredTag(metadata, "ImageLength", 1, "IFD" + n);
    checkRequiredTag(metadata, "ImageWidth", 1, "IFD" + n);
    int spp = -1;
    if (checkRequiredTag(metadata, "SamplesPerPixel", 1, "IFD" + n)) {
      spp = (int) metadata.get("SamplesPerPixel").getFirstNumericValue();
      checkRequiredTag(metadata, "BitsPerSample", spp, "IFD" + n);
    }
    if (n == 0)
      checkRequiredTag(metadata, "ImageDescription", -1, "IFD" + n);
    if (checkRequiredTag(metadata, "Compression", 1, "IFD" + n)) {
      int comp = (int) metadata.get("Compression").getFirstNumericValue();
      if (comp == 1)
        checkForbiddenTag(metadata, "CompressedBitsPerPixel", "IFD" + n);
    }
    checkRequiredTag(metadata, "XResolution", 1, "IFD" + n);
    checkRequiredTag(metadata, "YResolution", 1, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "Make", -1, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "Model", -1, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "Software", -1, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "Copyright", -1, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "DateTimeOriginal", 20, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "DateTime", 20, "IFD" + n);
    if (n == 0)
      checkRequiredTag(metadata, "TIFFEPStandardID", 4, "IFD" + n);
    if (checkRequiredTag(metadata, "NewSubfileType", 1, new long[] {0, 1}, "IFD" + n)) {
      if (structureOk) {
        checkRequiredTag(ifd.getMetadata(), "NewSubfileType", 1, new long[] {1}, "IFD" + n);
        checkRequiredTag(metadata, "NewSubfileType", 1, new long[] {0}, "IFD" + n);
      }
      int nst = (int) metadata.get("NewSubfileType").getFirstNumericValue();
      if (nst != 0) {
        if (n == 0)
          checkRequiredTag(metadata, "SubIFDs", -1, "IFD" + n);
      }
    }
    if (checkRequiredTag(metadata, "PhotometricInterpretation", 1, new long[]{1, 2, 6, 32803,
        32767}, "IFD" + n)) {
      int photo = (int) metadata.get("PhotometricInterpretation").getFirstNumericValue();
      if (photo != 6) {
        checkForbiddenTag(metadata, "YCbCrCoefficients", "IFD" + n);
        checkForbiddenTag(metadata, "YCbCrSubSampling", "IFD" + n);
        checkForbiddenTag(metadata, "YCbCrPositioning", "IFD" + n);
        checkForbiddenTag(metadata, "ReferenceBlackWhite", "IFD" + n);
      }
      if (photo == 2 || photo == 3) {
        if (spp != 3) {
          validation.addError("Invalid SampesPerPixel value fo TiffEP", "IFD" + n, spp);
        }
      } else if (photo == 1 || photo == 32803) {
        if (spp != 1) {
          validation.addError("Invalid SampesPerPixel value fo TiffEP", "IFD" + n, spp);
        }
        if (photo == 32803) {
          checkRequiredTag(metadata, "CFARepeatPatternDim", 2, "IFD" + n);
          checkRequiredTag(metadata, "CFAPattern", -1, "IFD" + n);
        }
      }
    }
    checkRequiredTag(metadata, "PlanarConfiguration", 1, new long[] {1, 2}, "IFD" + n);
    checkRequiredTag(metadata, "ResolutionUnit", 1, new long[] {1, 2, 3}, "IFD" + n);
    if (metadata.containsTagId(TiffTags.getTagId("Orientation")))
      checkRequiredTag(metadata, "Orientation", 1, new long[] {1, 3, 6, 8, 9}, "IFD" + n);

    if (!thumbnail) {
      if (ifd.hasStrips()) {
        checkRequiredTag(metadata, "StripBYTECount", -1, "IFD" + n);
        checkRequiredTag(metadata, "StripOffsets", -1, "IFD" + n);
        checkRequiredTag(metadata, "RowsPerStrip", 1, "IFD" + n);
        if (ifd.hasTiles()) {
          validation.addErrorLoc("Image in both strips and tiles", "IFD" + n);
        }
      } else if (ifd.hasTiles()) {
        checkRequiredTag(metadata, "TileLength", 1, "IFD" + n);
        checkRequiredTag(metadata, "TileOffsets", 1, "IFD" + n);
        checkRequiredTag(metadata, "TileWidth", -1, "IFD" + n);
      }
    } else {
      checkRequiredTag(metadata, "StripBYTECount", -1, "IFD" + n);
      checkRequiredTag(metadata, "StripOffsets", -1, "IFD" + n);
      checkRequiredTag(metadata, "RowsPerStrip", 1, "IFD" + n);
      checkForbiddenTag(metadata, "TileLength", "IFD" + n);
      checkForbiddenTag(metadata, "TileOffsets", "IFD" + n);
      checkForbiddenTag(metadata, "TileWidth", "IFD" + n);
    }

    int nycbcr = 0;
    if (metadata.containsTagId(TiffTags.getTagId("YCbCrCoefficients")))
      nycbcr++;
    if (metadata.containsTagId(TiffTags.getTagId("YCbCrSubSampling")))
      nycbcr++;
    if (metadata.containsTagId(TiffTags.getTagId("YCbCrPositioning")))
      nycbcr++;
    if (metadata.containsTagId(TiffTags.getTagId("ReferenceBlackWhite")))
      nycbcr++;
    if (nycbcr > 0 && nycbcr != 4) {
      checkRequiredTag(metadata, "YCbCrCoefficients", 3, "IFD" + n);
      checkRequiredTag(metadata, "YCbCrSubSampling", 2, "IFD" + n);
      checkRequiredTag(metadata, "YCbCrPositioning", 1, "IFD" + n);
      checkRequiredTag(metadata, "ReferenceBlackWhite", 6, "IFD" + n);
    }
    if (thumbnail) {
      checkForbiddenTag(metadata, "YCbCrCoefficients", "IFD" + n);
      checkForbiddenTag(metadata, "YCbCrSubSampling", "IFD" + n);
      checkForbiddenTag(metadata, "YCbCrPositioning", "IFD" + n);
      checkForbiddenTag(metadata, "ReferenceBlackWhite", "IFD" + n);
    }

    checkForbiddenTag(metadata, "PrimaryChromaticities", "IFD" + n);
    checkForbiddenTag(metadata, "WhitePoint", "IFD" + n);
    checkForbiddenTag(metadata, "TransferFunction", "IFD" + n);

    if (metadata.containsTagId(TiffTags.getTagId("FocalPlaneResolutionUnit"))) {
      int focal = (int) metadata.get("FocalPlaneResolutionUnit").getFirstNumericValue();
      if (focal < 1 || focal > 5)
        validation.addErrorLoc("Invalid value fot TiffEP tag FocalPlaneResolutionUnit", "IFD" + n);
    }

    if (metadata.containsTagId(TiffTags.getTagId("SensingMethod"))) {
      int sensing = (int) metadata.get("SensingMethod").getFirstNumericValue();
      if (sensing < 0 || sensing > 8)
        validation.addErrorLoc("Invalid value fot TiffEP tag SensingMethod", "IFD" + n);
    }
  }
private void validateIfd ( IFD ifd , int n ) { boolean hasSubIfd = ifd . hasSubIFD ( ) ; boolean thumbnail = hasSubIfd && ifd . getsubIFD ( ) . getImageSize ( ) > ifd . getImageSize ( ) ; boolean structureOk = false ; IfdTags metadata ; if ( ! hasSubIfd ) { validation . addErrorLoc ( "Missing Sub IFD" , "IFD" + n ) ; metadata = ifd . getMetadata ( ) ; } else if ( ! thumbnail ) { validation . addErrorLoc ( "Sub IFD image is not bigger than the main image" , "IFD" + n ) ; metadata = ifd . getMetadata ( ) ; } else { metadata = ifd . getsubIFD ( ) . getMetadata ( ) ; structureOk = true ; } checkRequiredTag ( metadata , "ImageLength" , 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "ImageWidth" , 1 , "IFD" + n ) ; int spp = - 1 ; if ( checkRequiredTag ( metadata , "SamplesPerPixel" , 1 , "IFD" + n ) ) { spp = ( int ) metadata . get ( "SamplesPerPixel" ) . getFirstNumericValue ( ) ; checkRequiredTag ( metadata , "BitsPerSample" , spp , "IFD" + n ) ; } if ( n == 0 ) checkRequiredTag ( metadata , "ImageDescription" , - 1 , "IFD" + n ) ; if ( checkRequiredTag ( metadata , "Compression" , 1 , "IFD" + n ) ) { int comp = ( int ) metadata . get ( "Compression" ) . getFirstNumericValue ( ) ; if ( comp == 1 ) checkForbiddenTag ( metadata , "CompressedBitsPerPixel" , "IFD" + n ) ; } checkRequiredTag ( metadata , "XResolution" , 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "YResolution" , 1 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "Make" , - 1 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "Model" , - 1 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "Software" , - 1 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "Copyright" , - 1 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "DateTimeOriginal" , 20 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "DateTime" , 20 , "IFD" + n ) ; if ( n == 0 ) checkRequiredTag ( metadata , "TIFFEPStandardID" , 4 , "IFD" + n ) ; if ( checkRequiredTag ( metadata , "NewSubfileType" , 1 , new long [ ] { 0 , 1 } , "IFD" + n ) ) { if ( structureOk ) { checkRequiredTag ( ifd . getMetadata ( ) , "NewSubfileType" , 1 , new long [ ] { 1 } , "IFD" + n ) ; checkRequiredTag ( metadata , "NewSubfileType" , 1 , new long [ ] { 0 } , "IFD" + n ) ; } int nst = ( int ) metadata . get ( "NewSubfileType" ) . getFirstNumericValue ( ) ; if ( nst != 0 ) { if ( n == 0 ) checkRequiredTag ( metadata , "SubIFDs" , - 1 , "IFD" + n ) ; } } if ( checkRequiredTag ( metadata , "PhotometricInterpretation" , 1 , new long [ ] { 1 , 2 , 6 , 32803 , 32767 } , "IFD" + n ) ) { int photo = ( int ) metadata . get ( "PhotometricInterpretation" ) . getFirstNumericValue ( ) ; if ( photo != 6 ) { checkForbiddenTag ( metadata , "YCbCrCoefficients" , "IFD" + n ) ; checkForbiddenTag ( metadata , "YCbCrSubSampling" , "IFD" + n ) ; checkForbiddenTag ( metadata , "YCbCrPositioning" , "IFD" + n ) ; checkForbiddenTag ( metadata , "ReferenceBlackWhite" , "IFD" + n ) ; } if ( photo == 2 || photo == 3 ) { if ( spp != 3 ) { validation . addError ( "Invalid SampesPerPixel value fo TiffEP" , "IFD" + n , spp ) ; } } else if ( photo == 1 || photo == 32803 ) { if ( spp != 1 ) { validation . addError ( "Invalid SampesPerPixel value fo TiffEP" , "IFD" + n , spp ) ; } if ( photo == 32803 ) { checkRequiredTag ( metadata , "CFARepeatPatternDim" , 2 , "IFD" + n ) ; checkRequiredTag ( metadata , "CFAPattern" , - 1 , "IFD" + n ) ; } } } checkRequiredTag ( metadata , "PlanarConfiguration" , 1 , new long [ ] { 1 , 2 } , "IFD" + n ) ; checkRequiredTag ( metadata , "ResolutionUnit" , 1 , new long [ ] { 1 , 2 , 3 } , "IFD" + n ) ; if ( metadata . containsTagId ( TiffTags . getTagId ( "Orientation" ) ) ) checkRequiredTag ( metadata , "Orientation" , 1 , new long [ ] { 1 , 3 , 6 , 8 , 9 } , "IFD" + n ) ; if ( ! thumbnail ) { if ( ifd . hasStrips ( ) ) { checkRequiredTag ( metadata , "StripBYTECount" , - 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "StripOffsets" , - 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "RowsPerStrip" , 1 , "IFD" + n ) ; if ( ifd . hasTiles ( ) ) { validation . addErrorLoc ( "Image in both strips and tiles" , "IFD" + n ) ; } } else if ( ifd . hasTiles ( ) ) { checkRequiredTag ( metadata , "TileLength" , 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "TileOffsets" , 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "TileWidth" , - 1 , "IFD" + n ) ; } } else { checkRequiredTag ( metadata , "StripBYTECount" , - 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "StripOffsets" , - 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "RowsPerStrip" , 1 , "IFD" + n ) ; checkForbiddenTag ( metadata , "TileLength" , "IFD" + n ) ; checkForbiddenTag ( metadata , "TileOffsets" , "IFD" + n ) ; checkForbiddenTag ( metadata , "TileWidth" , "IFD" + n ) ; } int nycbcr = 0 ; if ( metadata . containsTagId ( TiffTags . getTagId ( "YCbCrCoefficients" ) ) ) nycbcr ++ ; if ( metadata . containsTagId ( TiffTags . getTagId ( "YCbCrSubSampling" ) ) ) nycbcr ++ ; if ( metadata . containsTagId ( TiffTags . getTagId ( "YCbCrPositioning" ) ) ) nycbcr ++ ; if ( metadata . containsTagId ( TiffTags . getTagId ( "ReferenceBlackWhite" ) ) ) nycbcr ++ ; if ( nycbcr > 0 && nycbcr != 4 ) { checkRequiredTag ( metadata , "YCbCrCoefficients" , 3 , "IFD" + n ) ; checkRequiredTag ( metadata , "YCbCrSubSampling" , 2 , "IFD" + n ) ; checkRequiredTag ( metadata , "YCbCrPositioning" , 1 , "IFD" + n ) ; checkRequiredTag ( metadata , "ReferenceBlackWhite" , 6 , "IFD" + n ) ; } if ( thumbnail ) { checkForbiddenTag ( metadata , "YCbCrCoefficients" , "IFD" + n ) ; checkForbiddenTag ( metadata , "YCbCrSubSampling" , "IFD" + n ) ; checkForbiddenTag ( metadata , "YCbCrPositioning" , "IFD" + n ) ; checkForbiddenTag ( metadata , "ReferenceBlackWhite" , "IFD" + n ) ; } checkForbiddenTag ( metadata , "PrimaryChromaticities" , "IFD" + n ) ; checkForbiddenTag ( metadata , "WhitePoint" , "IFD" + n ) ; checkForbiddenTag ( metadata , "TransferFunction" , "IFD" + n ) ; if ( metadata . containsTagId ( TiffTags . getTagId ( "FocalPlaneResolutionUnit" ) ) ) { int focal = ( int ) metadata . get ( "FocalPlaneResolutionUnit" ) . getFirstNumericValue ( ) ; if ( focal < 1 || focal > 5 ) validation . addErrorLoc ( "Invalid value fot TiffEP tag FocalPlaneResolutionUnit" , "IFD" + n ) ; } if ( metadata . containsTagId ( TiffTags . getTagId ( "SensingMethod" ) ) ) { int sensing = ( int ) metadata . get ( "SensingMethod" ) . getFirstNumericValue ( ) ; if ( sensing < 0 || sensing > 8 ) validation . addErrorLoc ( "Invalid value fot TiffEP tag SensingMethod" , "IFD" + n ) ; } }
Validate ifd.

@param ifd the ifd
@param n the ifd number