Verify PDF Format Compliance
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);
}
|