Perfectly Clear SDK Documentation  9.1.1.325
Examples (OSX / Linux)

Sample source code is provided in this SDK for three applications that are ready to build on linux systems. These three examples each show different usage models and provide a starting point for adapting these into ready-for-production command line applications. These example applications are:

Sample1 - AutoCorrect

This is the most simple way to get started with this SDK. This sample application will correct the JPG or PNG file with one of 5 build-in presets. This sample uses the PFC_AutoCorrect() function.

Sample2 - Reading .preset files

This sample allows reading .preset files created with Perfectly Clear Workbench or Perfectly Clear Complete, and will apply the parameters found in that .preset file to the image provided in the first command line argument. This sample uses separate PFC_Calc() and PFC_Apply() function calls, so it is slightly less efficient if only a single correction will be applied to the image.

Resize Sample - Correct and Resize the image

Scenario #1 - Using PCF_AutoCorrect

The simplest way to use Perfectly Clear library suite.

  1. Setup the license protection
    // if you have a license key, then call PFC_SetProtectionPath with the path
    // to your license files
    int code = PFC_SetProtectionPath("/home/user/sdk_license");
    if (bVerbose)
    printf("License Code Status is %d\n", code);
  2. Populate image data into PFCIMAGE structure:
    // Populate image information into PFCIMAGE structure.
    im.width = originalImageFile.width; // Width of image
    im.height = originalImageFile.height; // Height of image
    im.stride = originalImageFile.stride; // Stride of image
    im.format = (PFCPIXELFORMAT)originalImageFile.pfcImageFormat(); // PFC_PixelFormat24bppBGR (RGBRG..) if jpeg
    im.data = originalImageFile.raw_image; // Location of image data buffer
  3. Initialize the parameter structure:
    // Declaration of PFCPARAM.
    PFCPARAM param;
    // Initialize process parameters. If presetID is left blank, default to using Intelligent Auto preset.
    PFC_SetParam(param, (PFCPRESETID)presetID);
  4. Perform full correction using the auto function:
    // Process image.
    int status = PFC_AutoCorrect(&im, NULL, param, -1, NULL, FALSE, bVerbose? myStatus : NULL);
    // Optional display of process status.
    if (bVerbose)
    {
    if (status == 0)
    {
    printf("Image processed successfully\n");
    }
    else if (status > 0)
    {
    printf(" Pre-calculation on noise returns %d\n", PFCNR_STATUS(status));
    printf(" Core pre-calculation returns %d\n", PFCCORE_STATUS(status));
    printf(" Pre-calculation on face details returns %d\n",PFCFB_STATUS(status));
    printf(" Pre-calculation on red eye returns %d\n", PFCRE_STATUS(status));
    }
    else if (status < 0)
    {
    printf("Image processed failed with return code: %d\n", status);
    }
    }

Scenario #2 - Separate PFC_Calc and PFC_Apply

