Subject:
[ruby-ffi] How to specify size for returned buffer?
From:
cfis
Date:
8/19/11 11:57 PM
To:
ruby-ffi

I'm trying to wrap FreeImage (http://freeimage.sourceforge.net/) and
it has this function:

DLL_API BOOL DLL_CALLCONV FreeImage_AcquireMemory(FIMEMORY *stream,
BYTE **data, DWORD *size_in_bytes);

The way this works is you hand FreeImage a pointer (data) which it
then allocates memory for and returns the size in the size_in_bytes
out parameter.  I've attached example C code from the FreeImage docs
in case it helps.

So I'm not sure how to wrap this function.  So far I have this:

FreeImage.attach_function('FreeImage_AcquireMemory',
[:pointer, :pointer, :uint], :bool)

buffer = MemoryPointer.new(:pointer)
size_ptr = MemoryPointer.new(:uint)
FreeImage.FreeImage_AcquireMemory(self, buffer, size);

What I would then like to do is something like:

buffer.size = size_ptr.read_pointer()

But buffer doesn't have any such API.

Any help appreciated.

Thanks,

Charlie
------------
void testAcquireMemIO(const char *lpszPathName) {
  FIMEMORY *hmem = NULL;
  // load a regular file
  FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
  FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, 0);

  // open and allocate a memory stream
  hmem = FreeImage_OpenMemory();

  // save the image to a memory stream
  FreeImage_SaveToMemory(FIF_PNG, dib, hmem, PNG_DEFAULT);
  FreeImage_Unload(dib);

  // get the buffer from the memory stream
  BYTE *mem_buffer = NULL;
  DWORD size_in_bytes = 0;
  FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes);

  // save the buffer to a file stream
  FILE *stream = fopen("buffer.png", "wb");
  if(stream) {
    fwrite(mem_buffer, sizeof(BYTE), size_in_bytes, stream);
    fclose(stream);
  }
  // close and free the memory stream
  FreeImage_CloseMemory(hmem);
}