ImageGear for C and C++ on Windows v21.0 - Updated
User Guide / How to Work with ... / Formats with Additional Functionality / PDF / How to... / Work with PDF Format Compliance / Verify PDF Format Compliance
In This Topic
    Verify PDF Format Compliance
    In This Topic

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