User Guide > How to Work with... > Formats with Additional Functionality > PDF > How to... > Work with PDF Format Compliance > Verify PDF Format Compliance |
Before working with a PDF document, make sure to initialize the PDF component (see Getting Started with PDF). |
ImageGear can determine that a PDF document was created in compliance with either PDF/A or PDF/X standards. This compliance check does not change the original PDF document; it just analyzes the content of a PDF document and reports violations.
PDF annotations can only be verified while they reside in a PDF document. Loading PDF annotations to ART will detach them from the PDF document and make them unavailable for PDF/A or PDF/X compliance validation. |
First, create a preflight object with the IG_PDF_preflight_create function.
Next, validate the PDF document using the IG_PDF_preflight_verify_compliance function, indicating the target ISO PDF standard with an enumIGPDFPreflightProfile value. Successful completion produces a preflight report, accessed with the returned HIG_PDF_PREFLIGHT_REPORT handle.
Retrieve the preflight report code using the IG_PDF_preflight_report_get_code function. Optionally, retrieve the preflight report description using the IG_PDF_preflight_report_get_description function as follows:
C |
Copy Code
|
---|---|
AT_INT bytesNeeded = 0; AT_CHAR* textBuffer = NULL; // Retrieve the PDF preflight report's description. First, query the minimum number of // bytes required to copy the description text. IG_PDF_preflight_report_get_description(pdfPreflightReport, NULL, &bytesNeeded); // Next, allocate a sufficiently sized character buffer to receive the description text. textBuffer = (AT_CHAR*)malloc(bytesNeeded); memset(textBuffer, '\0', bytesNeeded); // Finally, copy the description text into the buffer. IG_PDF_preflight_report_get_description(pdfPreflightReport, textBuffer, &bytesNeeded); |
C++ |
Copy Code
|
---|---|
// Retrieve the PDF preflight report's description. First, query the minimum number of // bytes required to copy the description text. AT_INT bytesNeeded = 0; IG_PDF_preflight_report_get_description(pdfPreflightReport, NULL, &bytesNeeded); // Next, allocate a sufficiently sized character buffer to receive the description text. std::vector<AT_CHAR> textBuffer(bytesNeeded, '\0'); // Finally, copy the description text into the buffer. IG_PDF_preflight_report_get_description(pdfPreflightReport, &textBuffer[0], &bytesNeeded); |
When a PDF is determined compliant to the chosen preflight profile, preflight report code equals IG_PDF_PREFLIGHT_SUCCESS. Refer to enumIGPDFPreflightReportCodes for other possible report codes.
Finally, release the preflight object using the IG_PDF_preflight_delete function.
The following example illustrates how a PDF document can be verified for compliance with PDF/A-1b:2005:
C |
Copy Code
|
---|---|
AT_BOOL IsCompliantToPDFA1B2005(AT_CHAR* pdfPath) { HMIGEAR document = 0; HIG_PDF_DOC pdfDoc = 0; HIG_PDF_PREFLIGHT pdfPreflight = 0; HIG_PDF_PREFLIGHT_REPORT pdfReport = 0; AT_INT reportCode = IG_PDF_PREFLIGHT_INCOMPLIANT_DOCUMENT; // Open first PDF document. IG_mpi_create(&document, 0); IG_mpi_file_open(pdfPath, document, IG_FORMAT_PDF, IG_MP_OPENMODE_READWRITE); IG_mpi_info_get(document, IG_MP_DOCUMENT, &pdfDoc, sizeof(HIG_PDF_DOC)); // Create preflight object. IG_PDF_preflight_create(pdfDoc, &pdfPreflight); // Verify compliance to PDF/A-1B:2005. IG_PDF_preflight_verify_compliance(pdfPreflight, IG_PDF_PREFLIGHT_PROFILE_PDFA_1B_2005, 0, -1, &pdfReport); IG_PDF_preflight_report_get_code(pdfReport, &reportCode); // Release the preflight report. IG_PDF_preflight_report_delete(pdfReport); // Release the preflight object. IG_PDF_preflight_delete(pdfPreflight); // Release the PDF document. IG_mpi_delete(document); return (IG_PDF_PREFLIGHT_SUCCESS == reportCode ? TRUE : FALSE); } |
C++ |
Copy Code
|
---|---|
AT_BOOL IsCompliantToPDFA1B2005(LPSTR pdfPath) { // Open first PDF document. HMIGEAR document = 0; IG_mpi_create(&document, 0); IG_mpi_file_open(pdfPath, document, IG_FORMAT_PDF, IG_MP_OPENMODE_READWRITE); HIG_PDF_DOC pdfDoc = 0; IG_mpi_info_get(document, IG_MP_DOCUMENT, &pdfDoc, sizeof(HIG_PDF_DOC)); // Create preflight object. HIG_PDF_PREFLIGHT pdfPreflight = 0; IG_PDF_preflight_create(pdfDoc, &pdfPreflight); // Verify compliance to PDF/A-1B:2005. HIG_PDF_PREFLIGHT_REPORT pdfReport = 0; IG_PDF_preflight_verify_compliance(pdfPreflight, IG_PDF_PREFLIGHT_PROFILE_PDFA_1B_2005, 0, -1, &pdfReport); AT_INT reportCode = IG_PDF_PREFLIGHT_INCOMPLIANT_DOCUMENT; IG_PDF_preflight_report_get_code(pdfReport, &reportCode); // Release the preflight report. IG_PDF_preflight_report_delete(pdfReport); // Release the preflight object. IG_PDF_preflight_delete(pdfPreflight); // Release the PDF document. IG_mpi_delete(document); return (IG_PDF_PREFLIGHT_SUCCESS == reportCode ? TRUE : FALSE); } |
To detail specific preflight noncompliance, if any, traverse the preflight report. The preflight report is organized as a tree of records. Starting with the first HIG_PDF_PREFLIGHT_REPORT returned from the IG_PDF_preflight_verify_compliance function, determine its child count using the IG_PDF_preflight_report_get_record_count function. Use the IG_PDF_preflight_report_get_record function to retrieve each of its child HIG_PDF_PREFLIGHT_REPORT handles. Repeat this sequence with each child handle retrieved.
The following example illustrates how to print a compliance report to stdout:
C |
Copy Code
|
---|---|
void PrintComplianceReportToStdoutRecursive(HIG_PDF_PREFLIGHT_REPORT currentRecord) { AT_INT pdfPreflightReportCode = IG_PDF_PREFLIGHT_INCOMPLIANT_DOCUMENT; AT_CHAR* textBuffer = NULL; AT_INT bytesNeeded = 0; AT_INT recordCount = 0; AT_INT i = 0; // Retrieve the current PDF preflight report code. IG_PDF_preflight_report_get_code(currentRecord, &pdfPreflightReportCode); // Retrieve the current PDF preflight report description. First, query the minimum number of // bytes required to copy the description text. IG_PDF_preflight_report_get_description(currentRecord, NULL, &bytesNeeded); // Next, allocate a sufficiently sized buffer to receive the description text. textBuffer = (AT_CHAR*)malloc(bytesNeeded); memset(textBuffer, '\0', bytesNeeded); // Finally, copy the description text into the buffer. IG_PDF_preflight_report_get_description(currentRecord, textBuffer, &bytesNeeded); // Print a message to stdout to describe the current record. fprintf(stdout, "Code: %d, Description: %s\n", pdfPreflightReportCode, textBuffer); // Recursively describe its child records. IG_PDF_preflight_report_get_record_count(currentRecord, &recordCount); for (i = 0; i < recordCount; i++) { HIG_PDF_PREFLIGHT_REPORT nextRecord = 0; IG_PDF_preflight_report_get_record(currentRecord, i, &nextRecord); PrintComplianceReportToStdoutRecursive(nextRecord); } free(textBuffer); } void PrintPdfa1B2005ComplianceReportToStdout(AT_CHAR* pdfFilePath) { HMIGEAR document = 0; HIG_PDF_DOC pdfDoc = 0; HIG_PDF_PREFLIGHT pdfPreflight = 0; HIG_PDF_PREFLIGHT_REPORT pdfPreflightReport = 0; // Open the PDF document from a file. IG_mpi_create(&document, 0); IG_mpi_file_open(pdfFilePath, document, IG_FORMAT_PDF, IG_MP_OPENMODE_READWRITE); IG_mpi_info_get(document, IG_MP_DOCUMENT, &pdfDoc, sizeof(HIG_PDF_DOC)); // Create the PDF preflight object. IG_PDF_preflight_create(pdfDoc, &pdfPreflight); // Verify the PDF's compliance to PDF/A-1B:2005. IG_PDF_preflight_verify_compliance(pdfPreflight, IG_PDF_PREFLIGHT_PROFILE_PDFA_1B_2005, 0, -1, &pdfPreflightReport); // Print the compliance report to stdout. PrintComplianceReportToStdoutRecursive(pdfPreflightReport); // Release the PDF preflight report object. IG_PDF_preflight_report_delete(pdfPreflightReport); // Release the PDF preflight object. IG_PDF_preflight_delete(pdfPreflight); // Release the PDF document. IG_mpi_delete(document); } |
C++ |
Copy Code
|
---|---|
void PrintComplianceReportToStdoutRecursive(HIG_PDF_PREFLIGHT_REPORT currentRecord) { // Retrieve the current PDF preflight report code. AT_INT pdfPreflightReportCode = IG_PDF_PREFLIGHT_INCOMPLIANT_DOCUMENT; IG_PDF_preflight_report_get_code(currentRecord, &pdfPreflightReportCode); // Retrieve the current PDF preflight report description. First, query the minimum number of // bytes required to copy the description text. AT_INT bytesNeeded = 0; IG_PDF_preflight_report_get_description(currentRecord, NULL, &bytesNeeded); // Next, allocate a sufficiently sized buffer to receive the description text. std::vector<AT_CHAR> textBuffer(bytesNeeded, '\0'); // Finally, copy the description text into the buffer. IG_PDF_preflight_report_get_description(currentRecord, &textBuffer[0], &bytesNeeded); // Print a message to stdout to describe the current record. std::cout << "Code: " << pdfPreflightReportCode << ", " << "Description: " << &textBuffer[0] << std::endl; // Recursively describe its child records. AT_INT recordCount = 0; IG_PDF_preflight_report_get_record_count(currentRecord, &recordCount); for (AT_INT i = 0; i < recordCount; i++) { HIG_PDF_PREFLIGHT_REPORT nextRecord = 0; IG_PDF_preflight_report_get_record(currentRecord, i, &nextRecord); PrintComplianceReportToStdoutRecursive_CC(nextRecord); } } void PrintPdfa1B2005ComplianceReportToStdout(AT_CHAR* pdfFilePath) { // Open the PDF document from a file. HMIGEAR document = 0; IG_mpi_create(&document, 0); IG_mpi_file_open(pdfFilePath, document, IG_FORMAT_PDF, IG_MP_OPENMODE_READWRITE); HIG_PDF_DOC pdfDoc = 0; IG_mpi_info_get(document, IG_MP_DOCUMENT, &pdfDoc, sizeof(HIG_PDF_DOC)); // Create the PDF preflight object. HIG_PDF_PREFLIGHT pdfPreflight = 0; IG_PDF_preflight_create(pdfDoc, &pdfPreflight); // Verify the PDF's compliance to PDF/A-1B:2005. HIG_PDF_PREFLIGHT_REPORT pdfPreflightReport = 0; IG_PDF_preflight_verify_compliance(pdfPreflight, IG_PDF_PREFLIGHT_PROFILE_PDFA_1B_2005, 0, -1, &pdfPreflightReport); // Print the compliance report to stdout. PrintComplianceReportToStdoutRecursive(pdfPreflightReport); // Release the PDF preflight report object. IG_PDF_preflight_report_delete(pdfPreflightReport); // Release the PDF preflight object. IG_PDF_preflight_delete(pdfPreflight); // Release the PDF document. IG_mpi_delete(document); } |