Reference C library

The TraX protocol can be implemented using the protocol specification, the protocol is quite easy to implement in many high-level languages. However, a reference C implementation is provided to serve as a practical model of implementation and to make the adoption of the protocol easier.

Requirements and building

The library is built using CMake build tool which generates build instructions for a given platform. The code is written in C89 for maximum portability and the library has no external dependencies apart from the standard C library. For more details on building check out the tutorial on compiling the project.

Documentation

All the public functionality of the library is described in the trax.h header file, below is a summary of individual functions that are available in the library.

Communication

TRAX_ERROR

Value that indicates protocol error

TRAX_OK

Value that indicates success of a function call

TRAX_HELLO

Value that indicates introduction message

TRAX_INITIALIZE

Value that indicates initialization message

TRAX_FRAME

Value that indicates frame message

TRAX_QUIT

Value that indicates quit message

TRAX_STATE

Value that indicates status message

trax_logging

Structure that describes logging handle.

trax_bounds

Structure that describes region bounds.

trax_handle

Structure that describes a protocol state for either client or server.

trax_image

Structure that describes an image.

trax_region

Structure that describes a region.

trax_properties

Structure that contains an key-value dictionary.

trax_logging trax_no_log

A constant to indicate that no logging will be done.

trax_bounds trax_no_bounds

A constant to indicate that here are no bounds.

const char* trax_version()

Returns a string version of the library for debugging purposes. If possible, this version is defined during compilation time and corresponds to Git hash for the current revision.

Returns:Version string as a constant character array
trax_metadata* trax_metadata_create(int region_formats, int image_formats, const char* tracker_name, const char* tracker_description, const char* tracker_family)

Create a tracker metadata structure returning its pointer

Returns:A pointer to a metadata structure that can be released using trax_metadata_release().
void trax_metadata_release(trax_metadata** metadata)

Releases a given metadata structure, clearing its memory.

Parameters:
  • metadata – Pointer of a pointer of tracker metadata structure.
trax_logging trax_logger_setup(trax_logger callback, void* data, int flags)

A function that can be used to initialize a logging configuration structure.

Parameters:
  • callback – Callback function used to process a chunk of log data
  • data – Additional data passed to the callback function as an argument
  • flags – Optional flags for logger
Returns:

A logging structure for the given data

trax_logging trax_logger_setup_file(FILE* file)

A handy function to initialize a logging configuration structure for file logging. Internally the function calls trax_logger_setup().

Parameters:
  • file – File object, opened for writing, can also be stdout or stderr
Returns:

A logging structure for the given file

trax_handle* trax_client_setup_file(int input, int output, trax_logging log)

Setups the protocol state object for the client. It is assumed that the tracker process is already running (how this is done is not specified by the protocol). This function tries to parse tracker’s introduction message and fails if it is unable to do so or if the handshake fails (e.g. unsupported format version).

Parameters:
  • input – Stream identifier, opened for reading, used to read server output
  • output – Stream identifier, opened for writing, used to write messages
  • log – Logging structure
Returns:

A handle object used for further communication or NULL if initialization was unsuccessful

trax_handle* trax_client_setup_socket(int server, int timeout, trax_logging log)

Setups the protocol state object for the client using a bi-directional socket. It is assumed that the connection was already established (how this is done is not specified by the protocol). This function tries to parse tracker’s introduction message and fails if it is unable to do so or if the handshake fails (e.g. unsupported format version).

Parameters:
  • server – Socket identifier, used to read communcate with tracker
  • log – Logging structure
Returns:

A handle object used for further communication or NULL if initialization was unsuccessful

int trax_client_wait(trax_handle* client, trax_region** region, trax_properties* properties)

Waits for a valid protocol message from the server.

Parameters:
  • client – Client state object
  • region – Pointer to current region for an object, set if the response is TRAX_STATE, otherwise NULL
  • properties – Additional properties
Returns:

Integer value indicating status, can be either TRAX_STATE, TRAX_QUIT, or TRAX_ERROR

int trax_client_initialize(trax_handle* client, trax_image* image, trax_region* region, trax_properties* properties)
Sends an initialize message to server.
Parameters:
  • client – Client state object
  • image – Image frame data
  • region – Initialization region
  • properties – Additional properties object
