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;
+	}
 }