All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.easyinnova.tiff.profiles.BaselineProfile Maven / Gradle / Ivy

There is a newer version: 1.9.7
Show newest version
/**
 * 

BaselineProfile.java

*

* This program is free software: you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version; or, at your choice, under the terms of the * Mozilla Public License, v. 2.0. SPDX GPL-3.0+ or MPL-2.0+. *

*

* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License and the Mozilla Public License for more details. *

*

* You should have received a copy of the GNU General Public License and the Mozilla Public License * along with this program. If not, see http://www.gnu.org/licenses/ and at http://mozilla.org/MPL/2.0 . *

*

* NB: for the © statement, include Easy Innova SL or other company/Person contributing the code. *

*

* © 2015 Easy Innova, SL *

* * @author Víctor Muñoz Solà * @version 1.0 * @since 4/6/2015 * */ package com.easyinnova.tiff.profiles; import com.easyinnova.tiff.model.IfdTags; import com.easyinnova.tiff.model.ReadTagsIOException; import com.easyinnova.tiff.model.Tag; import com.easyinnova.tiff.model.TagValue; import com.easyinnova.tiff.model.TiffDocument; import com.easyinnova.tiff.model.TiffObject; import com.easyinnova.tiff.model.TiffTags; import com.easyinnova.tiff.model.types.IFD; import com.easyinnova.tiff.model.types.Rational; import com.easyinnova.tiff.model.types.abstractTiffType; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Checks if the Tiff file complies with the Baseline 6.0. */ public class BaselineProfile extends GenericProfile implements Profile { /** * Known types of images. */ public enum ImageType { /** Bilevel (black and white). */ BILEVEL, /** Crayscale. */ GRAYSCALE, /** Palette-color. */ PALETTE, /** The transparency mask. */ TRANSPARENCY_MASK, /** RGB. */ RGB, /** CMYK. */ CMYK, /** YCbCr. */ YCbCr, /** CIELab. */ CIELab, /** Undefined. */ UNDEFINED }; /** The image type. */ private ImageType type; /** The photometric interpretation. */ private int photometric; /** Is image stored in strips. */ private boolean strips = false; /** Is image stored in tiles. */ private boolean tiles = false; /** * The tag order tolerance.
* 0: No tolerance. 1: Full tolerance (no matter if tags are not in ascending order) * */ private int tagOrderTolerance = 1; /** * The rows per strip tolerance.
* 0: No tolerance. 1: Full tolerance. * */ private int rowsPerStripTolerance = 1; /** * Instantiates a new baseline profile. * * @param doc the tiff file */ public BaselineProfile(TiffDocument doc) { super(doc); type = ImageType.UNDEFINED; } /** * Validates the IFD. */ @Override public void validate() { int n = 0; for (TiffObject o : model.getImageIfds()) { IFD ifd = (IFD) o; IfdTags metadata = ifd.getMetadata(); validateMetadata(metadata); checkImage(ifd, n, metadata); n++; } } /** * Creates the report. * * @return the XML report document * @throws ParserConfigurationException Configuration parsing exception */ public Document createSchematronReport() throws ParserConfigurationException { int n = 0; DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.newDocument(); Element rootElement = doc.createElement("report"); doc.appendChild(rootElement); // IFDs Element ifds = doc.createElement("ifds"); TiffObject o = model.getFirstIFD(); while (o != null) { IFD ifd = (IFD) o; Element ifdnode = doc.createElement("ifd"); ifdnode.setAttribute("n", n + ""); // Tags IfdTags metadata = ifd.getMetadata(); Element tags = reportMetadata(metadata, doc); ifdnode.appendChild(tags); // Image Element image = reportImage(ifd, n, metadata, doc); ifdnode.appendChild(image); n++; ifds.appendChild(ifdnode); o = ifd.getNextIFD(); } rootElement.appendChild(ifds); return doc; } /** * Validates that the ifd entries have correct types and cardinalities, as they are defined in the * JSONs tag configuration files. * * @param metadata the ifd metadata */ public void validateMetadata(IfdTags metadata) { int prevTagId = 0; try { TiffTags.getTiffTags(); } catch (ReadTagsIOException e) { } for (TagValue ie : metadata.getTags()) { if (!TiffTags.tagMap.containsKey(ie.getId())) { validation.addWarning("Ignoring undefined tag id " + ie.getId(), "", "Metadata"); } else if (!TiffTags.tagTypes.containsKey(ie.getType())) { validation.addWarning("Ignoring unknown tag type " + ie.getType(), "", "Metadata"); } else { Tag t = TiffTags.getTag(ie.getId()); String stype = TiffTags.tagTypes.get(ie.getType()); if (ie.getId() == 320) { // Colormap length check long bps = 0; if (metadata.containsTagId(258)) bps = metadata.get(258).getFirstNumericValue(); long calc = 3 * (long) Math.pow(2, bps); if (calc != ie.getCardinality()) { validation.addError("Invalid cardinality for tag " + TiffTags.getTag(ie.getId()).getName() + "[" + ie.getCardinality() + "]", "Metadata", stype); } } try { // Cardinality check int card = Integer.parseInt(t.getCardinality()); if (card != ie.getCardinality()) validation.addError("Cardinality for tag " + TiffTags.getTag(ie.getId()).getName() + " must be " + card, "Metadata", ie.getCardinality()); } catch (Exception e) { // TODO: Deal with formulas? } } if (ie.getId() < prevTagId) { if (tagOrderTolerance > 0) validation.addWarning("Tags are not in ascending order", "", "Metadata"); else validation.addErrorLoc("Tags are not in ascending order", "Metadata"); } prevTagId = ie.getId(); } } /** * Report metadata. * * @param metadata the metadata * @param doc the doc * @return the element */ public Element reportMetadata(IfdTags metadata, Document doc) { Element tags = doc.createElement("tags"); for (TagValue ie : metadata.getTags()) { Element tag = doc.createElement("tag"); tag.setTextContent(ie.getId() + ""); tag.setAttribute("id", ie.getId() + ""); tag.setAttribute("type", ie.getType() + ""); tag.setAttribute("cardinality", ie.getCardinality() + ""); tag.setAttribute("offset", ie.getReadOffset() + ""); tags.appendChild(tag); } return tags; } /** * Check if the tags that define the image are correct and consistent. * * @param ifd the ifd * @param n the ifd number * @param metadata the ifd metadata */ public void checkImage(IFD ifd, int n, IfdTags metadata) { CheckCommonFields(ifd, n, metadata); if (!metadata.containsTagId(TiffTags.getTagId("PhotometricInterpretation"))) { validation.addErrorLoc("Missing Photometric Interpretation", "IFD" + n); } else if (metadata.get(TiffTags.getTagId("PhotometricInterpretation")).getValue().size() != 1) { validation.addErrorLoc("Invalid Photometric Interpretation", "IFD" + n); } else { photometric = (int) metadata.get(TiffTags.getTagId("PhotometricInterpretation")).getFirstNumericValue(); switch (photometric) { case 0: case 1: if (!metadata.containsTagId(TiffTags.getTagId("BitsPerSample")) || metadata.get(TiffTags.getTagId("BitsPerSample")).getFirstNumericValue() == 1) { type = ImageType.BILEVEL; CheckBilevelImage(metadata, n); } else { type = ImageType.GRAYSCALE; CheckGrayscaleImage(metadata, n); } break; case 2: type = ImageType.RGB; CheckRGBImage(metadata, n); break; case 3: type = ImageType.PALETTE; CheckPalleteImage(metadata, n); break; case 4: type = ImageType.TRANSPARENCY_MASK; CheckTransparencyMask(metadata, n); break; case 5: type = ImageType.CMYK; CheckCMYK(metadata, n); break; case 6: type = ImageType.YCbCr; CheckYCbCr(metadata, n); break; case 8: case 9: case 10: type = ImageType.CIELab; CheckCIELab(metadata, n); break; default: validation.addWarning("Unknown Photometric Interpretation", "" + photometric, "IFD" + n); break; } } } /** * Report image. * * @param ifd the ifd * @param n the n * @param metadata the metadata * @param doc the doc * @return the element */ public Element reportImage(IFD ifd, int n, IfdTags metadata, Document doc) { Element image = doc.createElement("image"); // Photometric interpretation if (metadata.containsTagId(TiffTags.getTagId("PhotometricInterpretation"))) { Element photo = doc.createElement("photometricinterpretation"); int photov = (int) metadata.get(TiffTags.getTagId("PhotometricInterpretation")).getFirstNumericValue(); photo.setAttribute("value", photov + ""); photo.setAttribute("length", metadata.get(TiffTags.getTagId("PhotometricInterpretation")) .getValue().size() + ""); } return image; } /** * Check Bilevel Image. * * @param metadata the metadata * @param n the IFD number */ private void CheckBilevelImage(IfdTags metadata, int n) { // Compression long comp = metadata.get(TiffTags.getTagId("Compression")).getFirstNumericValue(); // if (comp != 1 && comp != 2 && comp != 32773) if (comp < 1) validation.addError("Invalid Compression", "IFD" + n, comp); } /** * Check Grayscale Image. * * @param metadata the metadata * @param n the IFD number */ private void CheckGrayscaleImage(IfdTags metadata, int n) { // Bits per Sample long bps = metadata.get(TiffTags.getTagId("BitsPerSample")).getFirstNumericValue(); // if (bps != 4 && bps != 8) if (bps < 1) validation.addError("Invalid Bits per Sample", "IFD" + n, bps); // Compression long comp = metadata.get(TiffTags.getTagId("Compression")).getFirstNumericValue(); // if (comp != 1 && comp != 32773) if (comp < 1) validation.addError("Invalid Compression", "IFD" + n, comp); } /** * Check Pallete Color Image. * * @param metadata the metadata * @param nifd the IFD number */ private void CheckPalleteImage(IfdTags metadata, int nifd) { // Color Map if (!metadata.containsTagId(TiffTags.getTagId("ColorMap"))) { validation.addErrorLoc("Missing Color Map", "IFD" + nifd); } else { int n = metadata.get(TiffTags.getTagId("ColorMap")).getCardinality(); if (n != 3 * (int) Math.pow(2, metadata.get(TiffTags.getTagId("BitsPerSample")) .getFirstNumericValue())) validation.addError("Incorrect Color Map Cardinality", "IFD" + nifd, metadata.get(320) .getCardinality()); } // Bits per Sample long bps = metadata.get(TiffTags.getTagId("BitsPerSample")).getFirstNumericValue(); if (bps != 4 && bps != 8) validation.addError("Invalid Bits per Sample", "IFD" + nifd, bps); // Compression long comp = metadata.get(TiffTags.getTagId("Compression")).getFirstNumericValue(); // if (comp != 1 && comp != 32773) if (comp < 1) validation.addError("Invalid Compression", "IFD" + nifd, comp); } /** * Check transparency mask. * * @param metadata the metadata * @param n the ifd number */ private void CheckTransparencyMask(IfdTags metadata, int n) { // Samples per pixel if (!metadata.containsTagId(TiffTags.getTagId("SamplesPerPixel"))) { validation.addErrorLoc("Missing Samples Per Pixel", "IFD" + n); } else { long spp = metadata.get(TiffTags.getTagId("SamplesPerPixel")).getFirstNumericValue(); if (spp != 1) { validation.addError("Invalid Samples Per Pixel", "IFD" + n, spp); } } // BitsPerSample if (!metadata.containsTagId(TiffTags.getTagId("BitsPerSample"))) { validation.addErrorLoc("Missing BitsPerSample", "IFD" + n); } else { long bps = metadata.get(TiffTags.getTagId("BitsPerSample")).getFirstNumericValue(); if (bps != 1) { validation.addError("Invalid BitsPerSample", "IFD" + n, bps); } } } /** * Check CMYK. * * @param metadata the metadata * @param n the ifd number */ private void CheckCMYK(IfdTags metadata, int n) { // Samples per pixel if (!metadata.containsTagId(TiffTags.getTagId("SamplesPerPixel"))) { validation.addErrorLoc("Missing Samples Per Pixel", "IFD" + n); } // BitsPerSample if (!metadata.containsTagId(TiffTags.getTagId("BitsPerSample"))) { validation.addErrorLoc("Missing BitsPerSample", "IFD" + n); } } /** * Check YCbCr. * * @param metadata the metadata * @param n the IFD number */ private void CheckYCbCr(IfdTags metadata, int n) { // Samples per pixel if (!metadata.containsTagId(TiffTags.getTagId("SamplesPerPixel"))) { validation.addErrorLoc("Missing Samples Per Pixel", "IFD" + n); } else { long spp = metadata.get(TiffTags.getTagId("SamplesPerPixel")).getFirstNumericValue(); if (spp != 3) { validation.addError("Invalid Samples Per Pixel", "IFD" + n, spp); } } // BitsPerSample if (!metadata.containsTagId(TiffTags.getTagId("BitsPerSample"))) { validation.addErrorLoc("Missing BitsPerSample", "IFD" + n); } else { for (abstractTiffType vi : metadata.get(TiffTags.getTagId("BitsPerSample")).getValue()) { if (vi.toInt() != 8) { validation.addError("Invalid BitsPerSample", "IFD" + n, vi.toInt()); break; } } } // Compression // long comp = metadata.get(TiffTags.getTagId("Compression")).getFirstNumericValue(); // if (comp != 1 && comp != 5 && comp != 6) // validation.addError("Invalid Compression", comp); // if (!metadata.containsTagId(TiffTags.getTagId("ReferenceBlackWhite"))) // validation.addError("Missing ReferenceBlackWhite"); // if (!metadata.containsTagId(TiffTags.getTagId("YCbCrCoefficients"))) // validation.addError("Missing YCbCr Coefficients"); // if (!metadata.containsTagId(TiffTags.getTagId("YCbCrSubSampling"))) // validation.addError("Missing YCbCr SubSampling"); // if (!metadata.containsTagId(TiffTags.getTagId("YCbCrPositioning"))) // validation.addError("Missing YCbCr Positioning"); } /** * Check CIELab. * * @param metadata the metadata * @param n the IFD number */ private void CheckCIELab(IfdTags metadata, int n) { // BitsPerSample if (!metadata.containsTagId(TiffTags.getTagId("BitsPerSample"))) { validation.addErrorLoc("Missing BitsPerSample", "IFD" + n); } else { for (abstractTiffType vi : metadata.get(TiffTags.getTagId("BitsPerSample")).getValue()) { if (vi.toInt() != 8) { validation.addError("Invalid BitsPerSample", "IFD" + n, vi.toInt()); break; } } } } /** * Check RGB Image. * * @param metadata the metadata * @param n the IFD number */ private void CheckRGBImage(IfdTags metadata, int n) { // Samples per Pixel long samples = metadata.get(TiffTags.getTagId("SamplesPerPixel")).getFirstNumericValue(); if (samples < 3) validation.addError("Invalid Samples per Pixel", "IFD" + n, samples); // Compression long comp = metadata.get(TiffTags.getTagId("Compression")).getFirstNumericValue(); // if (comp != 1 && comp != 32773) if (comp < 1) validation.addError("Invalid Compression", "IFD" + n, comp); } /** * Check common fields. * * @param ifd the ifd * @param n the ifd number * @param metadata the ifd metadata */ private void CheckCommonFields(IFD ifd, int n, IfdTags metadata) { int id; // Width tag is mandatory id = TiffTags.getTagId("ImageWidth"); if (!metadata.containsTagId(id)) validation.addError("Missing required field", "IFD" + n, TiffTags.getTag(id).getName()); else { long val = metadata.get(id).getFirstNumericValue(); if (val <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Height tag is mandatory id = TiffTags.getTagId("ImageLength"); if (!metadata.containsTagId(id)) validation.addError("Missing required field", "IFD" + n, TiffTags.getTag(id).getName()); else { long val = metadata.get(id).getFirstNumericValue(); if (val <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check Resolution Unit id = TiffTags.getTagId("ResolutionUnit"); if (!metadata.containsTagId(id)) { // validation.addError("Missing required field", TiffTags.getTag(id).getName()); } else { long val = metadata.get(id).getFirstNumericValue(); if (val != 1 && val != 2 && val != 3) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check XResolution id = TiffTags.getTagId("XResolution"); if (!metadata.containsTagId(id)) { // validation.addError("Missing required field", TiffTags.getTag(id).name); } else { float val = ((Rational) metadata.get(id).getValue().get(0)).getFloatValue(); if (val <= 0f) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check YResolution id = TiffTags.getTagId("YResolution"); if (!metadata.containsTagId(id)) { // validation.addError("Missing required field", TiffTags.getTag(id).name); } else { float val = ((Rational) metadata.get(id).getValue().get(0)).getFloatValue(); if (val <= 0f) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check Planar Configuration id = TiffTags.getTagId("PlanarConfiguration"); if (!metadata.containsTagId(id)) { // validation.addError("Missing required field", TiffTags.getTag(id).name); } else { long val = metadata.get(id).getFirstNumericValue(); if (val != 1 && val != 2) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check Orientation id = TiffTags.getTagId("Orientation"); if (!metadata.containsTagId(id)) { // validation.addError("Missing required field", TiffTags.getTag(id).name); } else { long val = metadata.get(id).getFirstNumericValue(); if (val <= 0 || val > 8) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, val); } // Check whether the image is stored in tiles or strips strips = ifd.hasStrips(); tiles = ifd.hasTiles(); if (!strips && !tiles) validation.addErrorLoc("Missing image organization tags", "IFD" + n); else if (strips && tiles) validation.addErrorLoc("Image in both strips and tiles", "IFD" + n); else if (strips) { CheckStrips(metadata, n); } else if (tiles) { CheckTiles(ifd, metadata, n); } // Check pixel samples bits if (metadata.containsTagId(TiffTags.getTagId("BitsPerSample")) && metadata.containsTagId(TiffTags.getTagId("SampesPerPixel"))) { long spp = metadata.get(TiffTags.getTagId("SamplesPerPixel")).getFirstNumericValue(); int bps = metadata.get(TiffTags.getTagId("BitsPerSample")).getValue().size(); if (spp != bps) { validation .addErrorLoc("Samples per Pixel and Bits per Sample count do not match", "IFD" + n); if (bps == 1) { // TODO: Tolerate and proceed as if the BitsPerSample tag had a count equal to the // SamplesPerPixel tag value, and with all values equal to the single value actually given } } if (metadata.containsTagId(TiffTags.getTagId("ExtraSamples"))) { int ext = metadata.get(TiffTags.getTagId("ExtraSamples")).getValue().size(); if (ext + 3 != bps) { validation.addError("Incorrect Extra Samples Count", "IFD" + n, ext); } else if (ext > 0 && bps <= 3) { validation.addError("Unnecessary Extra Samples", "IFD" + n, ext); } } if (bps > 1) { TagValue lbps = metadata.get(TiffTags.getTagId("BitsPerSample")); if (lbps == null || lbps.getValue() == null) { validation.addErrorLoc("Invalid Bits per Sample", "IFD" + n); } else { boolean distinct_bps_samples = false; for (int i = 1; i < lbps.getCardinality(); i++) { if (lbps.getValue().get(i).toInt() != lbps.getValue().get(i - 1).toInt()) distinct_bps_samples = true; } if (distinct_bps_samples) validation.addErrorLoc("Distinct Bits per Sample values", "IFD" + n); } } } } /** * Check that the strips containing the image are well-formed. * * @param metadata the metadata * @param n the IFD number */ private void CheckStrips(IfdTags metadata, int n) { long offset; int id; // Strip offsets id = TiffTags.getTagId("StripOffsets"); offset = metadata.get(id).getFirstNumericValue(); int nso = metadata.get(id).getCardinality(); if (offset <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, offset); // Strip Byte Counts id = TiffTags.getTagId("StripBYTECount"); offset = metadata.get(id).getFirstNumericValue(); int nsc = metadata.get(id).getCardinality(); if (offset <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, offset); if (nso != nsc) { validation.addErrorLoc("Inconsistent strip lengths", "IFD" + n); } int pixelSize = 0; for (int i = 0; i < metadata.get("BitsPerSample").getCardinality(); i++) { pixelSize += metadata.get("BitsPerSample").getValue().get(i).toInt(); } if (metadata.get("Compression").getFirstNumericValue() == 1 && pixelSize >= 8) { int calculatedImageLength = 0; for (int i = 0; i < nsc; i++) { calculatedImageLength += metadata.get(id).getValue().get(i).toInt(); } if (calculatedImageLength != metadata.get("ImageLength").getFirstNumericValue() * metadata.get("ImageWidth").getFirstNumericValue() * pixelSize / 8) { // validation.toString(); validation.addErrorLoc("Calculated and declared image size do not match", "IFD" + n); } } // Rows per Strip id = TiffTags.getTagId("RowsPerStrip"); if (!metadata.containsTagId(id)) { if (rowsPerStripTolerance > 0) validation.addWarning("Missing required field", TiffTags.getTag(id).getName(), "IFD" + n); else validation.addError("Missing required field", "IFD" + n, TiffTags.getTag(id).getName()); } else { offset = metadata.get(id).getFirstNumericValue(); if (offset <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, offset); } } /** * Check that the tiles containing the image are well-formed. * * @param ifd the ifd * @param metadata the metadata * @param n the ifd number */ private void CheckTiles(IFD ifd, IfdTags metadata, int n) { long offset; int id; // Check Tile Offsets id = TiffTags.getTagId("TileOffsets"); offset = metadata.get(id).getFirstNumericValue(); int no = metadata.get(id).getCardinality(); if (offset <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, offset); // Check Tile Byte Counts id = TiffTags.getTagId("TileBYTECounts"); offset = metadata.get(id).getFirstNumericValue(); int nc = metadata.get(id).getCardinality(); if (offset <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, offset); if (no != nc) { validation.addErrorLoc("Inconsistent tile lengths", "IFD" + n); } // Check Tile Width long tileWidth = 0; id = TiffTags.getTagId("TileWidth"); if (!metadata.containsTagId(id)) validation.addErrorLoc("Missing required field for tiles " + TiffTags.getTag(id).getName(), "IFD" + n); else { tileWidth = metadata.get(id).getFirstNumericValue(); if (tileWidth <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, tileWidth); } // Check Tile Length id = TiffTags.getTagId("TileLength"); long tileLength = 0; if (!metadata.containsTagId(id)) validation.addErrorLoc("Missing required field for tiles " + TiffTags.getTag(id).getName(), "IFD" + n); else { tileLength = metadata.get(id).getFirstNumericValue(); if (tileLength <= 0) validation.addError("Invalid value for field " + TiffTags.getTag(id).getName(), "IFD" + n, tileLength); } long tilesPerImage = ((metadata.get(TiffTags.getTagId("ImageWidth")).getFirstNumericValue() + tileWidth - 1) / tileWidth) * ((metadata.get(TiffTags.getTagId("ImageLength")).getFirstNumericValue() + tileLength - 1) / tileLength); // Check Plannar Configuration id = TiffTags.getTagId("PlanarConfiguration"); int idspp = TiffTags.getTagId("SamplesPerPixel"); if (metadata.containsTagId(id) && metadata.containsTagId(idspp)) { long planar = metadata.get(id).getFirstNumericValue(); long spp = metadata.get(idspp).getFirstNumericValue(); if (planar == 2) { long spp_tpi = spp * tilesPerImage; if (ifd.getImageTiles().getTiles().size() < spp_tpi) { validation.addErrorLoc("Insufficient tiles", "IFD" + n); } } } } /** * Gets the image type. * * @return the type */ public ImageType getType() { return type; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy