Getting image data from a declared C function into Xojo

The following is some C code from a test application that verifies a DLL is working correctly. We had the DLL ported to mac. The data is an image in a buffer on a frame grabber board. This code was given to me by the frame grabber manufacturer. We’re importing a dylib that contains the functions called in this code. I need to figure out how to get the results of this into something I can manipulate in Xojo

 // Get data
    uint32_t r, c, bpp;
    ret = GetBufferSize(&h, &r, &c, &bpp);
    std::cout << "-GetBufferSize row = " << r << " col = " << c << " bpp = " << bpp << " reply " << ret << std::endl;
    uint16_t tc = 0xabcd;
    uint64_t ts = 0x123456789abcdef;
    if (bpp == 4)
    {
        unsigned int * buf = (unsigned int*)malloc((size_t)r*c * 4);
        ret = GetBufferRGB32(&h, buf, &ts,&tc); // labview does not support **
        std::cout << "--GetBufferRGB32 = " << (size_t) buf << " ts = " << ts << " tc = " << tc << " reply " << ret << std::endl;
        
        printStatus(h);
        Sleep(100);
        ret = GetBufferRGB32(&h, buf, &ts, &tc);    // labview does not support **
        std::cout << "--GetBufferRGB32 = " << (size_t)buf << " ts = " << ts << " tc = " << tc << " reply " << ret << std::endl;

        printStatus(h);
        free(buf);
    }
    else if (bpp == 2)
    {
        unsigned short * buf = (unsigned short*)malloc((size_t)r*c * 2);
        ret = GetBufferY16(&h, buf, &ts, &tc);  // labview does not support **
        std::cout << "--GetBufferY16 = " << (size_t)buf << " ts = " << ts << " tc = " << tc << " reply " << ret << std::endl;
        
        printStatus(h);
        Sleep(100);
        ret = GetBufferY16(&h, buf, &ts, &tc);  // labview does not support **
        std::cout << "--GetBufferY16 = " << (size_t)buf << " ts = " << ts << " tc = " << tc << " reply " << ret << std::endl;
        
        printStatus(h);
        free(buf);
    }

In my case bpp=2 so I’ll be using GetBufferY16(), and need to get the image data in that buffer into Xojo.

&h is a handle to the frame buffer, which I have access to as ‘handle’
r is a count of the number of rows in the image, which I have as ‘row’
c is a count of the number of columns in the image, which I have as ‘col’
bpp is the number of bytes per pixel (4 = 32bit, 2 = 16bit, 1 = 8bit), which I have as bpp

All of this works as expected in Xojo.

The GetBufferY16() function (in C) is:

// Get new Gray 16 scale buffer
COAX_GRABBER_API int32_t GetBufferY16(int32_t * handle, unsigned short * buffer, uint64_t* epoc = NULL, uint16_t* frameID = NULL);

If I’m reading the snippet above correctly, in the C test code, they’re allocating memory based on the calculated buffer size, then passing that to the GetBufferY16() function. My declare of the C function in Xojo is:

// Get new Gray 16 scale buffer
// COAX_GRABBER_API int32_t GetBufferY16(int32_t * handle, unsigned short * buffer, uint64_t* epoc = NULL, uint16_t* frameID = NULL);
Declare Function GetBufferY16 Lib "libCoaxLinkGrabber.dylib" (byref handle as int32,  byref buffer as Short,  byref epoc as uint64 ,  byref frameID as uint16 ) as Integer

Would I need to create a memory block in Xojo that matches the buffer size and pass a pointer to it? if so, how, if the function is expecting a short?

Change it to buffer as Ptr and just pass the memoryblock. Xojo auto-converts a memoryblock into a pointer (the short in the C code). When it returns, the memoryblock will contain the image data.

1 Like

So:

// Get new Gray 16 scale buffer
// COAX_GRABBER_API int32_t GetBufferY16(int32_t * handle, unsigned short * buffer, uint64_t* epoc = NULL, uint16_t* frameID = NULL);
Declare Function GetBufferY16 Lib "libCoaxLinkGrabber.dylib" (byref handle as int32,  buffer as ptr,  byref epoc as uint64 ,  byref frameID as uint16 ) as Integer

Followed by:

ElseIf (bpp = 2) then
  //16bit image
  //Calculate buffer size
  buffer = row * col * 2
  Var mb As New MemoryBlock(buffer)
  grabimage = GetBufferY16(handle,mb,epoc,frameID)

gives me a segmentation fault.

Have you checked that handle, row and col were correct after calling GetBufferSize ?

They are, yes.

[EDIT] …However, this got me to look a little deeper and I realized that the size of the files I’m testing right now are huge, so the resulting buffer size (row * col * 2) was a much bigger number than my buffer variable could handle. I changed it to a Uint64 and now it works. These images are about 14000 x 10000 pixels in size, so just massive.

Thanks!