Skip to content

API: C API: Memory Management Of SPERR Output

Samuel Li edited this page Jun 2, 2022 · 3 revisions

SPERR aims to make its C API simple and making use of only plain C data types. This page documents the memory management model of SPERR output.

Compression Output

SPERR's compression output is a compact bitstream represented as an array of type uint8_t. Thus, the compression output consists of two parts: 1) an uint8_t array and 2) the length of this array.

One reality of compression is that the length of this output bitstream is often unknown in advance, especially when compressing in the "fixed-error" mode. (Sometimes it even can be unknown in the "fixed-size" mode.) As a result, the C API of SPERR chooses to allocate this output array inside of the function call after it knows how big of the array to allocate, instead of asking the user to pass in a pre-allocated array.

This model works in 4 steps:

  1. The user declares a NULL pointer, ptr, and passes its address to SPERR.
  2. The user also declares a variable len and passes its address to SPERR.
  3. SPERR allocates an appropriate array, and modifies the value ptr to the address of the allocated array.
  4. SPERR also modifies the value of len to keep the length of the newly allocated array.

In C programming language, the usage looks like:

void* ptr = NULL;
size_t len = 0;
sperr_compress(&ptr, &len);
/* 
 * ptr is now pointing to a valid memory block, and len contains the length of that memory block. 
 */
free(ptr);

As a reminder, the user of SPERR C functions will be responsible of free'ing the memory block pointed to by ptr.

Decompression Output

The decompression output of SPERR C API is an array of type either float or double, as requested by the user. SPERR C API again chooses to allocate memory inside of the decompression function call, and pass the address of this array back to the user. The length of this array, however, is implied by the dimension of the decompressed data, which is dimx x dimy x dimz in case of 3D volumes, and dimx x dimy in case of 2D slices.

The memory model of decompression works in 4 steps:

  1. The user declares a NULL pointer, ptr, and passes its address to SPERR.
  2. The user also declares two or three variables (dimx, dimy, and possibly dimz) and passes their addresses to SPERR.
  3. SPERR allocates an appropriate array, and modifies the value ptr to the address of the allocated array.
  4. SPERR also modifies the value of dimx, dimy, and possibly dimz to keep the dimension of the decompressed 2D slice/3D volume.

In C programming language, this usage looks like:

void* ptr = NULL;
size_t dimx, dimy, dimz;
sperr_decompress(&ptr, &dimx, &dimy, &dimz);
/* 
 * ptr is now pointing to a valid memory block with a length of dimx x dimy x dimz.
 */
free(ptr);

Again, the user of SPERR C functions will be responsible of free'ing the memory block pointed to by ptr.