More advanced way to use Perfectly Clear library suite.

  1. Setup the license protection
    // if you have a license key, then call PFC_SetProtectionPath with the path
    // to your license files
    int code = PFC_SetProtectionPath("/home/user/sdk_license");
    if (bVerbose)
    printf("License Code Status is %d\n", code);
  2. Create a single engine that can be re-used on many images:
    // Create PFCENGINE instance for use in this session.
    // Optional display of status.
    if (bVerbose)
    {
    if (pEngine->status == ENGINESTATUS_OK)
    {
    printf("Engine created successfully.\n");
    }
    else
    {
    {
    printf("Face Beautification library not available.");
    }
    }
    }
  3. Initialize the parameter structure (using default parameter values): The parameters can be imported from a preset file.
    // Optionally, the process parameters can be imported from a .preset file.
    // (The .preset file can be exported from Athentech's desktop applications. e.g. Workbench.)
    int ret = PFC_ReadPresets(param, profilename);
    if (bVerbose)
    printf("PFC_ReadPresets returns %d\n", ret);
    Alternatively the parameters can be initialized using PFC_SetParam() function.
    // Use default parameters.
    PFC_SetParam(param);
    Example:
    PFCPARAM param;
    if (profilename != NULL)
    {
    // Optionally, the process parameters can be imported from a .preset file.
    // (The .preset file can be exported from Athentech's desktop applications. e.g. Workbench.)
    int ret = PFC_ReadPresets(param, profilename);
    if (bVerbose)
    printf("PFC_ReadPresets returns %d\n", ret);
    if (ret != 0)
    {
    if (ret == -2) // preset file not found
    {
    // Use default parameters if preset file not found.
    PFC_SetParam(param);
    printf("Unable to open preset file %s. Using default settings.\n", argv[3]);
    }
    else
    {
    printf("Unable to read preset file.\n");
    exit(1);
    }
    }
    }
    else
    {
    // Use default parameters.
    PFC_SetParam(param);
    }
  4. Populate image data into PFCIMAGE structure:
    // Populate image information into PFCIMAGE structure.
    im.width = originalImageFile.width; // Width of image
    im.height = originalImageFile.height; // Height of image
    im.stride = originalImageFile.stride; // Stride of image
    im.format = (PFCPIXELFORMAT)originalImageFile.pfcImageFormat(); // PFC_PixelFormat24bppBGR (RGBRG..) if jpeg
    im.data = originalImageFile.raw_image; // Location of image data buffer
  5. Perform pre-calculation of image specific profile. pEngine is created from step 1 and used here in the PFC_Calc function
    // Analyze image and obtain image specific profile.
    PFCPROFILE pProfile = PFC_Calc(&im, NULL, pEngine, CALC_ALL, -1, NULL, NULL, bVerbose? myStatus : NULL);
    // Optional display of status.
    if (bVerbose)
    {
    if (pProfile->Status != 0)
    {
    if (pProfile->Status & CALC_NR)
    {
    printf(" Pre-calculation on noise returns %d\n", pProfile->NR_Status);
    }
    if (pProfile->Status & CALC_CORE)
    {
    printf(" Core pre-calculation returns %d\n", pProfile->CORE_Status);
    }
    if (pProfile->Status & CALC_FB)
    {
    printf(" Pre-calculation on face details returns %d\n", pProfile->FB_Status);
    }
    if (pProfile->Status & CALC_RE)
    {
    printf(" Pre-calculation on red eye returns %d\n", pProfile->RE_Status);
    }
    }
    printf("Calc returns %d\n", pProfile->Status);
    }
  6. Apply the calculated profile and parameters to the image.
    // Process image with user parameters.
    PFCAPPLYSTATUS status = PFC_Apply(&im, pEngine, pProfile, param, bVerbose? myStatus : NULL);
    // Optional display of status.
    if (status == APPLY_SUCCESS && bVerbose)
    {
    printf("Image processed successfully.\n");
    }
    else if (status > APPLY_SUCCESS && bVerbose)
    {
    // Check return code for Noise Removal
    printf("Noise removal status %d\n", NRRETCODE(status));
    // Check return code for Perfectly Clear Core correction
    printf("Perfectly Clear correction status %d\n", CORERETCODE(status));
    // Check return code for Face Beautification
    printf("Face beautification status %d\n", FBRETCODE(status));
    // Check return code for Red Eye Removal
    printf("Red eye removal status %d\n", RERETCODE(status));
    }
    else if (status < APPLY_SUCCESS )
    {
    printf("Image processing failed with return code: %d\n", status);
    }
  7. Release resources used by PFCPROFILE:
    // Release Profile
    PFC_ReleaseProfile(pProfile);
  8. Release the engine to release resource. Or, keep the engine around for use on another image.
    // Destroy engine. It is important that PFCENGINE is destroyed after
    // all the profiles are released.

Scenario #3 - Resize and Correct

This sample loads and corrects the image exactly like in Sample 1, but this resized the output images:

// Allocate a destination image with the final dimensions you want after resizing
// Setting width, height, bytes per pixel, stride
PFCImageFile fileResized(800, 600, 3, 3 * 800);
// Populate PFCIMAGE struct
PFCIMAGE imageResized;
imageResized.width = fileResized.width;
imageResized.height = fileResized.height;
imageResized.stride = fileResized.stride;
imageResized.data = fileResized.raw_image;
// Perform the resizing
status = (PFCAPPLYSTATUS)PFC_Resize(&im, &imageResized);
if (status == APPLY_SUCCESS) {
// Save resized image
char outResized[1000];
sprintf(outResized, "%s.%dx%d.jpg", inname, imageResized.width, imageResized.height);
fileResized.SaveImageFile(outResized, 90, false, false);
}