/***************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * ****************************************************************************/ package org.apache.padaf.preflight.graphics; import static org.apache.padaf.preflight.ValidationConstants.ERROR_GRAPHIC_MISSING_FIELD; import static org.apache.padaf.preflight.ValidationConstants.ERROR_GRAPHIC_UNEXPECTED_KEY; import static org.apache.padaf.preflight.ValidationConstants.ERROR_GRAPHIC_UNEXPECTED_VALUE_FOR_KEY; import static org.apache.padaf.preflight.ValidationConstants.XOBJECT_DICTIONARY_KEY_COLOR_SPACE; import java.util.List; import org.apache.padaf.preflight.DocumentHandler; import org.apache.padaf.preflight.ValidationConstants; import org.apache.padaf.preflight.ValidationException; import org.apache.padaf.preflight.ValidationResult.ValidationError; import org.apache.padaf.preflight.graphics.color.ColorSpaceHelper; import org.apache.padaf.preflight.graphics.color.ColorSpaceHelperFactory; import org.apache.padaf.preflight.graphics.color.ColorSpaceHelperFactory.ColorSpaceRestriction; import org.apache.padaf.preflight.utils.COSUtils; import org.apache.padaf.preflight.utils.RenderingIntents; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSBoolean; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSStream; /** * This class validates XObject with the Image subtype. */ public class XObjImageValidator extends AbstractXObjValidator { public XObjImageValidator(DocumentHandler handler, COSStream xobj) { super(handler, xobj); } /* * (non-Javadoc) * * @seenet.awl.edoc.pdfa.validation.graphics.AbstractXObjValidator# * checkMandatoryFields(java.util.List) */ @Override protected boolean checkMandatoryFields(List<ValidationError> result) { boolean res = this.xobject.getItem(COSName.getPDFName("Width")) != null; res = res && this.xobject.getItem(COSName.getPDFName("Height")) != null; // type and subtype checked before to create the Validator. if (!res) { result.add(new ValidationError(ERROR_GRAPHIC_MISSING_FIELD)); } return res; } /* * 6.2.4 no Alternates */ protected void checkAlternates(List<ValidationError> result) throws ValidationException { if (this.xobject.getItem(COSName.getPDFName("Alternates")) != null) { result.add(new ValidationError( ValidationConstants.ERROR_GRAPHIC_UNEXPECTED_KEY, "Unexpected 'Alternates' Key")); } } /* * 6.2.4 if interpolates, value = false */ protected void checkInterpolate(List<ValidationError> result) throws ValidationException { if (this.xobject.getItem(COSName.getPDFName("Interpolate")) != null) { if (this.xobject.getBoolean(COSName.getPDFName("Interpolate"), true)) { result.add(new ValidationError( ValidationConstants.ERROR_GRAPHIC_UNEXPECTED_VALUE_FOR_KEY, "Unexpected 'true' value for 'Interpolate' Key")); } } } /* * 6.2.4 Intent has specific values */ protected void checkIntent(List<ValidationError> result) throws ValidationException { if (this.xobject.getItem(COSName.getPDFName("Intent")) != null) { String s = this.xobject.getNameAsString("Intent"); if (!RenderingIntents.contains(s)) { result.add(new ValidationError(ERROR_GRAPHIC_UNEXPECTED_VALUE_FOR_KEY, "Unexpected value '" + s + "' for Intent key in image")); } } } /* * According to the PDF Reference file, there are some specific rules on following fields * ColorSpace, Mask, ImageMask and BitsPerComponent. * If ImageMask is set to true, ColorSpace and Mask entries are forbidden. */ protected void checkColorSpaceAndImageMask(List<ValidationError> result) throws ValidationException { COSBase csImg = this.xobject.getItem(COSName.getPDFName(XOBJECT_DICTIONARY_KEY_COLOR_SPACE)); COSBase bitsPerComp = this.xobject.getItem(COSName.getPDFName("BitsPerComponent")); COSBase mask = this.xobject.getItem(COSName.getPDFName("Mask")); if (isImageMaskTrue()) { if ( csImg != null || mask != null) { result.add(new ValidationError(ERROR_GRAPHIC_UNEXPECTED_KEY, "ImageMask entry is true, ColorSpace and Mask are forbidden.")); } Integer bitsPerCompValue = COSUtils.getAsInteger(bitsPerComp, cosDocument); if (bitsPerCompValue != 1 ) { result.add(new ValidationError(ERROR_GRAPHIC_UNEXPECTED_VALUE_FOR_KEY, "ImageMask entry is true, BitsPerComponent must be 1.")); } } else { ColorSpaceHelper csh = ColorSpaceHelperFactory.getColorSpaceHelper(csImg, handler, ColorSpaceRestriction.NO_PATTERN); csh.validate(result); } } private boolean isImageMaskTrue() { COSBase imgMask = this.xobject.getItem(COSName.getPDFName("ImageMask")); if (imgMask != null && imgMask instanceof COSBoolean) { return ((COSBoolean) imgMask).getValue(); } else { return false; } } /* * (non-Javadoc) * * @see net.awl.edoc.pdfa.validation.graphics.AbstractXObjValidator#validate() */ @Override public List<ValidationError> validate() throws ValidationException { List<ValidationError> result = super.validate(); checkAlternates(result); checkInterpolate(result); checkIntent(result); checkColorSpaceAndImageMask(result); return result; } }