Skip to content
⚡ Developer documentation for INFINICAM, the real-time high-speed camera (UC-1.1 / GbE-2)

Creating the SingleImage (Color) Project

These are the steps to create a program that captures one frame of compressed data from a GbE-2 (color model), performs Bayer conversion (debayering) and white balance adjustment to decode it in color, and saves it as a file in the PPM format (Portable Pixmap), which can be viewed with standard image viewing software.

  1. Write the source code

    Open the main file (e.g. GbE2_SingleImageColor.cpp) and replace its contents with the following code.

    #include <stdio.h>
    #include <stdlib.h>
    #include <PUCLIB.h> // Load the PUCLIB header
    int main() {
    printf("Starting INFINICAM GbE-2 SingleImage (Color) capture...\n");
    // 1. Initialize the SDK
    PUCRESULT ret = PUC_Initialize();
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to initialize the SDK. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 2. Search for a GbE-2 device on the network
    PUC_DETECT_FILTER filter = { 0 };
    filter.nDeviceTypeFlags = PUC_DETECT_TARGET_GBE2; // Specify GbE-2
    PUC_DETECT_INFO detectInfo = { 0 };
    ret = PUC_DetectDevice2(&filter, &detectInfo);
    if (ret != PUC_SUCCEEDED || detectInfo.nDeviceCount == 0) {
    printf("Error: No GbE-2 camera was found. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 3. Open the first detected device
    PUC_HANDLE hDevice = NULL;
    ret = PUC_OpenDevice2(0, &hDevice);
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to open the device. ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 4. Determine the color model and set the white balance gains
    PUC_COLOR_TYPE colorType = PUC_COLOR_MONO;
    PUC_GetColorType(hDevice, &colorType);
    if (colorType != PUC_COLOR_COLOR) {
    printf("Note: The connected camera was detected as a monochrome model.\n");
    }
    // Set the white balance gain for each of the R, G, and B channels (1.0 = no change)
    PUC_SetWhiteBalanceGain(1.0, 1.0, 1.0);
    // 5. Get the resolution
    UINT32 width = 0, height = 0;
    ret = PUC_GetResolution(hDevice, &width, &height);
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to get the resolution. ErrorCode: %d\n", ret);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    printf("Resolution: %u x %u pixels (color)\n", width, height);
    // 6. Retrieve the quantization table in bulk (used for decoding)
    unsigned short qVals[PUC_Q_COUNT] = { 0 };
    ret = PUC_GetQuantization2(hDevice, qVals);
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to get the quantization table. ErrorCode: %d\n", ret);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    // 7. Get the transfer data size and allocate buffers
    UINT32 xferDataSize = 0;
    ret = PUC_GetXferDataSize(hDevice, &xferDataSize);
    if (ret != PUC_SUCCEEDED) {
    printf("Error: Failed to get the transfer data size. ErrorCode: %d\n", ret);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    // Allocate the buffer to store the compressed data
    unsigned char* pCompressedBuffer = (unsigned char*)malloc(xferDataSize);
    // Allocate the buffer to store the color-decoded data (RGB 24-bit = 3 bytes per pixel)
    // Align the row byte count (width * 3) to a 4-byte boundary
    UINT32 lineBytes = ((width * 3) + 3) & ~3;
    unsigned long decodedBufferSize = (unsigned long)lineBytes * height;
    unsigned char* pDecodedBuffer = (unsigned char*)malloc(decodedBufferSize);
    if (pCompressedBuffer == NULL || pDecodedBuffer == NULL) {
    printf("Error: Memory allocation failed.\n");
    free(pCompressedBuffer);
    free(pDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    // 8. Capture one frame of data
    PUC_XFER_DATA_INFO xferDataInfo = { 0 };
    xferDataInfo.pData = pCompressedBuffer;
    xferDataInfo.nDataSize = xferDataSize;
    printf("Capturing one frame...\n");
    ret = PUC_GetSingleXferData(hDevice, &xferDataInfo);
    if (ret == PUC_SUCCEEDED) {
    // 9. Decode the compressed data in color
    // The SDK automatically applies Bayer conversion (debayering) and white balance adjustment internally,
    // and expands the data as RGB data (1 pixel = 3 bytes).
    ret = PUC_DecodeData(pDecodedBuffer, 0, 0, width, height, lineBytes, pCompressedBuffer, qVals);
    if (ret == PUC_SUCCEEDED) {
    // 10. Save the decoded color image in PPM (P6) format
    const char* filename = "captured_color_image.ppm";
    FILE* fp = NULL;
    if (fopen_s(&fp, filename, "wb") == 0 && fp != NULL) {
    // Write the PPM header (P6 / width / height / max gray value 255)
    fprintf(fp, "P6\n%u %u\n255\n", width, height);
    // Write the valid color image data (RGB 3 bytes/px) one row at a time
    for (UINT32 y = 0; y < height; y++) {
    fwrite(pDecodedBuffer + (y * lineBytes), sizeof(unsigned char), width * 3, fp);
    }
    fclose(fp);
    printf("SUCCESS: Saved the PPM color image file (%s)\n", filename);
    } else {
    printf("Error: Failed to save the file.\n");
    }
    } else {
    printf("Error: Failed to decode the image data. ErrorCode: %d\n", ret);
    }
    } else {
    printf("Error: Failed to capture the image data. ErrorCode: %d\n", ret);
    }
    // 11. Free the memory and close the device
    free(pCompressedBuffer);
    free(pDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_SUCCESS;
    }
  2. Build and run

    1. Press Ctrl + Shift + B to build the project.
    2. Make sure puclib.dll and related files are placed in the same folder as the executable (.exe).
    3. Run with Ctrl + F5. If captured_color_image.ppm is generated directly under the project folder, it has succeeded.

The PPM (Portable Pixmap) format is an uncompressed full-color image format standardized by the Netpbm project. It consists of a text-based header and binary pixel data with 8 bits per RGB channel (24-bit color total).

P6
800 600
255
[Binary RGB pixel data (width x height x 3 bytes)]
  1. Magic number (P6): Indicates that this is a binary full-color (RGB 24-bit) image.
  2. Image width and height: Specifies the resolution in pixels, e.g. 800 600.
  3. Maximum brightness value (255): Specifies the maximum gray level of each color channel (R, G, B).
  4. Pixel data: Immediately after the newline, the brightness data follows as-is in R, G, B order (1 pixel = 3 bytes).