You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2011/12/11 20:43:25 UTC
svn commit: r1213049 - in
/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight:
ValidationConstants.java helpers/CatalogValidationHelper.java
Author: leleueri
Date: Sun Dec 11 19:43:24 2011
New Revision: 1213049
URL: http://svn.apache.org/viewvc?rev=1213049&view=rev
Log:
Addition of ICC_Profile Name
Modified:
pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/ValidationConstants.java
pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/CatalogValidationHelper.java
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/ValidationConstants.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/ValidationConstants.java?rev=1213049&r1=1213048&r2=1213049&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/ValidationConstants.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/ValidationConstants.java Sun Dec 11 19:43:24 2011
@@ -267,6 +267,7 @@ public interface ValidationConstants {
static final String ICC_Characterization_Data_Registry_FOGRA43 = "FOGRA43";
static final String ICC_Characterization_Data_Registry_CGATS_TR_006 = "CGATS TR 006";
+ static final String ICC_Characterization_Data_Registry_CGATS_TR006 = "CGATS TR006";
static final String ICC_Characterization_Data_Registry_FOGRA39 = "FOGRA39";
static final String ICC_Characterization_Data_Registry_JC200103 = "JC200103";
static final String ICC_Characterization_Data_Registry_FOGRA27 = "FOGRA27";
@@ -275,8 +276,11 @@ public interface ValidationConstants {
static final String ICC_Characterization_Data_Registry_FOGRA46 = "FOGRA46";
static final String ICC_Characterization_Data_Registry_FOGRA41 = "FOGRA41";
static final String ICC_Characterization_Data_Registry_CGATS_TR_001 = "CGATS TR 001";
+ static final String ICC_Characterization_Data_Registry_CGATS_TR001 = "CGATS TR001";
static final String ICC_Characterization_Data_Registry_CGATS_TR_003 = "CGATS TR 003";
+ static final String ICC_Characterization_Data_Registry_CGATS_TR003 = "CGATS TR003";
static final String ICC_Characterization_Data_Registry_CGATS_TR_005 = "CGATS TR 005";
+ static final String ICC_Characterization_Data_Registry_CGATS_TR005 = "CGATS TR005";
static final String ICC_Characterization_Data_Registry_FOGRA28 = "FOGRA28";
static final String ICC_Characterization_Data_Registry_JCW2003 = "JCW2003";
static final String ICC_Characterization_Data_Registry_EUROSB204 = "EUROSB204";
@@ -290,6 +294,7 @@ public interface ValidationConstants {
static final String ICC_Characterization_Data_Registry_IFRA26 = "IFRA26";
static final String ICC_Characterization_Data_Registry_JCN2002 = "JCN2002";
static final String ICC_Characterization_Data_Registry_CGATS_TR_002 = "CGATS TR 002";
+ static final String ICC_Characterization_Data_Registry_CGATS_TR002 = "CGATS TR002";
static final String ICC_Characterization_Data_Registry_FOGRA33 = "FOGRA33";
static final String ICC_Characterization_Data_Registry_FOGRA37 = "FOGRA37";
static final String ICC_Characterization_Data_Registry_FOGRA31 = "FOGRA31";
@@ -405,10 +410,6 @@ public interface ValidationConstants {
*/
static final String ERROR_SYNTAX_STREAM_INVALID_FILTER = "1.2.7";
/**
- * The stream uses a filter which isn't defined in the PDF Reference document.
- */
- static final String ERROR_SYNTAX_STREAM_UNDEFINED_FILTER = "1.2.12";
- /**
* The content stream has some syntax errors
*/
static final String ERROR_SYNTAX_CONTENT_STREAM_INVALID = "1.2.8";
@@ -423,7 +424,11 @@ public interface ValidationConstants {
/**
* The content stream contains an invalid argument for the operator
*/
- static final String ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT = "1.2.11";
+ static final String ERROR_SYNTAX_CONTENT_STREAM_INVALID_ARGUMENT = "1.2.11";
+ /**
+ * The stream uses a filter which isn't defined in the PDF Reference document.
+ */
+ static final String ERROR_SYNTAX_STREAM_UNDEFINED_FILTER = "1.2.12";
/**
* Common error about the cross ref table
*/
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/CatalogValidationHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/CatalogValidationHelper.java?rev=1213049&r1=1213048&r2=1213049&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/CatalogValidationHelper.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/padaf/preflight/helpers/CatalogValidationHelper.java Sun Dec 11 19:43:24 2011
@@ -57,10 +57,11 @@ public class CatalogValidationHelper ext
protected List<String> listICC = new ArrayList<String>();
public CatalogValidationHelper(ValidatorConfig cfg)
- throws ValidationException {
+ throws ValidationException {
super(cfg);
listICC.add(ICC_Characterization_Data_Registry_FOGRA43);
listICC.add(ICC_Characterization_Data_Registry_CGATS_TR_006);
+ listICC.add(ICC_Characterization_Data_Registry_CGATS_TR006);
listICC.add(ICC_Characterization_Data_Registry_FOGRA39);
listICC.add(ICC_Characterization_Data_Registry_JC200103);
listICC.add(ICC_Characterization_Data_Registry_FOGRA27);
@@ -71,6 +72,9 @@ public class CatalogValidationHelper ext
listICC.add(ICC_Characterization_Data_Registry_CGATS_TR_001);
listICC.add(ICC_Characterization_Data_Registry_CGATS_TR_003);
listICC.add(ICC_Characterization_Data_Registry_CGATS_TR_005);
+ listICC.add(ICC_Characterization_Data_Registry_CGATS_TR001);
+ listICC.add(ICC_Characterization_Data_Registry_CGATS_TR003);
+ listICC.add(ICC_Characterization_Data_Registry_CGATS_TR005);
listICC.add(ICC_Characterization_Data_Registry_FOGRA28);
listICC.add(ICC_Characterization_Data_Registry_JCW2003);
listICC.add(ICC_Characterization_Data_Registry_EUROSB204);
@@ -84,6 +88,7 @@ public class CatalogValidationHelper ext
listICC.add(ICC_Characterization_Data_Registry_IFRA26);
listICC.add(ICC_Characterization_Data_Registry_JCN2002);
listICC.add(ICC_Characterization_Data_Registry_CGATS_TR_002);
+ listICC.add(ICC_Characterization_Data_Registry_CGATS_TR002);
listICC.add(ICC_Characterization_Data_Registry_FOGRA33);
listICC.add(ICC_Characterization_Data_Registry_FOGRA37);
listICC.add(ICC_Characterization_Data_Registry_FOGRA31);
@@ -111,7 +116,7 @@ public class CatalogValidationHelper ext
for (String iccStandard : listICC) {
if (iccStandard.contains(name)) { // TODO check with an equal instead of contains?
return true;
- }
+ }
}
return false;
}
@@ -123,272 +128,274 @@ public class CatalogValidationHelper ext
* net.awl.edoc.pdfa.validation.helpers.AbstractValidationHelper#innerValidate
* (net.awl.edoc.pdfa.validation.DocumentHandler)
*/
- @Override
- public List<ValidationError> innerValidate(DocumentHandler handler)
- throws ValidationException {
- List<ValidationError> result = new ArrayList<ValidationError>(0);
- PDDocument pdfbox = handler.getDocument();
- PDDocumentCatalog catalog = pdfbox.getDocumentCatalog();
- if (catalog != null) {
- validateActions(handler, catalog, result);
- validateLang(handler, catalog, result);
- validateNames(handler, catalog, result);
- validateOCProperties(handler, catalog, result);
- } else {
- throw new ValidationException(
- "There are no Catalog entry in the Document.");
- }
-
- // ---- Check OutputIntent to know the ICC Profile
- result.addAll(validateOutputIntent(handler));
-
- return result;
- }
-
- /**
- * This method validates if OpenAction entry contains forbidden action type.
- * It checks too if an Additional Action is present.
- *
- * @param handler
- * @param catalog
- * @param result
- * @throws ValidationException
- */
- protected void validateActions(DocumentHandler handler,
- PDDocumentCatalog catalog, List<ValidationError> result)
- throws ValidationException {
- // ---- get OpenAction and Additional Action if these entries are present
- List<AbstractActionManager> lActions = this.actionFact.getActions(catalog
- .getCOSDictionary(), handler.getDocument().getDocument());
- for (AbstractActionManager action : lActions) {
- if (!action.valid(result)) {
- return;
- }
- }
- }
-
- /**
- * The Lang element is optional but it is recommended. This method check the
- * Syntax of the Lang if this entry is present.
- *
- * @param handler
- * @param catalog
- * @param result
- * @throws ValidationException
- */
- protected void validateLang(DocumentHandler handler,
- PDDocumentCatalog catalog, List<ValidationError> result)
- throws ValidationException {
- String lang = catalog.getLanguage();
- if (lang != null && !"".equals(lang) && !lang.matches("[A-Za-z]{1,8}(-[A-Za-z]{1,8})*")) {
- result.add(new ValidationError(ERROR_SYNTAX_LANG_NOT_RFC1766));
- }
- }
-
- /**
- * A Catalog shall not contain the EmbeddedFiles entry.
- *
- * @param handler
- * @param catalog
- * @param result
- * @throws ValidationException
- */
- protected void validateNames(DocumentHandler handler,
- PDDocumentCatalog catalog, List<ValidationError> result)
- throws ValidationException {
- PDDocumentNameDictionary names = catalog.getNames();
- if (names != null) {
- PDEmbeddedFilesNameTreeNode efs = names.getEmbeddedFiles();
- if (efs != null) {
- result.add(new ValidationError(
- ERROR_SYNTAX_TRAILER_CATALOG_EMBEDDEDFILES,"EmbeddedFile entry is present in the Names dictionary"));
- }
- }
- }
-
- /**
- * A Catalog shall not contain the OCPProperties (Optional Content Properties)
- * entry.
- *
- * @param handler
- * @param catalog
- * @param result
- * @throws ValidationException
- */
- protected void validateOCProperties(DocumentHandler handler,
- PDDocumentCatalog catalog, List<ValidationError> result)
- throws ValidationException {
- COSBase ocp = catalog.getCOSDictionary().getItem(
- COSName.getPDFName(DOCUMENT_DICTIONARY_KEY_OPTIONAL_CONTENTS));
- if (ocp != null) {
- result
- .add(new ValidationError(ERROR_SYNTAX_TRAILER_CATALOG_OCPROPERTIES, "A Catalog shall not contain the OCPProperties entry."));
- }
- }
-
- /**
- * This method checks the content of each OutputIntent. The S entry must
- * contain GTS_PDFA1. The DestOuputProfile must contain a valid ICC Profile
- * Stream.
- *
- * If there are more than one OutputIntent, they have to use the same ICC
- * Profile.
- *
- * This method returns a list of ValidationError. It is empty if no errors
- * have been found.
- *
- * @param handler
- * @return
- * @throws ValidationException
- */
- public List<ValidationError> validateOutputIntent(DocumentHandler handler)
- throws ValidationException {
- List<ValidationError> result = new ArrayList<ValidationError>(0);
- PDDocument pdDocument = handler.getDocument();
- PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
- COSDocument cDoc = pdDocument.getDocument();
-
- COSBase cBase = catalog.getCOSDictionary().getItem(COSName.getPDFName(DOCUMENT_DICTIONARY_KEY_OUTPUT_INTENTS));
- COSArray outputIntents = COSUtils.getAsArray(cBase, cDoc);
-
- Map<COSObjectKey, Boolean> tmpDestOutputProfile = new HashMap<COSObjectKey, Boolean>();
-
- for (int i = 0; outputIntents != null && i < outputIntents.size(); ++i) {
- COSDictionary dictionary = COSUtils.getAsDictionary(outputIntents.get(i), cDoc);
-
- if (dictionary == null) {
-
- result.add(new ValidationError(
- ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
- "OutputIntent object is null or isn't a dictionary"));
-
- } else {
- // ---- S entry is mandatory and must be equals to GTS_PDFA1
- String sValue = dictionary.getNameAsString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_S));
- if (!OUTPUT_INTENT_DICTIONARY_VALUE_GTS_PDFA1.equals(sValue)) {
- result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_S_VALUE_INVALID,
- "The S entry of the OutputIntent isn't GTS_PDFA1"));
- continue;
- }
-
- // ---- OutputConditionIdentifier is a mandatory field
- String outputConditionIdentifier = dictionary
- .getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_OUTPUT_CONDITION_IDENTIFIER));
- if (outputConditionIdentifier == null) {// empty string is autorized (it may be an application specific value)
- result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
- "The OutputIntentCondition is missing"));
- continue;
- }
-
- // ---- If OutputConditionIdentifier is "Custom" or a non Standard ICC Characterization :
- // ---- DestOutputProfile and Info are mandatory
- // ---- DestOutputProfile must be a ICC Profile
-
- // ---- Because of PDF/A conforming file needs to specify the color characteristics, the DestOutputProfile
- // ---- is checked even if the OutputConditionIdentifier isn't "Custom"
- COSBase dop = dictionary.getItem(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_DEST_OUTPUT_PROFILE));
- ValidationError valer = validateICCProfile(dop, cDoc, tmpDestOutputProfile, handler);
- if (valer != null) {
- result.add(valer);
- continue;
- }
-
- if (!isStandardICCCharacterization(outputConditionIdentifier)) {
- String info = dictionary.getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_INFO));
- if (info == null || "".equals(info)) {
+ @Override
+ public List<ValidationError> innerValidate(DocumentHandler handler)
+ throws ValidationException {
+ List<ValidationError> result = new ArrayList<ValidationError>(0);
+ PDDocument pdfbox = handler.getDocument();
+ PDDocumentCatalog catalog = pdfbox.getDocumentCatalog();
+ if (catalog != null) {
+ validateActions(handler, catalog, result);
+ validateLang(handler, catalog, result);
+ validateNames(handler, catalog, result);
+ validateOCProperties(handler, catalog, result);
+ } else {
+ throw new ValidationException(
+ "There are no Catalog entry in the Document.");
+ }
+
+ // ---- Check OutputIntent to know the ICC Profile
+ result.addAll(validateOutputIntent(handler));
+
+ return result;
+ }
+
+ /**
+ * This method validates if OpenAction entry contains forbidden action type.
+ * It checks too if an Additional Action is present.
+ *
+ * @param handler
+ * @param catalog
+ * @param result
+ * @throws ValidationException
+ */
+ protected void validateActions(DocumentHandler handler,
+ PDDocumentCatalog catalog, List<ValidationError> result)
+ throws ValidationException {
+ // ---- get OpenAction and Additional Action if these entries are present
+ List<AbstractActionManager> lActions = this.actionFact.getActions(catalog
+ .getCOSDictionary(), handler.getDocument().getDocument());
+ for (AbstractActionManager action : lActions) {
+ if (!action.valid(result)) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * The Lang element is optional but it is recommended. This method check the
+ * Syntax of the Lang if this entry is present.
+ *
+ * @param handler
+ * @param catalog
+ * @param result
+ * @throws ValidationException
+ */
+ protected void validateLang(DocumentHandler handler,
+ PDDocumentCatalog catalog, List<ValidationError> result)
+ throws ValidationException {
+ String lang = catalog.getLanguage();
+ if (lang != null && !"".equals(lang) && !lang.matches("[A-Za-z]{1,8}(-[A-Za-z]{1,8})*")) {
+ result.add(new ValidationError(ERROR_SYNTAX_LANG_NOT_RFC1766));
+ }
+ }
+
+ /**
+ * A Catalog shall not contain the EmbeddedFiles entry.
+ *
+ * @param handler
+ * @param catalog
+ * @param result
+ * @throws ValidationException
+ */
+ protected void validateNames(DocumentHandler handler,
+ PDDocumentCatalog catalog, List<ValidationError> result)
+ throws ValidationException {
+ PDDocumentNameDictionary names = catalog.getNames();
+ if (names != null) {
+ PDEmbeddedFilesNameTreeNode efs = names.getEmbeddedFiles();
+ if (efs != null) {
+ result.add(new ValidationError(
+ ERROR_SYNTAX_TRAILER_CATALOG_EMBEDDEDFILES,"EmbeddedFile entry is present in the Names dictionary"));
+ }
+ }
+ }
+
+ /**
+ * A Catalog shall not contain the OCPProperties (Optional Content Properties)
+ * entry.
+ *
+ * @param handler
+ * @param catalog
+ * @param result
+ * @throws ValidationException
+ */
+ protected void validateOCProperties(DocumentHandler handler,
+ PDDocumentCatalog catalog, List<ValidationError> result)
+ throws ValidationException {
+ COSBase ocp = catalog.getCOSDictionary().getItem(
+ COSName.getPDFName(DOCUMENT_DICTIONARY_KEY_OPTIONAL_CONTENTS));
+ if (ocp != null) {
+ result
+ .add(new ValidationError(ERROR_SYNTAX_TRAILER_CATALOG_OCPROPERTIES, "A Catalog shall not contain the OCPProperties entry."));
+ }
+ }
+
+ /**
+ * This method checks the content of each OutputIntent. The S entry must
+ * contain GTS_PDFA1. The DestOuputProfile must contain a valid ICC Profile
+ * Stream.
+ *
+ * If there are more than one OutputIntent, they have to use the same ICC
+ * Profile.
+ *
+ * This method returns a list of ValidationError. It is empty if no errors
+ * have been found.
+ *
+ * @param handler
+ * @return
+ * @throws ValidationException
+ */
+ public List<ValidationError> validateOutputIntent(DocumentHandler handler)
+ throws ValidationException {
+ List<ValidationError> result = new ArrayList<ValidationError>(0);
+ PDDocument pdDocument = handler.getDocument();
+ PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
+ COSDocument cDoc = pdDocument.getDocument();
+
+ COSBase cBase = catalog.getCOSDictionary().getItem(COSName.getPDFName(DOCUMENT_DICTIONARY_KEY_OUTPUT_INTENTS));
+ COSArray outputIntents = COSUtils.getAsArray(cBase, cDoc);
+
+ Map<COSObjectKey, Boolean> tmpDestOutputProfile = new HashMap<COSObjectKey, Boolean>();
+
+ for (int i = 0; outputIntents != null && i < outputIntents.size(); ++i) {
+ COSDictionary dictionary = COSUtils.getAsDictionary(outputIntents.get(i), cDoc);
+
+ if (dictionary == null) {
+
+ result.add(new ValidationError(
+ ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
+ "OutputIntent object is null or isn't a dictionary"));
+
+ } else {
+ // ---- S entry is mandatory and must be equals to GTS_PDFA1
+ String sValue = dictionary.getNameAsString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_S));
+ if (!OUTPUT_INTENT_DICTIONARY_VALUE_GTS_PDFA1.equals(sValue)) {
+ result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_S_VALUE_INVALID,
+ "The S entry of the OutputIntent isn't GTS_PDFA1"));
+ continue;
+ }
+
+ // ---- OutputConditionIdentifier is a mandatory field
+ String outputConditionIdentifier = dictionary
+ .getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_OUTPUT_CONDITION_IDENTIFIER));
+ if (outputConditionIdentifier == null) {// empty string is autorized (it may be an application specific value)
result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
- "The Info entry of a OutputIntent dictionary is missing"));
- continue;
- }
- }
- }
- }
- return result;
- }
-
- /**
- * This method checks the destOutputProfile which must be a valid ICCProfile.
- *
- * If an other ICCProfile exists in the mapDestOutputProfile, a
- * ValdiationError (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE) is
- * returned because of only one profile is authorized. If the ICCProfile
- * already exist in the mapDestOutputProfile, the method returns null. If the
- * destOutputProfile contains an invalid ICCProfile, a ValidationError
- * (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID) is returned If the
- * destOutputProfile is an empty stream, a
- * ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY) is returned.
- *
- * If the destOutputFile is valid, mapDestOutputProfile is updated, the
- * ICCProfile is added to the document handler and null is returned.
- *
- * @param destOutputProfile
- * @param cDoc
- * @param tmpDestOutputProfile
- * @param handler
- * @return
- * @throws ValidationException
- */
- protected ValidationError validateICCProfile(COSBase destOutputProfile,
- COSDocument cDoc, Map<COSObjectKey, Boolean> mapDestOutputProfile,
- DocumentHandler handler) throws ValidationException {
- try {
- if (destOutputProfile == null) {
- return new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
- "OutputIntent object uses a NULL Object");
- }
-
- // ---- destOutputProfile should be an instance of COSObject because of
- // this is a object reference
- if (destOutputProfile instanceof COSObject) {
- if (mapDestOutputProfile.containsKey(new COSObjectKey(
- (COSObject) destOutputProfile))) {
- // ---- the profile is already checked. continue
- return null;
- } else if (!mapDestOutputProfile.isEmpty()) {
- // ---- A DestOutputProfile exits but it isn't the same, error
- return new ValidationError(
- ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE, "More than one ICCProfile is defined");
- }
- // else the profile will be kept in the tmpDestOutputProfile if it is valid
- }
-
- PDStream stream = PDStream.createFromCOS(COSUtils.getAsStream(
- destOutputProfile, cDoc));
- if (stream == null) {
- return new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
- "OutputIntent object uses a NULL Object");
- }
-
- ICC_Profile iccp = ICC_Profile.getInstance(stream.getByteArray());
- // check the ICC Profile version (6.2.2)
- if (iccp.getMajorVersion() == 2) {
- if (iccp.getMinorVersion() > 0x20) {
- // in PDF 1.4, max version is 02h.20h (meaning V 3.5)
- return new ValidationError(
- ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_TOO_RECENT, "Invalid version of the ICCProfile");
- } // else OK
- } else if (iccp.getMajorVersion() > 2) {
- // in PDF 1.4, max version is 02h.20h (meaning V 3.5)
- return new ValidationError(
- ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_TOO_RECENT, "Invalid version of the ICCProfile");
- } // else seems less than 2, so correct
-
- if (handler.getIccProfileWrapper() == null) {
- handler.setIccProfileWrapper(new ICCProfileWrapper(iccp));
- }
-
- // ---- keep reference to avoid multiple profile definition
- mapDestOutputProfile.put(new COSObjectKey((COSObject) destOutputProfile),
- true);
-
- } catch (IllegalArgumentException e) {
- // ---- this is not a ICC_Profile
- return new ValidationError(
- ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID, "DestOutputProfile isn't a ICCProfile");
- } catch (IOException e) {
- throw new ValidationException("Unable to parse the ICC Profile", e);
- }
+ "The OutputIntentCondition is missing"));
+ continue;
+ }
+
+ // ---- If OutputConditionIdentifier is "Custom" or a non Standard ICC Characterization :
+ // ---- DestOutputProfile and Info are mandatory
+ // ---- DestOutputProfile must be a ICC Profile
+
+ // ---- Because of PDF/A conforming file needs to specify the color characteristics, the DestOutputProfile
+ // ---- is checked even if the OutputConditionIdentifier isn't "Custom"
+ COSBase dop = dictionary.getItem(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_DEST_OUTPUT_PROFILE));
+ ValidationError valer = validateICCProfile(dop, cDoc, tmpDestOutputProfile, handler);
+ if (valer != null) {
+ result.add(valer);
+ continue;
+ }
+
+ if (!isStandardICCCharacterization(outputConditionIdentifier)) {
+ String info = dictionary.getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_INFO));
+ if (info == null || "".equals(info)) {
+ result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
+ "The Info entry of a OutputIntent dictionary is missing"));
+ continue;
+ }
+ }
+ }
+ }
+ return result;
+ }
- return null;
- }
+ /**
+ * This method checks the destOutputProfile which must be a valid ICCProfile.
+ *
+ * If an other ICCProfile exists in the mapDestOutputProfile, a
+ * ValdiationError (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE) is
+ * returned because of only one profile is authorized. If the ICCProfile
+ * already exist in the mapDestOutputProfile, the method returns null. If the
+ * destOutputProfile contains an invalid ICCProfile, a ValidationError
+ * (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID) is returned If the
+ * destOutputProfile is an empty stream, a
+ * ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY) is returned.
+ *
+ * If the destOutputFile is valid, mapDestOutputProfile is updated, the
+ * ICCProfile is added to the document handler and null is returned.
+ *
+ * @param destOutputProfile
+ * @param cDoc
+ * @param tmpDestOutputProfile
+ * @param handler
+ * @return
+ * @throws ValidationException
+ */
+ protected ValidationError validateICCProfile(COSBase destOutputProfile,
+ COSDocument cDoc, Map<COSObjectKey, Boolean> mapDestOutputProfile,
+ DocumentHandler handler) throws ValidationException {
+ try {
+ if (destOutputProfile == null) {
+ return new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
+ "OutputIntent object uses a NULL Object");
+ }
+
+ // ---- destOutputProfile should be an instance of COSObject because of
+ // this is a object reference
+ if (destOutputProfile instanceof COSObject) {
+ if (mapDestOutputProfile.containsKey(new COSObjectKey(
+ (COSObject) destOutputProfile))) {
+ // ---- the profile is already checked. continue
+ return null;
+ } else if (!mapDestOutputProfile.isEmpty()) {
+ // ---- A DestOutputProfile exits but it isn't the same, error
+ return new ValidationError(
+ ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE, "More than one ICCProfile is defined");
+ }
+ // else the profile will be kept in the tmpDestOutputProfile if it is valid
+ }
+
+ PDStream stream = PDStream.createFromCOS(COSUtils.getAsStream(
+ destOutputProfile, cDoc));
+ if (stream == null) {
+ return new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY,
+ "OutputIntent object uses a NULL Object");
+ }
+
+ ICC_Profile iccp = ICC_Profile.getInstance(stream.getByteArray());
+ // check the ICC Profile version (6.2.2)
+ if (iccp.getMajorVersion() == 2) {
+ if (iccp.getMinorVersion() > 0x20) {
+ // TODO on lazy mode this error should be a warning?
+ // in PDF 1.4, max version is 02h.20h (meaning V 3.5)
+ return new ValidationError(
+ ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_TOO_RECENT, "Invalid version of the ICCProfile");
+ } // else OK
+ } else if (iccp.getMajorVersion() > 2) {
+ // TODO on lazy mode this error should be a warning?
+ // in PDF 1.4, max version is 02h.20h (meaning V 3.5)
+ return new ValidationError(
+ ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_TOO_RECENT, "Invalid version of the ICCProfile");
+ } // else seems less than 2, so correct
+
+ if (handler.getIccProfileWrapper() == null) {
+ handler.setIccProfileWrapper(new ICCProfileWrapper(iccp));
+ }
+
+ // ---- keep reference to avoid multiple profile definition
+ mapDestOutputProfile.put(new COSObjectKey((COSObject) destOutputProfile),
+ true);
+
+ } catch (IllegalArgumentException e) {
+ // ---- this is not a ICC_Profile
+ return new ValidationError(
+ ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID, "DestOutputProfile isn't a ICCProfile");
+ } catch (IOException e) {
+ throw new ValidationException("Unable to parse the ICC Profile", e);
+ }
+
+ return null;
+ }
}