Concepts and Definitions

Naming Convention

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]

Coordinate System

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.

Memory Allocation

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().

Error Handling

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.

Data Types

Binary Images

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:

  1. Binary data can be read in any word width, not just bytes, and the pixels remain linearly stored in the word.
  2. Bitblit operations work on all pixel depths.

8-Bit Images

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

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.

Figure 1: Chain code directions for 4-connectivity (a) and 8-connectivity (b).

Pixel Buffers

Storage

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.

Image Representation

An image is described by four or five parameters for 8-bit images or binary images, respectively. These parameters are:

  1. The pixel buffer pointer, buf.
  2. The row dimension in bytes, or leading dimension, dim.
  3. The bit offset 0 – 7 to the first pixel in the first byte, off. Only for binary images.
  4. The image width in pixels, width.
  5. The image height in pixels, 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:

  1. The allocated memory must start at a rapp_alignment boundary.
  2. The size of the allocated memory must be a multiple of rapp_alignment.
  3. The row dimension must be a multiple of rapp_alignment.

Figure 2 shows an example of a binary image buffer.

Figure 2: A binary image in memory. For clarity, the rows are shown stacked on top of each other, even though memory is one-dimensional. The allocated area is limited by the outer rectangle. The grid represents individual bytes, so in this example the alignment value is four bytes. The buffer pointer is offset by one row and six bytes from the start of the allocated area. The binary offset is four bits, and combined with the image width, it also determines the bit position in the last byte in a row. The blue area is the actual image region, and the gray area is the additional processing region.

Aligned Images

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.

Figure 3: An aligned image in memory.

Alignment

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.

Aliasing

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.

Processing Region

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.

Temporary Buffers

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.

Image Size

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.

Next section: Support Functionality


Generated on 1 Jun 2016 for RAPP by  doxygen 1.6.1