ImageGear for C and C++ on Linux v19.10 - Updated
Verify PDF Format Compliance
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);
}