EyeQ Docs
Getting started

C/C++ Quickstart

Getting started with Perfectly Clear SDK in C/C++

This guide walks you through correcting your first image using the Perfectly Clear SDK.

Project structure

Set up your project directory with the SDK extracted alongside your source files. Your project structure should look like this:

my-project/
├── main.cpp
├── Makefile
├── sample.jpg
└── perfectly-clear-sdk/
    └── Linux/
        ├── header/
        │   ├── PerfectlyClearPro.h
        │   └── PFCImageFile.h
        ├── bin/
        │   ├── libPerfectlyClearPro.a
        │   ├── libPFCImageFile.a
        │   ├── libwebp.a
        │   ├── liblcms2.so.2
        │   └── libexiv2.so.26
        └── sdk_license/
            └── (license files)

Activate the SDK license

Before processing images, activate your SDK license using PFC_SetProtectionPath(). Point it to the directory containing your license files.

#include "PerfectlyClearPro.h"

int licenseStatus = PFC_SetProtectionPath("./perfectly-clear-sdk/sdk_license");
if (licenseStatus == 0 || licenseStatus == 102 || licenseStatus == 103) {
    printf("SDK license activated successfully\n");
} else {
    printf("License activation failed (status: %d)\n", licenseStatus);
    return 1;
}

Status codes 0, 102 (active license), and 103 (active trial) indicate success. Any other code means that activation failed.

When you're done, call PFC_ReleaseProtectionPath() to release license resources.

Load an image

Use PFCImageFile to load an image from disk, then populate a PFCIMAGE structure for processing.

#include "PFCImageFile.h"

PFCImageFile imageFile;
if (imageFile.LoadImageFile("input.jpg", true, NULL) != LOAD_OK) {
    printf("Failed to load image\n");
    return 1;
}

PFCIMAGE image = {
    imageFile.width,
    imageFile.height,
    imageFile.stride,
    (PFCPIXELFORMAT)imageFile.pfcImageFormat(),
    imageFile.raw_image
};

The second parameter (true) converts the image to sRGB color space, which is recommended for best results.

Apply auto-correction

Create an engine, initialize correction parameters with a preset, and call PFC_AutoCorrect().

PFCENGINE* pEngine = PFC_CreateEngine();
PFCPARAM param;
PFC_SetParam(param, PRESET_VIVID);

int result = PFC_AutoCorrect(&image, NULL, param, -1, NULL, false, NULL, pEngine, false);
if (result < APPLY_SUCCESS) {
    printf("Correction failed: %d\n", result);
    PFC_DestroyEngine(pEngine);
    PFC_ReleaseProtectionPath();
    return 1;
}

PFC_DestroyEngine(pEngine);

Available presets include PRESET_VIVID for landscapes, PRESET_BEAUTIFY for portraits, and PRESET_IAUTO_21 for general photography.

Save output

Save the corrected image using SaveImageFile().

if (imageFile.SaveImageFile("output.jpg", 90, true, true)) {
    printf("Saved to: output.jpg\n");
} else {
    printf("Failed to save output\n");
    return 1;
}

Parameters are: output path, JPEG quality (0-100), convert back to original color space, and preserve metadata.

Complete example

Create main.cpp:

#include <stdio.h>

extern "C" {
#include "PerfectlyClearPro.h"
}
#include "PFCImageFile.h"

int main(int argc, char* argv[]) {
    if (argc < 3) {
        printf("Usage: %s <input.jpg> <output.jpg>\n", argv[0]);
        return 1;
    }

    const char* inputFile = argv[1];
    const char* outputFile = argv[2];

    // Activate SDK license
    int licenseStatus = PFC_SetProtectionPath("./perfectly-clear-sdk/sdk_license");
    if (licenseStatus == 0 || licenseStatus == 102 || licenseStatus == 103) {
        printf("SDK license activated successfully\n");
    } else {
        printf("License activation failed (status: %d)\n", licenseStatus);
        return 1;
    }

    // Load image
    PFCImageFile imageFile;
    if (imageFile.LoadImageFile(inputFile, true, NULL) != LOAD_OK) {
        printf("Failed to load image: %s\n", inputFile);
        return 1;
    }

    // Set up image structure
    PFCIMAGE image = {
        imageFile.width,
        imageFile.height,
        imageFile.stride,
        (PFCPIXELFORMAT)imageFile.pfcImageFormat(),
        imageFile.raw_image
    };

    // Apply auto correction
    PFCENGINE* pEngine = PFC_CreateEngine();
    PFCPARAM param;
    PFC_SetParam(param, PRESET_VIVID);

    int result = PFC_AutoCorrect(&image, NULL, param, -1, NULL, false, NULL, pEngine, false);
    if (result < APPLY_SUCCESS) {
        printf("Correction failed: %d\n", result);
        PFC_DestroyEngine(pEngine);
        PFC_ReleaseProtectionPath();
        return 1;
    }
    printf("Image corrected successfully\n");

    // Cleanup
    PFC_DestroyEngine(pEngine);
    PFC_ReleaseProtectionPath();

    // Save output
    if (imageFile.SaveImageFile(outputFile, 90, true, true)) {
        printf("Saved to: %s\n", outputFile);
    } else {
        printf("Failed to save: %s\n", outputFile);
        return 1;
    }

    return 0;
}

Create Makefile:

CC = g++
SDK_ROOT = ./perfectly-clear-sdk
SDK_BIN = $(SDK_ROOT)/Linux/bin
SDK_HEADER = $(SDK_ROOT)/Linux/header

CFLAGS = -O2 -pthread -D_LINUX -I$(SDK_HEADER) -Wl,-R'$$ORIGIN/perfectly-clear-sdk/Linux/bin'

all: quick-cpp copy-deps

quick-cpp: main.cpp
	$(CC) $(CFLAGS) -m64 -o $@ main.cpp \
		$(SDK_BIN)/libPerfectlyClearPro.a \
		$(SDK_BIN)/libPFCImageFile.a \
		$(SDK_BIN)/libwebp.a \
		$(SDK_BIN)/liblcms2.so.2 \
		$(SDK_BIN)/libexiv2.so.26 \
		-ldl

copy-deps:
	@echo "Copying dependencies..."
	cp $(SDK_BIN)/liblcms2.so.2 .
	cp $(SDK_BIN)/libexiv2.so.26 .
	@echo "Build complete!"

clean:
	rm -f quick-cpp *.so*

.PHONY: all copy-deps clean

A sample image is included in the SDK at docs sample image, or you can use any JPEG image of your choice.

Build and run:

make
./quick-cpp sample.jpg corrected.jpg

Expected output:

Copying dependencies...
Build complete!
SDK license activated successfully
Image corrected successfully
Saved to: output.jpg

PFC-SDK Version 10.7.2.1269 built from 4fa849d8101945eea725a08dd0dae5101f090fa0 on 11-10-2025.

Copyright © 2026 EyeQ Imaging Inc. All rights reserved.

On this page