![]() |
Foundation LayerMemory Allocation The PhotoJazz engine itself only allocates memory on the stack, for stack frames and local variables. Whenever it needs to allocate or free a larger chunk of memory, it calls functions that you define. BitJazz uses an object-oriented C structure, JzAllocator, for this purpose, which contains a suite of callback functions for allocation and freeing, as well as a private data field reserved for your use. Each of the callback functions takes the JzAllocator object as its first argument. The JzAllocator structure, which you create, contains a pointer to a callback function (mAllocate) to allocate a chunk of memory, a pointer to a callback function (mFree) to free a chunk of memory allocated by mAllocate, and a private data field (mData) for your sole use. typedef struct JzAllocator { You must create an instance of this structure, define an mAllocate function and an mFree function, set the function pointers in the structure instance to your functions, and pass a pointer to the structure instance in to PhotoJazz each time you start to read or write a PhotoJazz file with JzReadBegin or JzWriteBegin. PhotoJazz stores this address and allocates and frees memory by calling through the function pointers in the structure pointed to by that address. The mAllocate callback function, which you define, takes as arguments a pointer to a JzAllocator structure (aAllocator) and a byte count (aSize), and tries to allocate a chunk of memory of the specified size. When PhotoJazz calls this function, it passes back the address of the JzAllocator structure you gave it at the beginning of the file with JzReadBegin or JzWriteBegin. If the allocation succeeds, your mAllocate function must return the address of the beginning of the newly allocated chunk of memory. If the allocation fails (presumably because there is insufficient memory), your mAllocate function must return NULL (0). To permit PhotoJazz to clean up its state properly, you must return control to PhotoJazz, which will then return an error result (kJzStreamResultOutOfMemory) indicating allocation failure through the JzRead or JzWrite function in progress. void *((*mAllocate)(JzAllocator *aAllocator, unsigned long aSize)); For example, a basic stdlib implementation of mAllocate might be: #include <stdlib.h> The mFree callback function, which you define, takes as arguments a pointer to a JzAllocator structure (aAllocator) and a pointer to a chunk of memory (aBuffer) previously allocated by the mAllocate function. When PhotoJazz calls this function, it passes back the address of the JzAllocator structure you gave it at the beginning of the file with JzReadBegin or JzWriteBegin. void (*mFree)(JzAllocator *aAllocator, void *aBuffer); For example, a basic stdlib implementation of mFree might be: #include <stdlib.h> The mData member of the JzAllocator structure is solely for your use; PhotoJazz never accesses it. Depending on your allocation package's needs, you can ignore it, put an identifying number in it, or put in a pointer to a structure containing additional information. PhotoJazz accesses the JzAllocator structure by reference only and defines no hidden members of its own in the structure, so you are free to define your own structure with a JzAllocator as its first member instead of forcing your ancillary data to fit in the mData field. unsigned long mData; Examples The PhotoJazz SDK comes with two sample implementations of the JzAllocator: JzAllocatorStdlib.{c,h} and JzAllocatorMacintosh.{c,h}. Here is a sample code snippet using JzAllocatorStdlib: #include "JzAllocatorStdlib.h" Depending on your needs, you may prefer to create a global, static, or dynamic JzAllocator instead of a local one.
|