Returns:

Integer value indicating status, can be either TRAX_OK or TRAX_ERROR

int trax_client_frame(trax_handle* client, trax_image* image, trax_properties* properties)
Sends a frame message to server.
Parameters:
  • client – Client state object
  • image – Image frame data
  • properties – Additional properties
Returns:

Integer value indicating status, can be either TRAX_OK or TRAX_ERROR

trax_handle* trax_server_setup(trax_metadata* metadata, trax_logging log)

Setups the protocol for the server side and returns a handle object.

Parameters:
  • metadata – Tracker metadata
  • log – Logging structure
Returns:

A handle object used for further communication or NULL if initialization was unsuccessful

trax_handle* trax_server_setup_file(trax_metadata* metadata, int input, int output, trax_logging log)

Setups the protocol for the server side based on input and output stream and returns a handle object.

Parameters:
  • metadata – Tracker metadata
  • input – Stream identifier, opened for reading, used to read client output
  • output – Stream identifier, opened for writing, used to write messages
  • log – Logging structure
Returns:

A handle object used for further communication or NULL if initialization was unsuccessful

int trax_server_wait(trax_handle* server, trax_image** image, trax_region** region, trax_properties* properties)
Waits for a valid protocol message from the client.
Parameters:
  • server – Server state object
  • image – Pointer to image frame data, set if the response is not TRAX_QUIT or TRAX_ERROR, otherwise NULL
  • region – Pointer to initialization region, set if the response is TRAX_INITIALIZE, otherwise NULL
  • properties – Additional properties
Returns:

Integer value indicating status, can be either TRAX_INITIALIZE, TRAX_FRAME, TRAX_QUIT, or TRAX_ERROR

int trax_server_reply(trax_handle* server, trax_region* region, trax_properties* properties)
Sends a status reply to the client.
Parameters:
  • server – Server state object
  • region – Current region of an object
  • properties – Additional properties
Returns:

Integer value indicating status, can be either TRAX_OK or TRAX_ERROR

int trax_terminate(trax_handle* handle)

Used in client and server. Closes communication, sends quit message if needed. This function is implicitly called in trax_cleanup().

Parameters:
  • handle – Server or client state object
Returns:

Integer value indicating status, can be either TRAX_OK or TRAX_ERROR

int trax_cleanup(trax_handle** handle)

Used in client and server. Closes communication, sends quit message if needed. Releases the handle structure.

Parameters:
  • handle – Pointer to state object pointer
Returns:

Integer value indicating status, can be either TRAX_OK or TRAX_ERROR

int trax_set_parameter(trax_handle* handle, int id, int value)

Sets the parameter of the client or server instance.

int trax_get_parameter(trax_handle* handle, int id, int* value)

Gets the parameter of the client or server instance.

Image

TRAX_IMAGE_EMPTY

Empty image type, not usable in any way but to signify that there is no data.

TRAX_IMAGE_PATH

Image data is provided in a file on a file system. Only a path is provided.

TRAX_IMAGE_URL

Image data is provided in a local or remote resource. Only a URL is provided.

TRAX_IMAGE_MEMORY

Image data is provided in a memory buffer and can be accessed directly.

TRAX_IMAGE_BUFFER

Image data is provided in a memory buffer but has to be decoded first.

TRAX_IMAGE_BUFFER_ILLEGAL

Image buffer is of an unknown data type.

TRAX_IMAGE_BUFFER_PNG

Image data is encoded as PNG image.

TRAX_IMAGE_BUFFER_JPEG

Image data is encoded as JPEG image.

TRAX_IMAGE_MEMORY_ILLEGAL

Image data is available in an unknown format.

TRAX_IMAGE_MEMORY_GRAY8

Image data is available in 8 bit per pixel format.

TRAX_IMAGE_MEMORY_GRAY16

Image data is available in 16 bit per pixel format.

TRAX_IMAGE_MEMORY_RGB

Image data is available in RGB format with three bytes per pixel.

void trax_image_release(trax_image** image)

Releases image structure, frees allocated memory.

