EyeQ Docs

PDF processing

Correct images embedded in PDF files

The PDF samples demonstrate how to extract images from PDF files, apply corrections, embed the corrected image back into the PDF, and save the modified PDF. This is useful for photo books, or any PDF containing images that would benefit from enhancement. This requires that the PDF content is "layered" - saved with the images as separate objects rather than flattened into a single layer. The sample uses the PFCPDFImageIterator class to access and modify images within the PDF structure.

Key functions

A summary of key functions and purposes:

FunctionPurpose
PFCPDFImageIterator::loadOpen a PDF file for processing
PFCPDFImageIterator::nextImageGet the next image from the PDF
PFCPDFImageIterator::saveWrite the modified PDF to disk
PFCPDFImage::imageFileAccess the image data for correction

C/C++ implementation

The following excerpts are from PDF_Sample.cpp.

Load the PDF file

Open the PDF file using the iterator. The load function returns a status code indicating success or failure.

#include "PFCPDFImageIterator.h"
#include "PFCPDFImage.h"

PFCPDFImageIterator file;

// Open the PDF file
if (file.load(inputPath) != PFCPDFImageIterator::LoadStatus::Ok) {
    printf("Cannot load PDF: %s\n", inputPath);
    return 1;
}

Iterate and correct images

Loop through all images in the PDF using nextImage(). Each call returns a PFCPDFImage object containing the unpacked image data that you can correct like any other image.

// Create correction engine
PFCENGINE *pEngine = PFC_CreateEngine();
PFC_LoadAIEngine(pEngine, 
    AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, 
    binPath.c_str());

// Process each image in the PDF
while (PFCPDFImage* pdfImage = file.nextImage()) {
    // Access the image data
    PFCImageFile* imgFile = pdfImage->imageFile;
    
    // Set up PFCIMAGE struct
    PFCIMAGE im;
    im.width = imgFile->width;
    im.height = imgFile->height;
    im.stride = imgFile->stride;
    im.format = (PFCPIXELFORMAT)imgFile->pfcImageFormat();
    im.data = imgFile->raw_image;
    
    //setup Engine and apply auto corrections
    PFCENGINE* pEngine = PFC_CreateEngine();
    // Load AI engine (assuming all dlls and models are in exe folder):
    std::string exePath = std::string(argv[0]);
    std::string binPath = exePath.substr(0, exePath.find_last_of('/')).c_str();
    int aistatus  = PFC_LoadAIEngine(pAiEngine, AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, binPath.c_str());

    // We set params within AutoCorrect(), so this can start out empty.
    PFCPARAM ignoredParam;

    int result = PFC_AutoCorrect(&image, NULL, ignoredParam, -1, NULL, false, NULL, pEngine, false);
    printf("Image corrected with status: %d\n", result);
    
    // Release profile (image data is modified in place)
    PFC_ReleaseProfile(pProfile);
}

PFC_DestroyEngine(pEngine);

Save the modified PDF

After processing all images, save the PDF with the corrected images embedded.

if (file.save(outputPath) != PFCPDFImageIterator::SaveStatus::Ok) {
    printf("Cannot save PDF: %s\n", outputPath);
    return 1;
}

Complete workflow

The full workflow loads, processes, and saves in sequence.

// 1. Load PDF
PFCPDFImageIterator file;
file.load("input.pdf");

// 2. Set up correction engine
// Create correction engine
PFCENGINE *pEngine = PFC_CreateEngine();
PFC_LoadAIEngine(pEngine, 
    AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, 
    binPath.c_str());

// 3. Process each image in the PDF
while (PFCPDFImage* pdfImage = file.nextImage()) {
    // Access the image data
    PFCImageFile* imgFile = pdfImage->imageFile;
    
    // Set up PFCIMAGE struct
    PFCIMAGE im;
    im.width = imgFile->width;
    im.height = imgFile->height;
    im.stride = imgFile->stride;
    im.format = (PFCPIXELFORMAT)imgFile->pfcImageFormat();
    im.data = imgFile->raw_image;
    
    //setup Engine and apply auto corrections
    PFCENGINE* pEngine = PFC_CreateEngine();
    // Load AI engine (assuming all dlls and models are in exe folder):
    std::string exePath = std::string(argv[0]);
    std::string binPath = exePath.substr(0, exePath.find_last_of('/')).c_str();
    int aistatus  = PFC_LoadAIEngine(pAiEngine, AI_SCENE_DETECTION | AI_CORRECTIONS | AI_COLOR | AI_FACEMESH, binPath.c_str());

    // We set params within AutoCorrect(), so this can start out empty.
    PFCPARAM ignoredParam;

    int result = PFC_AutoCorrect(&image, NULL, ignoredParam, -1, NULL, false, NULL, pEngine, false);
    printf("Image corrected with status: %d\n", result);
    
    // Release profile (image data is modified in place)
    PFC_ReleaseProfile(pProfile);
}

PFC_DestroyEngine(pEngine);
file.save("output.pdf");

Important notes

The nextImage() function returns images one at a time. When you call nextImage() again, the previous image's memory may be reused. Process each image completely before moving to the next.

The corrections are applied in place to the image data. When you call save(), the PDF is written with all the corrected images.

Source files

You can find the code snippets in the following files:

PlatformSamplePath
Linux/macOSPDFSampleLinux/PDFSample/PDF_Sample.cpp
WindowsPDFSampleWin/PDFSample/PDFSample.cpp

PDF processing requires the PFCPDF library (libPFCPDF.so on Linux, PFCPDF.dll on Windows). Make sure this library is available in your build environment.

PFC-SDK Version 10.7.3.1317 built from df9dbc8727c92fb9b1d2c68b21e60ea9c7229e1a on 03-23-2026.

Copyright © 2026 EyeQ Imaging Inc. All rights reserved.

On this page