All symbols and constants in the API are prefixed with rapp_
and RAPP_
, respectively. All functions operating on images with of the same type are suffixed with that type. The type suffixes are _bin
for binary images and _u8
for 8-bit unsigned images. The complete naming scheme is shown below:
{rapp_ | RAPP_} family-name _ name [suffix]
The RAPP library uses an image coordinate system with the origin located in the the upper-left corner of the image. The positive x-direction is to the right and the positive y-direction is downwards.
RAPP functions never allocate memory. All memory allocations must be handled by the caller. However, the library provides an allocator that is compatible with the platform-specific buffer alignment. This allocator may be implemented on top of malloc() and free().
All functions that perform computations return a negative error code on failure. This code can then be converted to a description string for diagnostic purposes. There are no internal failure modes (with the exception of uninitialized), which means that all errors are determined by the input argument values. Some functions also pass the non-negative computation result via the return value.
Binary images are stored in a bit-packed format, i.e. truly one bit per pixel. In an 8-pixel byte, the individual ordering left-to-right is 0 – 7 for little-endian platforms, and 7 – 0 for big-endian platforms, where bit 0 is the least significant bit in the byte. To put it another way, the bit order follows the byte order of the platform. There are two major benefits with this scheme:
8-bit images are represented using 8-bit unsigned integers (uint8_t
). This does not imply that data is always unsigned - they are just interpreted differently. Images with signed data are to be interpreted as having a constant bias of 128, i.e. the stored value 0 correspond to -128, and 255 to 127. All functions that produce a signed result use this encoding. The main reason for using this scheme is that it essentially halves the number of 8-bit implementations. In this manual the term "8-bit" will refer to this unsigned 8-bit data type.
Chain codes are stored as ASCII characters in NUL-terminated strings. 4-connectivity chain codes use the characters 0 – 3 for directions right, up, left and down. 8-connectivity chains use 0 – 7 for directions right, up-right, up, up-left, left, down-left, down and down-right. The figure below illustrates code interpretation.
Pixel data is stored linearly in memory using row-major order, from the upper-left to the lower-right corner. For 8-bit images, the layout in memory is endian-independent. Additionally, for binary images the bit-order in individual bytes follows the byte-order of the platform.
An image is described by four or five parameters for 8-bit images or binary images, respectively. These parameters are:
buf
.dim
.off
. Only for binary images.width
.height
.The row dimension is the actual size of the image rows and may be greater than what the width of the image would require. It corresponds to the increment we need to add to the buffer pointer to get to the pixel one step below. With an explicit row dimension, it is possible to work on sub images of a larger original image. The row dimension must always be aligned, i.e. it must be a multiple of the rapp_alignment value.
Even though the buffer may start at an arbitrary byte, the allocated memory area must extend to the nearest alignment boundaries. To summarize the alignment restrictions, the following constraints apply:
Figure 2 shows an example of a binary image buffer.
For performance reasons, one additional alignment restriction is placed on the images passed to RAPP – the actual image region must start on a rapp_alignment boundary. This implies the following:
Images with these properties are called aligned images. Unless explicitly stated, all functions in the RAPP library require aligned images. Figure 3 shows an example of an aligned image.
The alignment value is platform-dependent. It is given by the constant global variable rapp_alignment and is a power of two, at least four bytes. The supplied allocator always returns aligned memory pointers.
Unless explicitly stated, pixel buffers must never overlap in memory. If they do, the result of the computation is undefined. The called function may return RAPP_ERR_OVERLAP.
The RAPP functions are allowed to process pixels to the left and to the right of the actual image region given, limited by the nearest alignment boundary. While this does not matter much for pixelwise operations, it may produce erroneous results in other cases if those alignment pixels are not properly cleared. The functions rapp_pad_align_bin() and rapp_pad_align_u8() does this for binary and 8-bit images.
Some operations need temporary storage. Since no memory can be allocated inside a RAPP function, temporary buffers must be allocated by the caller and passed to the function. The pixel buffer alignment restrictions apply.
The RAPP functions cannot process arbitrarily large images. The maximum image size allowed is 28*(sizeof(int) - 1) pixels. Some functions that perform reductions, e.g. statistics and moments may have additional size restrictions.