Parameters:
  • image – Pointer to image structure pointer (the pointer is set to NULL if the structure is destroyed successfuly)
trax_image* trax_image_create_path(const char* path)

Creates a file-system path image description.

Parameters:
  • url – File path string, it is copied internally
Returns:

Image structure pointer

trax_image* trax_image_create_url(const char* url)

Creates a URL path image description.

Parameters:
  • url – URL string, it is copied internally
Returns:

Image structure pointer

trax_image* trax_image_create_memory(int width, int height, int format)

Creates a raw in-memory buffer image description. The memory is not initialized, you have do this manually.

Parameters:
  • width – Image width
  • height – Image height
  • format – Image format, see format type constants for options
Returns:

Image structure pointer

trax_image* trax_image_create_buffer(int length, const char* data)

Creates a file buffer image description.

Parameters:
  • length – Length of the buffer
  • data – Character array with data, the buffer is copied
Returns:

Image structure pointer

int trax_image_get_type(const trax_image* image)

Returns a type of the image handle.

Parameters:
  • image – Image structure pointer
Returns:

Image type code, see image type constants for more details

const char* trax_image_get_path(const trax_image* image)

Returns a file path from a file-system path image description. This function returns a pointer to the internal data which should not be modified.

Parameters:
  • image – Image structure pointer
Returns:

Pointer to null-terminated character array

const char* trax_image_get_url(const trax_image* image)

Returns a file path from a URL path image description. This function returns a pointer to the internal data which should not be modified.

Parameters:
  • image – Image structure pointer
Returns:

Pointer to null-terminated character array

void trax_image_get_memory_header(const trax_image* image, int* width, int* height, int* format)

Returns the header data of a memory image.

Parameters:
  • image – Image structure pointer
  • width – Pointer to variable that is populated with width of the image
  • height – Pointer to variable that is populated with height of the image
  • format – Pointer to variable that is populated with format of the image, see format constants for options
char* trax_image_write_memory_row(trax_image* image, int row)

Returns a pointer for a writeable row in a data array of an image.

Parameters:
  • image – Image structure pointer
  • row – Number of row
Returns:

Pointer to character array of the line

const char* trax_image_get_memory_row(const trax_image* image, int row)

Returns a read-only pointer for a row in a data array of an image.

Parameters:
  • image – Image structure pointer
  • row – Number of row
Returns:

Pointer to character array of the line

const char* trax_image_get_buffer(const trax_image* image, int* length, int* format)

Returns a file buffer and its length. This function returns a pointer to the internal data which should not be modified.

Parameters:
  • image – Image structure pointer
  • length – Pointer to variable that is populated with buffer length
  • format – Pointer to variable that is populated with buffer format code
Returns:

Pointer to character array

Region

TRAX_REGION_EMPTY

Empty region type, not usable in any way but to signify that there is no data.

TRAX_REGION_SPECIAL

Special code region type, only one value avalable that can have a defined meaning.

TRAX_REGION_RECTANGLE

Rectangle region type. Left, top, width and height values available.

TRAX_REGION_POLYGON

Polygon region type. Three or more points available with x and y coordinates.

… c:macro:: TRAX_REGION_MASK

TRAX_REGION_ANY

Any region type, a shortcut to specify that any supported region type can be used.

void trax_region_release(trax_region** region)

Releases region structure, frees allocated memory.

Parameters:
  • region – Pointer to region structure pointer (the pointer is set to NULL if the structure is destroyed successfuly)
int trax_region_get_type(const trax_region* region)

Returns type identifier of the region object.

Parameters:
  • region – Region structure pointer
Returns:

One of the region type constants

trax_region* trax_region_create_special(int code)

Creates a special region object.

Parameters:
  • code – A numerical value that is contained in the region type
Returns:

A pointer to the region object

void trax_region_set_special(trax_region* region, int code)

Sets the code of a special region.

Parameters:
  • region – Region structure pointer
  • code – The new numerical value
int trax_region_get_special(const trax_region* region)

Returns a code of a special region object if the region is of special type.

Parameters:
  • region – Region structure pointer
Returns:

The numerical value

trax_region* trax_region_create_rectangle(float x, float y, float width, float height)

Creates a rectangle region.

