/** * Check required tag is present, and its cardinality and value is correct. * * @param metadata the metadata * @param tagName the name of the mandatory tag * @param cardinality the mandatory cardinality * @param possibleValues the possible tag values * @param ext string extension * @return true, if tag is found */ private boolean checkRequiredTag( IfdTags metadata, String tagName, int cardinality, long[] possibleValues, String ext) { boolean ok = true; int tagid = TiffTags.getTagId(tagName); if (!metadata.containsTagId(tagid)) { validation.addErrorLoc("Missing required tag for TiffEP " + tagName, ext); ok = false; } else if (cardinality != -1 && metadata.get(tagid).getCardinality() != cardinality) { validation.addError( "Invalid cardinality for TiffEP tag " + tagName, ext, metadata.get(tagid).getCardinality()); } else if (cardinality == 1 && possibleValues != null) { long val = metadata.get(tagid).getFirstNumericValue(); boolean contained = false; int i = 0; while (i < possibleValues.length && !contained) { contained = possibleValues[i] == val; i++; } if (!contained) validation.addError("Invalid value for TiffEP tag " + tagName, ext, val); } return ok; }
/** * Validate ifd. * * @param ifd the ifd * @param n the ifd number */ 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); } }
/** * Check a forbidden tag is not present. * * @param metadata the metadata * @param tagName the tag name * @param ext string extension */ private void checkForbiddenTag(IfdTags metadata, String tagName, String ext) { int tagid = TiffTags.getTagId(tagName); if (metadata.containsTagId(tagid)) { validation.addErrorLoc("Forbidden tag for TiffEP found " + tagName, ext); } }
/** * Validate sub ifd. * * @param ifd the subifd * @param n the ifd number */ @SuppressWarnings("unused") @Deprecated private void validateSubIfd(IFD ifd, int n) { boolean thumbnail = ifd.getParent().getImageSize() > ifd.getImageSize(); IfdTags metadata = ifd.getMetadata(); checkRequiredTag(metadata, "ImageLength", 1, "SubIFD" + n); checkRequiredTag(metadata, "ImageWidth", 1, "SubIFD" + n); int spp = -1; if (checkRequiredTag(metadata, "SamplesPerPixel", 1, "SubIFD" + n)) { spp = (int) metadata.get("SamplesPerPixel").getFirstNumericValue(); checkRequiredTag(metadata, "BitsPerSample", spp, "SubIFD" + n); } if (checkRequiredTag(metadata, "Compression", 1, "SubIFD" + n)) { int comp = (int) metadata.get("Compression").getFirstNumericValue(); if (comp == 1) checkForbiddenTag(metadata, "CompressedBitsPerPixel", "IFD" + n); } checkRequiredTag(metadata, "XResolution", 1, "SubIFD" + n); checkRequiredTag(metadata, "YResolution", 1, "SubIFD" + n); checkForbiddenTag(metadata, "SubIFDs", "IFD" + n); if (thumbnail) checkRequiredTag(metadata, "NewSubfileType", 1, new long[] {1}, "SubIFD" + n); else checkRequiredTag(metadata, "NewSubfileType", 1, new long[] {0}, "SubIFD" + n); if (checkRequiredTag( metadata, "PhotometricInterpretation", 1, new long[] {1, 2, 6, 32803, 32767}, "SubIFD" + n)) { int photo = (int) metadata.get("PhotometricInterpretation").getFirstNumericValue(); if (photo != 6) { checkForbiddenTag(metadata, "YCbCrCoefficients", "SubIFD" + n); checkForbiddenTag(metadata, "YCbCrSubSampling", "SubIFD" + n); checkForbiddenTag(metadata, "YCbCrPositioning", "SubIFD" + n); checkForbiddenTag(metadata, "ReferenceBlackWhite", "SubIFD" + n); } if (photo == 2 || photo == 3) { if (spp != 3) { validation.addError("Invalid SampesPerPixel value fo TiffEP", "SubIFD" + n, spp); } } else if (photo == 1 || photo == 32803) { if (spp != 1) { validation.addError("Invalid SampesPerPixel value fo TiffEP", "SubIFD" + n, spp); } if (photo == 32803) { checkRequiredTag(metadata, "CFARepeatPatternDim", 2, "SubIFD" + n); checkRequiredTag(metadata, "CFAPattern", -1, "SubIFD" + n); } } } checkRequiredTag(metadata, "PlanarConfiguration", 1, new long[] {1, 2}, "SubIFD" + n); checkRequiredTag(metadata, "ResolutionUnit", 1, new long[] {1, 2, 3}, "SubIFD" + n); if (!thumbnail) { if (ifd.hasStrips()) { checkRequiredTag(metadata, "StripBYTECount", -1, "SubIFD" + n); checkRequiredTag(metadata, "StripOffsets", -1, "SubIFD" + n); checkRequiredTag(metadata, "RowsPerStrip", 1, "SubIFD" + n); if (ifd.hasTiles()) { validation.addErrorLoc("Image in both strips and tiles", "SubIFD"); } } else if (ifd.hasTiles()) { checkRequiredTag(metadata, "TileLength", 1, "SubIFD" + n); checkRequiredTag(metadata, "TileOffsets", 1, "SubIFD" + n); checkRequiredTag(metadata, "TileWidth", -1, "SubIFD" + n); } } else { checkRequiredTag(metadata, "StripBYTECount", -1, "SubIFD" + n); checkRequiredTag(metadata, "StripOffsets", -1, "SubIFD" + n); checkRequiredTag(metadata, "RowsPerStrip", 1, "SubIFD" + n); checkForbiddenTag(metadata, "TileLength", "SubIFD" + n); checkForbiddenTag(metadata, "TileOffsets", "SubIFD" + n); checkForbiddenTag(metadata, "TileWidth", "SubIFD" + 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, "SubIFD" + n); checkRequiredTag(metadata, "YCbCrSubSampling", 2, "SubIFD" + n); checkRequiredTag(metadata, "YCbCrPositioning", 1, "SubIFD" + n); checkRequiredTag(metadata, "ReferenceBlackWhite", 6, "SubIFD" + 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); }