Parameters:
  • x – Left offset
  • y – Top offset
  • width – Width of rectangle
  • height – Height of rectangle
Returns:

A pointer to the region object

void trax_region_set_rectangle(trax_region* region, float x, float y, float width, float height)

Sets the coordinates for a rectangle region.

Parameters:
  • region – A pointer to the region object
  • x – Left offset
  • y – Top offset
  • width – Width of rectangle
  • height – Height of rectangle
void trax_region_get_rectangle(const trax_region* region, float* x, float* y, float* width, float* height)

Retreives coordinate from a rectangle region object.

Parameters:
  • region – A pointer to the region object
  • x – Pointer to left offset value variable
  • y – Pointer to top offset value variable
  • width – Pointer to width value variable
  • height – Pointer to height value variable
trax_region* trax_region_create_polygon(int count)

Creates a polygon region object for a given amout of points. Note that the coordinates of the points are arbitrary and have to be set after allocation.

Parameters:
  • code – The number of points in the polygon
Returns:

A pointer to the region object

void trax_region_set_polygon_point(trax_region* region, int index, float x, float y)

Sets coordinates of a given point in the polygon.

Parameters:
  • region – A pointer to the region object
  • index – Index of point
  • x – Horizontal coordinate
  • y – Vertical coordinate
void trax_region_get_polygon_point(const trax_region* region, int index, float* x, float* y)

Retrieves the coordinates of a specific point in the polygon.

Parameters:
  • region – A pointer to the region object
  • index – Index of point
  • x – Pointer to horizontal coordinate value variable
  • y – Pointer to vertical coordinate value variable
int trax_region_get_polygon_count(const trax_region* region)

Returns the number of points in the polygon.

Parameters:
  • region – A pointer to the region object
Returns:

Number of points

trax_bounds trax_region_bounds(const trax_region* region)

Calculates a bounding box region that bounds the input region.

Parameters:
  • region – A pointer to the region object
Returns:

A bounding box structure that contains values for left, top, right, and bottom

trax_region* trax_region_clone(const trax_region* region)

Clones a region object.

Parameters:
  • region – A pointer to the region object
Returns:

A cloned region object pointer

trax_region* trax_region_convert(const trax_region* region, int format)

Converts region between different formats (if possible).

Parameters:
  • region – A pointer to the region object
  • format – One of the format type constants
Returns:

A converted region object pointer

float trax_region_contains(const trax_region* region, float x, float y)

Calculates if the region contains a given point.

Parameters:
  • region – A pointer to the region object
  • x – X coordinate of the point
  • y – Y coordinate of the point
Returns:

Returns zero if the point is not in the region or one if it is

float trax_region_overlap(const trax_region* a, const trax_region* b, const trax_bounds bounds)

Calculates the spatial Jaccard index for two regions (overlap).

Parameters:
  • a – A pointer to the region object
  • b – A pointer to the region object
Returns:

A bounds structure to contain only overlap within bounds or trax_no_bounds if no bounds are specified

char* trax_region_encode(const trax_region* region)

Encodes a region object to a string representation.

Parameters:
  • region – A pointer to the region object
Returns:

A character array with textual representation of the region data

trax_region* trax_region_decode(const char* data)

Decodes string representation of a region to an object.

Parameters:
  • region – A character array with textual representation of the region data
Returns:

A pointer to the region object or NULL if string does not contain valid region data

Properties

trax_properties* trax_properties_create()

Create an empty properties dictionary.

Returns:A pointer to a properties object
void trax_properties_release(trax_properties** properties)

Destroy a properties object and clean up the memory.

Parameters:
  • properties – A pointer to a properties object pointer
void trax_properties_clear(trax_properties* properties)

Clears a properties dictionary making it empty.

Parameters:
  • properties – A pointer to a properties object
void trax_properties_set(trax_properties* properties, const char* key, const char* value)

Set a string property for a given key. The value string is cloned.

Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property, only keys valid according to the protocol are accepted
  • value – The value for the property, the string is cloned internally
void trax_properties_set_int(trax_properties* properties, const char* key, int value)

Set an integer property. The value will be encoded as a string.

Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property, only keys valid according to the protocol are accepted
  • value – The value for the property
void trax_properties_set_float(trax_properties* properties, const char* key, float value)

Set an floating point value property. The value will be encoded as a string.

Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property, only keys valid according to the protocol are accepted
  • value – The value for the property
char* trax_properties_get(const trax_properties* properties, const char* key)

Get a string property. The resulting string is a clone of the one stored so it should be released when not needed anymore.

Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property
Returns:

The value for the property or NULL if there is no value associated with the key

int trax_properties_get_int(const trax_properties* properties, const char* key, int def)
Get an integer property. A stored string value is converted to an integer. If this is not possible or the property does not exist a given default value is returned.
Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property
  • def – Default value for the property
Returns:

The value for the property or default value if there is no value associated with the key or conversion from string is impossible

float trax_properties_get_float(const trax_properties* properties, const char* key, float def)

Get an floating point value property. A stored string value is converted to an integer. If this is not possible or the property does not exist a given default value is returned.

Parameters:
  • properties – A pointer to a properties object
  • key – A key for the property
  • def – Default value for the property
Returns:

The value for the property or default value if there is no value associated with the key or conversion from string is impossible

int trax_properties_count(const trax_properties* properties)

Get a number of all pairs in the properties object.

Parameters:
  • properties – A pointer to a properties object
Returns:

Number of key-value pairs in the properties object

void trax_properties_enumerate(trax_properties* properties, trax_enumerator enumerator, const void* object)

Iterate over the property set using a callback function. An optional pointer can be given and is forwarded to the callback.

Parameters:
  • properties – A pointer to a properties object
  • enumerator – A pointer to the enumerator function that is called for every key-value pair
  • object – A pointer to additional data for the enumerator function

Integration example

The library can be easily integrated into C and C++ code (although a C++ wrapper also exists) and can be also linked into other programming languages that enable linking of C libraries. Below is an sripped-down example of a C tracker skeleton with a typical tracking loop. Note that this is not a complete example and servers only as a demonstration of a typical tracker on a tracking-loop level.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>

int main( int argc, char** argv)
{
    int i;
    FILE* out;
    rectangle_type region;
    image_type image;

    out = fopen("trajectory.txt", "w");

    region = read_bounding_box();
    image = read_image(1);
    region = initialize_tracker(region, image);

    write_frame(out, region);

    for (i = 2; ; i++)
    {
      image = read_image(i);
      region = update_tracker(image);
      write_frame(out, region);
    }

    fclose(out);
    return 0;
}

The code above can be modified to use the TraX protocol by including the C library header and changing the tracking loop to accept frames from the protocol insead of directly reading them from the filesystem. It also requires linking the protocol library (libtrax) when building the tracker executable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>

// Include TraX library header
#include "trax.h"

int main( int argc, char** argv)
{
    int run = 1;
    trax_image* img = NULL;
    trax_region* reg = NULL;

    // Call trax_server_setup at the beginning
    trax_handle* handle;
    trax_metadata* meta = trax_metadata_create(TRAX_REGION_RECTANGLE, TRAX_IMAGE_PATH, "Name", NULL, NULL);

    handle = trax_server_setup(meta, trax_no_log);

    trax_metadata_release(&meta);

    while(run)
    {
        int tr = trax_server_wait(handle, &img, &reg, NULL);

        // There are two important commands. The first one is
        // TRAX_INITIALIZE that tells the tracker how to initialize.
        if (tr == TRAX_INITIALIZE) {

            rectangle_type region = initialize_tracker(
                region_to_rectangle(reg), load_image(img));
            trax_server_reply(handle, rectangle_to_region(region), NULL);

        } else
        // The second one is TRAX_FRAME that tells the tracker what to process next.
        if (tr == TRAX_FRAME) {

            rectangle_type region = update_tracker(load_image(img));
            trax_server_reply(handle, rectangle_to_region(region), NULL);

        }
        // Any other command is either TRAX_QUIT or illegal, so we exit.
        else {
            run = 0;
        }

        if (img) trax_image_release(&img);
        if (reg) trax_region_release(&reg);

    }

    // TraX: Call trax_cleanup at the end
    trax_cleanup(&handle);

    return 0;
}