diff --git a/liboptv/.gitignore b/liboptv/.gitignore new file mode 100644 index 00000000..c84f4712 --- /dev/null +++ b/liboptv/.gitignore @@ -0,0 +1,30 @@ + +Makefile +Makefile.in + +aclocal.m4 +autom4te.cache/ +build-aux/ + +config.h +config.h.in +config.log +config.status +configure +libtool +m4/ + +src/.deps/ +src/.libs/ +src/Makefile +src/Makefile.in +src/liboptv.la +src/*.lo +src/*.o + +tests/.deps/ +tests/.libs/ +tests/check_fb +tests/*.o + +stamp-h1 diff --git a/liboptv/Makefile.am b/liboptv/Makefile.am new file mode 100644 index 00000000..eefcf234 --- /dev/null +++ b/liboptv/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src . tests +pkginclude_HEADERS = include/* + diff --git a/liboptv/configure.ac b/liboptv/configure.ac new file mode 100644 index 00000000..b03d9fba --- /dev/null +++ b/liboptv/configure.ac @@ -0,0 +1,43 @@ +# Process this file with autoconf to produce a configure script. + +# Prelude. +AC_PREREQ([2.59]) +AC_INIT([optv], [0.1-dev], [openptv AT googlegroups.com]) + +# unique source file --- primitive safety check +AC_CONFIG_SRCDIR([.]) +AC_CONFIG_MACRO_DIR([m4]) + +# place to put some extra build scripts installed +AC_CONFIG_AUX_DIR([build-aux]) + +# fairly severe build strictness +# change foreign to gnu or gnits to comply with gnu standards +AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.9.6]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL + +# Checks for libraries. + +# The testing framework Check. +PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. +AC_FUNC_MALLOC + +# Output files +AC_CONFIG_HEADERS([config.h]) + +AC_CONFIG_FILES([Makefile + src/Makefile + tests/Makefile]) + +AC_OUTPUT diff --git a/liboptv/include/tracking_frame_buf.h b/liboptv/include/tracking_frame_buf.h new file mode 100644 index 00000000..48fc9df4 --- /dev/null +++ b/liboptv/include/tracking_frame_buf.h @@ -0,0 +1,99 @@ +/* +Definition for the tracking frame buffers. Each frame holds target information +for all cameras, correspondence information and path links information. +*/ + +#ifndef TRACKING_FRAME_BUF_H +#define TRACKING_FRAME_BUF_H + +#define POSI 80 +#define STR_MAX_LEN 255 + +typedef struct +{ + int pnr; + double x, y; + int n, nx, ny, sumg; + int tnr; +} +target; + +int compare_targets(target *t1, target *t2); +int read_targets(target buffer[], char* file_base, int frame_num); +int write_targets(target buffer[], int num_targets, char* file_base, \ + int frame_num); + +typedef struct +{ + int nr; + int p[4]; +} +corres; + +int compare_corres(corres *c1, corres *c2); +#define CORRES_NONE -1 + +typedef double coord_t; +typedef float fitness_t; + +typedef struct Pstruct +{ + coord_t x[3]; /*coordinates*/ + int prev, next; /*pointer to prev or next link*/ + int prio; /*Prority of link is used for differen levels*/ + fitness_t decis[POSI]; /*Bin for decision critera of possible links to next dataset*/ + fitness_t finaldecis; /*final decision critera by which the link was established*/ + int linkdecis[POSI]; /* pointer of possible links to next data set*/ + int inlist; /* Counter of number of possible links to next data set*/ +} P; + +int compare_path_info(P *p1, P *p2); +void register_link_candidate(P *self, fitness_t fitness, int cand); +#define PREV_NONE -1 +#define NEXT_NONE -2 +#define PRIO_DEFAULT 2 +void reset_links(P *self); + +int read_path_frame(corres *cor_buf, P *path_buf, \ + char *corres_file_base, char *linkage_file_base, + char *prio_file_base, int frame_num); +int write_path_frame(corres *cor_buf, P *path_buf, int num_parts,\ + char *corres_file_base, char *linkage_file_base, + char *prio_file_base, int frame_num); + +typedef struct { + P *path_info; + corres *correspond; + target **targets; + int num_cams, max_targets; + int num_parts; /* Number of 3D particles in the correspondence buffer */ + int *num_targets; /* Pointer to array of 2D particle counts per image. */ +} frame; + +void frame_init(frame *new_frame, int num_cams, int max_targets); +void free_frame(frame *self); +int read_frame(frame *self, char *corres_file_base, char *linkage_file_base, + char *prio_file_base, char **target_file_base, int frame_num); +int write_frame(frame *self, char *corres_file_base, char *linkage_file_base, + char *prio_file_base, char **target_file_base, int frame_num); + + +typedef struct { + /* _ring_vec is the underlying double-size vector, buf is the pointer to + the start of the ring. */ + frame **buf, **_ring_vec; + int buf_len, num_cams; + char *corres_file_base, *linkage_file_base, *prio_file_base; + char **target_file_base; +} framebuf; + +void fb_init(framebuf *new_buf, int buf_len, int num_cams, int max_targets,\ + char *corres_file_base, char* linkage_file_base, char *prio_file_base, + char **target_file_base); +void fb_free(framebuf *self); +void fb_next(framebuf *self); +void fb_prev(framebuf *self); +int fb_read_frame_at_end(framebuf *self, int frame_num, int read_links); +int fb_write_frame_from_start(framebuf *self, int frame_num); + +#endif diff --git a/liboptv/src/Makefile.am b/liboptv/src/Makefile.am new file mode 100644 index 00000000..2b73fbff --- /dev/null +++ b/liboptv/src/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in +lib_LTLIBRARIES = liboptv.la + +liboptv_la_SOURCES = tracking_frame_buf.c ../include/tracking_frame_buf.h +liboptv_la_CFLAGS = -I../include/ + diff --git a/liboptv/src/tracking_frame_buf.c b/liboptv/src/tracking_frame_buf.c new file mode 100644 index 00000000..82cc9551 --- /dev/null +++ b/liboptv/src/tracking_frame_buf.c @@ -0,0 +1,679 @@ +/* +Implementation for the tracking frame buffers. Each frame holds target information +for all cameras, correspondence information and path links information. + +Contains functions for dealing with the frame content, such as comparing and +reading targets, correspondences, etc. +*/ + +#include +#include +#include +#include "tracking_frame_buf.h" + +/* Check that target t1 is equal to target t2, i.e. all their fields are equal. + * + * Arguments: + * target *t1, *t2 - the target structures to compare. + * + * Returns: + * true if all fields are equal, false otherwise. +*/ +int compare_targets(target *t1, target *t2) { + return (\ + (t1->pnr == t2->pnr) && (t1->x == t2->x) && (t1->y == t2->y) && \ + (t1->n == t2->n) && (t1->nx == t2->nx) && (t1->ny == t2->ny) && \ + (t1->sumg == t2->sumg) && (t1->tnr == t2->tnr)); +} + +/* Reads targets from a file. The number of targets is read from the first + * line, then each line is one target. + * + * Arguments: + * target buffer[] - an allocated array of target structs to fill in from + * files. + * char* file_base - base name of the files to read, to which a frame number + * and the suffix '_targets' is added. + * int frame_num - number of frame to add to file_base. A value of 0 or less + * means that no frame number should be added. + * + * Returns: + * the number of targets found in the file, or 0 if an error occurred. +*/ + +int read_targets(target buffer[], char* file_base, int frame_num) { + FILE *FILEIN; + int tix, num_targets, scanf_ok; + char filein[STR_MAX_LEN + 1]; + + if (frame_num > 0) { + sprintf(filein, "%s%04d%s", file_base, frame_num, "_targets"); + } else { + strncpy(filein, file_base, STR_MAX_LEN); + strncat(filein, "_targets", STR_MAX_LEN); + } + + FILEIN = fopen (filein, "r"); + if (! FILEIN) { + printf("Can't open ascii file: %s\n", filein); + goto handle_error; + } + + if (fscanf(FILEIN, "%d\n", &num_targets) == 0) { + printf("Bad format for file: %s\n", filein); + goto handle_error; + } + for (tix = 0; tix < num_targets; tix++) { + scanf_ok = fscanf (FILEIN, "%4d %lf %lf %d %d %d %d %d\n", + &(buffer[tix].pnr), &(buffer[tix].x), + &(buffer[tix].y), &(buffer[tix].n), + &(buffer[tix].nx), &(buffer[tix].ny), + &(buffer[tix].sumg), &(buffer[tix].tnr) ); + + if (scanf_ok == 0) { + printf("Bad format for file: %s\n", filein); + goto handle_error; + } + } + + fclose (FILEIN); + return num_targets; + +handle_error: + if (FILEIN != NULL) fclose (FILEIN); + return 0; +} + +/* Writes targets to a file. The number of targets is written to the first + * line, then each line is one target. + * + * Arguments: + * target buffer[] - an allocated array of target structs to fill in from + * files. + * int num_targets - length of the targets buffer. + * char* file_base - base name of the files to read, to which a frame number + * and the suffix '_targets' is added. + * int frame_num - number of frame to add to file_base. A value of 0 or less + * means that no frame number should be added. + * + * Returns: + * True value on success, or 0 if an error occurred. +*/ +int write_targets(target buffer[], int num_targets, char* file_base, \ + int frame_num) { + + FILE *FILEOUT; + int tix, printf_ok, success = 0; + char fileout[STR_MAX_LEN + 1]; + + sprintf(fileout, "%s%04d%s", file_base, frame_num, "_targets"); + + FILEOUT = fopen(fileout, "w"); + if (! FILEOUT) { + printf("Can't open ascii file: %s\n", fileout); + goto finalize; + } + + if (fprintf (FILEOUT, "%d\n", num_targets) <= 0) { + printf("Write error in file %s\n", fileout); + goto finalize; + } + + for (tix = 0; tix < num_targets; tix++) { + printf_ok = fprintf(FILEOUT, "%4d %9.4f %9.4f %5d %5d %5d %5d %5d\n", + buffer[tix].pnr, buffer[tix].x, + buffer[tix].y, buffer[tix].n, + buffer[tix].nx, buffer[tix].ny, + buffer[tix].sumg, buffer[tix].tnr); + if (printf_ok <= 0) { + printf("Write error in file %s\n", fileout); + goto finalize; + } + } + success = 1; + +finalize: + if (FILEOUT != NULL) fclose (FILEOUT); + return success; +} + +/* Check that two correspondence structs are equal, i.e. all their fields are + * equal. + * + * Arguments: + * corres *c1, *c2 - the target structures to compare. + * + * Returns: + * true if all fields are equal, false otherwise. +*/ +int compare_corres(corres *c1, corres *c2) { + return ((c1->nr == c2->nr) && (c1->p[0] == c2->p[0]) && \ + (c1->p[1] == c2->p[1]) && (c1->p[2] == c2->p[2]) && \ + (c1->p[3] == c2->p[3])); +} + +/* Check that two path info (P) structs are equal, i.e. all their fields are + * equal. + * + * Arguments: + * P *p1, *p2 - the target structures to compare. + * + * Returns: + * true if all fields are equal, false otherwise. +*/ +int compare_path_info(P *p1, P *p2) { + int iter; + if (!((p1->prev == p2->prev) && (p1->next == p2->next) && \ + (p1->prio == p2->prio) && (p1->finaldecis == p2->finaldecis) && \ + (p1->inlist == p2->inlist))) + return 0; + + for (iter = 0; iter < 3; iter++) { + if (p1->x[iter] != p2->x[iter]) return 0; + } + for (iter = 0; iter < POSI; iter++) { + if (p1->decis[iter] != p2->decis[iter]) return 0; + if (p1->linkdecis[iter] != p2->linkdecis[iter]) return 0; + } + return 1; +} + +/* register_link_candidate() adds information on a possible link to a path info + * structure. + * + * Arguments: + * P *self - the path info structure to modify. + * fitness_t fitness - the likelihood of the link candidate to actually be the + * correct link, based on physical criteria. + * int cand - the candidate's index in next frame's target list. + */ +void register_link_candidate(P *self, fitness_t fitness, int cand) { + self->decis[self->inlist] = fitness; + self->linkdecis[self->inlist] = cand; + self->inlist++; +} + +/* reset_links() sets the prev, next and prio integer pointers to the + * default value representing no link. + * + * Arguments: + * P *self - the path info structure to modify. + */ +void reset_links(P *self) { + self->prev = PREV_NONE; + self->next = NEXT_NONE; + self->prio = PRIO_DEFAULT; +} + +/* Reads rt_is files. these files contain both the path info and the + * information on correspondence between targets on the different images. + * Sets fields not in file to default values. + * + * Arguments: + * corres *cor_buf - a buffer of corres structs to fill in from the file. + * P *path_buf - same for path info structures. + * char* corres_file_base, *linkage_file_base - base names of the output + * correspondence and likage files respectively, to which a frame number + * is added. Without separator. + * char *prio_file_base - for the linkage file with added 'prio' column. + * int frame_num - number of frame to add to file_base. A value of 0 or less + * means that no frame number should be added. The '.' separator is added + * between the name and the frame number. + * + * Returns: + * The number of points read for this frame. 0 on failure. +*/ +int read_path_frame(corres *cor_buf, P *path_buf, \ + char *corres_file_base, char *linkage_file_base, char *prio_file_base, + int frame_num) +{ + FILE *filein, *linkagein = NULL, *prioin = NULL; + char fname[STR_MAX_LEN]; + int read_res = 0, targets = 0, alt_link = 0; + double discard; /* For position values that are to be read again from a + differnt file. */ + + /* File format: first line contains the number of points, then each line is + a record of path and correspondence info. We don't need the nuber of points + because we read to EOF anyway. */ + + sprintf(fname, "%s.%d", corres_file_base, frame_num); + filein = fopen (fname, "r"); + if (!filein) { + /* Keeping the printf until we have proper logging. */ + printf("Can't open ascii file: %s\n", fname); + goto finalize; + } + + read_res = fscanf(filein, "%d\n", &read_res); + if (!read_res) goto finalize; + + if (linkage_file_base != NULL) { + sprintf(fname, "%s.%d", linkage_file_base, frame_num); + linkagein = fopen (fname, "r"); + + if (!linkagein) { + /* Keeping the printf until we have proper logging. */ + printf("Can't open linkage file: %s\n", fname); + goto finalize; + } + + read_res = fscanf(linkagein, "%d\n", &read_res); + if (!read_res) goto finalize; + } + + if (prio_file_base != NULL) { + sprintf(fname, "%s.%d", prio_file_base, frame_num); + prioin = fopen (fname, "r"); + + if (!prioin) { + /* Keeping the printf until we have proper logging. */ + printf("Can't open prio file: %s\n", fname); + goto finalize; + } + + read_res = fscanf(prioin, "%d\n", &read_res); + if (!read_res) goto finalize; + } + + do { + if (linkagein != NULL) { + read_res = fscanf(linkagein, "%4d %4d %lf %lf %lf\n", + &(path_buf->prev), &(path_buf->next), &discard, &discard, &discard); + if (!read_res) { + printf("Error with linkage file format in: %s.%d\n", + linkage_file_base, frame_num); + targets = 0; + break; + } + } else { + /* Defaults: */ + path_buf->prev = -1; + path_buf->next = -2; + } + + if (prioin != NULL) { + read_res = fscanf( prioin, "%4d %4d %lf %lf %lf %d\n", + &read_res, &read_res, &discard, &discard, &discard, + &(path_buf->prio) ); + if (!read_res) { + printf("Error with linkage file format in: %s.%d\n", + linkage_file_base, frame_num); + targets = 0; + break; + } + } else { + path_buf->prio = 4; + } + + /* Initialize tracking-related transient variables. These never get + saved or restored. */ + path_buf->inlist = 0; + path_buf->finaldecis = 1000000.0; + + for (alt_link = 0; alt_link < POSI; alt_link++) { + path_buf->decis[alt_link] = 0.0; + path_buf->linkdecis[alt_link] = -999; + } + + /* Rest of values: */ + read_res = fscanf(filein, "%d %lf %lf %lf %d %d %d %d\n",\ + &read_res, &(path_buf->x[0]), &(path_buf->x[1]), &(path_buf->x[2]), + &(cor_buf->p[0]), &(cor_buf->p[1]), &(cor_buf->p[2]), + &(cor_buf->p[3]) ); + + if (read_res != 8) { + targets = 0; + break; + } + + cor_buf->nr = ++targets; + + cor_buf++; + path_buf++; + } while (!feof(filein)); + +finalize: + if (filein != NULL) fclose(filein); + if (linkagein != NULL) fclose(linkagein); + if (prioin != NULL) fclose(prioin); + return targets; +} + +/* write_path_frame() writes the correspondence and linkage information for a + * frame with the next and previous frames. The information is weirdly + * distributed among two files. The rt_is file holds correspondence and + * position data, and the ptv_is holds linkage data. + * + * Arguments: + * corres *cor_buf - an array of corres structs to write to the files. + * P *path_buf - same for path info structures. + * int num_parts - number of particles represented by the cor_buf and path_buf + * arrays, i.e. the arrays' length. + * char* corres_file_base, *linkage_file_base - base names of the output + * correspondence and likage files respectively, to which a frame number + * is added. Without separator. + * char *prio_file_base - for the linkage file with added 'prio' column. + * int frame_num - number of frame to add to file_base. The '.' separator is + * added between the name and the frame number. + * + * Returns: + * True on success. 0 on failure. + */ +int write_path_frame(corres *cor_buf, P *path_buf, int num_parts,\ + char *corres_file_base, char *linkage_file_base, char *prio_file_base, + int frame_num) +{ + FILE *corres_file, *linkage_file = NULL, *prio_file = NULL; + char corres_fname[STR_MAX_LEN + 1], linkage_fname[STR_MAX_LEN + 1]; + char prio_fname[STR_MAX_LEN + 1]; + int pix, success = 0; + + sprintf(corres_fname, "%s.%d", corres_file_base, frame_num); + corres_file = fopen (corres_fname, "w"); + if (corres_file == NULL) { + printf("Can't open file %s for writing\n", corres_fname); + goto finalize; + } + + sprintf(linkage_fname, "%s.%d", linkage_file_base, frame_num); + linkage_file = fopen (linkage_fname, "w"); + if (linkage_file == NULL) { + printf("Can't open file %s for writing\n", linkage_fname); + goto finalize; + } + + fprintf(corres_file, "%d\n", num_parts); + fprintf(linkage_file, "%d\n", num_parts); + + if (prio_file_base != NULL) { + sprintf(prio_fname, "%s.%d", prio_file_base, frame_num); + prio_file = fopen (prio_fname, "w"); + if (prio_file == NULL) { + printf("Can't open file %s for writing\n", prio_fname); + goto finalize; + } + fprintf(prio_file, "%d\n", num_parts); + } + + for(pix = 0; pix < num_parts; pix++) { + fprintf(linkage_file, "%4d %4d %10.3f %10.3f %10.3f\n", + path_buf[pix].prev, path_buf[pix].next, path_buf[pix].x[0], + path_buf[pix].x[1], path_buf[pix].x[2]); + + fprintf(corres_file, "%4d %9.3f %9.3f %9.3f %4d %4d %4d %4d\n", + pix + 1, path_buf[pix].x[0], path_buf[pix].x[1], path_buf[pix].x[2], + cor_buf[pix].p[0], cor_buf[pix].p[1], cor_buf[pix].p[2], + cor_buf[pix].p[3]); + + if (prio_file_base == NULL) continue; + fprintf(prio_file, "%4d %4d %10.3f %10.3f %10.3f %d\n", + path_buf[pix].prev, path_buf[pix].next, path_buf[pix].x[0], + path_buf[pix].x[1], path_buf[pix].x[2], path_buf[pix].prio); + } + success = 1; + +finalize: + if (corres_file != NULL) fclose(corres_file); + if (linkage_file != NULL) fclose(linkage_file); + if (prio_file != NULL) fclose(prio_file); + + return success; +} + +/* init_frame() initializes a frame object, allocates its arrays and sets up + * the frame data. + * + * Arguments: + * int num_cams - number of cameras per frame. + * int max_targets - number of elements to allocate for the different buffers + * held by a frame. + */ +void frame_init(frame *new_frame, int num_cams, int max_targets) { + int cam; + + new_frame->path_info = (P *) calloc(max_targets, sizeof(P)); + new_frame->correspond = (corres *) calloc(max_targets, sizeof(corres)); + + new_frame->targets = (target**) calloc(num_cams, sizeof(target*)); + new_frame->num_targets = (int *) calloc(max_targets, sizeof(int)); + + for (cam = 0; cam < num_cams; cam++) { + new_frame->targets[cam] = \ + (target *) calloc(max_targets, sizeof(target)); + new_frame->num_targets[cam] = 0; + } + + new_frame->num_cams = num_cams; + new_frame->max_targets = max_targets; + new_frame->num_parts = 0; +} + +/* free_frame() frees all memory allocated for the frame arrays. + * + * Arguments: + * frame *self - the frame to free. + */ +void free_frame(frame *self) { + free(self->path_info); + self->path_info = NULL; + + free(self->correspond); + self->correspond = NULL; + + free(self->num_targets); + self->num_targets = NULL; + + for (; self->num_cams > 0; self->num_cams--) { + free(self->targets[self->num_cams - 1]); + self->targets[self->num_cams - 1] = NULL; + } + + free(self->targets); + self->targets = NULL; +} + +/* read_frame() reads all of the frame associated data: correspondences, + * targets, and whatever else is needed. Mark files to be ignored by passing + * NULL as name (only the path-info and prio files). + * + * Arguments: + * frame *self - the frame object to fill with the data read. + * char* corres_file_base, *linkage_file_base - base names of the output + * correspondence and likage files respectively, to which a frame number + * is added. Without separator. + * char *prio_file_base - for the linkage file with added 'prio' column. + * char **target_file_base - an array of strings following the same rules as + * for file_base; one for each camera in the frame. + * int frame_num - number of frame to add to file_base. A value of 0 or less + * means that no frame number should be added. The '.' separator is added + * between the name and the frame number. + * + * Returns: + * True on success, false otherwise. In case of failure, the state of frame is + * undefined. + */ +int read_frame(frame *self, char *corres_file_base, char *linkage_file_base, + char *prio_file_base, char **target_file_base, + int frame_num) +{ + int cam; + + self->num_parts = read_path_frame(self->correspond, self->path_info, + corres_file_base, linkage_file_base, prio_file_base, frame_num); + if (self->num_targets == 0) return 0; + + for (cam = 0; cam < self->num_cams; cam++) { + self->num_targets[cam] = read_targets( + self->targets[cam], target_file_base[cam], frame_num); + if (self->num_targets[cam] == 0) return 0; + } + + return 1; +} + +/* write_frame() writes all of the frame associated data: correspondnces, + * targets, path info, and whatever else is needed. + * + * Arguments: + * frame *self - the frame whose data is to be written. + * char *corres_file_base - base name of the correspondence file to read, to + * which a frame number is added. Without separator. + * char *linkage_file_base - same as corres_file_base, for the linkage file. + * char *prio_file_base - for the linkage file with added 'prio' column. + * char **target_file_base - an array of strings following the same rules as + * for file_base; one for each camera in the frame. + * int frame_num - number of frame to add to file_base. A value of 0 or less + * means that no frame number should be added. The '.' separator is added + * between the name and the frame number. + * + * Returns: + * True on success, false otherwise. In case of failure, the state of output + * files is undefined. + */ +int write_frame(frame *self, char *corres_file_base, char *linkage_file_base, + char *prio_file_base, char **target_file_base, int frame_num) +{ + int cam, status; + + status = write_path_frame(self->correspond, self->path_info, + self->num_parts, corres_file_base, linkage_file_base, prio_file_base, + frame_num); + if (status == 0) return 0; + + for (cam = 0; cam < self->num_cams; cam++) { + status = write_targets( + self->targets[cam], self->num_targets[cam], target_file_base[cam], + frame_num); + if (status == 0) return 0; + } + + return 1; +} + +/* fb_init() allocates a frame buffer object and creates the frames + * it buffers. The buffer is a ring-buffer based on a double-size vector. + * + * Arguments: + * int buf_len - number of frames in the buffer. + * int num_cams - number of cameras per frame. + * int max_targets - number of elements to allocate for the different buffers + * held by a frame. + * char *rt_file_base + * + * Returns: + * a pointer to the new dynamically allocated frame-buffer structure. + */ + +void fb_init(framebuf *new_buf, int buf_len, int num_cams, int max_targets,\ + char *corres_file_base, char *linkage_file_base, char *prio_file_base, + char **target_file_base) +{ + frame *alloc_frame; + + new_buf->buf_len = buf_len; + new_buf->num_cams = num_cams; + new_buf->corres_file_base = corres_file_base; + new_buf->linkage_file_base = linkage_file_base; + new_buf->prio_file_base = prio_file_base; + new_buf->target_file_base = target_file_base; + + new_buf->_ring_vec = (frame **) calloc(buf_len*2, sizeof(frame *)); + new_buf->buf = new_buf->_ring_vec + buf_len; + + while (new_buf->buf != new_buf->_ring_vec) { + new_buf->buf--; + + alloc_frame = (frame *) malloc(sizeof(frame)); + frame_init(alloc_frame, num_cams, max_targets); + + /* The second half of _ring_vec points to the same objects as the + first half. This allows direct indexing like fb->buf[buf_len - 1] + even when fb->buf moves forward. */ + *(new_buf->buf) = alloc_frame; + *(new_buf->buf + buf_len) = alloc_frame; + } + /* Leaves new_buf->buf pointing to the beginning of _ring_vec, + which is what we want. */ +} + +/* fb_free() frees all memory allocated for the frames and ring vector in a + * framebuf object. + * + * Arguments: + * framebuf *self - the framebuf holding the memory to free. + */ +void fb_free(framebuf *self) { + self->buf = self->_ring_vec; + + while (self->buf != self->_ring_vec + self->buf_len) { + free_frame(*(self->buf)); + free(*(self->buf)); + self->buf++; + } + self->buf = NULL; + + free(self->_ring_vec); + self->_ring_vec = NULL; +} + +/* fb_next() advances the start pointer of the frame buffer, resetting it to the + * beginning after exceeding the buffer length. + * + * Arguments: + * framebuf *self - the framebuf to advance. + */ +void fb_next(framebuf *self) { + self->buf++; + if (self->buf - self->_ring_vec >= self->buf_len) + self->buf = self->_ring_vec; +} + +/* fb_prev() backs the start pointer of the frame buffer, setting it to the + * end after exceeding the buffer start. + * + * Arguments: + * framebuf *self - the framebuf to advance. + */ +void fb_prev(framebuf *self) { + self->buf--; + if (self->buf < self->_ring_vec) + self->buf = self->_ring_vec + self->buf_len - 1; +} + +/* fb_read_frame_at_end() reads a frame to the last position in the ring. + * + * Arguments: + * framebuf *self - the framebuf object doing the reading. + * int frame_num - number of the frame to read in the sequence of frames. + * int read_links - whether or not to read data in the linkage/prio files. + * + * Returns: + * True on success, false on failure. + */ +int fb_read_frame_at_end(framebuf *self, int frame_num, int read_links) { + if (read_links) { + return read_frame(self->buf[self->buf_len - 1], self->corres_file_base, + self->linkage_file_base, self->prio_file_base, + self->target_file_base, frame_num); + } else { + return read_frame(self->buf[self->buf_len - 1], self->corres_file_base, + NULL, NULL, self->target_file_base, frame_num); + } +} + +/* fb_write_frame_from_start() writes the frame to the first position in the ring. + * + * Arguments: + * framebuf *self - the framebuf object doing the reading. + * int frame_num - number of the frame to write in the sequence of frames. + * + * Returns: + * True on success, false on failure. + */ +int fb_write_frame_from_start(framebuf *self, int frame_num) { + return write_frame(self->buf[0], self->corres_file_base, + self->linkage_file_base, self->prio_file_base, self->target_file_base, + frame_num); +} + diff --git a/liboptv/tests/Makefile.am b/liboptv/tests/Makefile.am new file mode 100644 index 00000000..fc0de67c --- /dev/null +++ b/liboptv/tests/Makefile.am @@ -0,0 +1,8 @@ +TESTS = check_fb +check_PROGRAMS = check_fb +dist_noinst_DATA = testing_fodder/* + +check_fb_SOURCES = check_fb.c $(top_builddir)/include/tracking_frame_buf.h +check_fb_CFLAGS = @CHECK_CFLAGS@ -I../include/ +check_fb_LDADD = $(top_builddir)/src/liboptv.la @CHECK_LIBS@ + diff --git a/liboptv/tests/check_fb.c b/liboptv/tests/check_fb.c new file mode 100644 index 00000000..aa86ec0c --- /dev/null +++ b/liboptv/tests/check_fb.c @@ -0,0 +1,299 @@ +/* Unit tests for functions related to the frame buffer. Uses the Check + framework: http://check.sourceforge.net/ + + To run it, type "make check" when in the top C directory, src_c/ + If that doesn't run the tests, use the Check tutorial: + http://check.sourceforge.net/doc/check_html/check_3.html +*/ + +#include +#include +#include + +#include "tracking_frame_buf.h" + +START_TEST(test_read_targets) +{ + target tbuf[2]; /* Two targets in the sample target file */ + target t1 = {0, 1127.0000, 796.0000, 13320, 111, 120, 828903, 1}; + target t2 = {1, 796.0000, 809.0000, 13108, 113, 116, 658928, 0}; + + char *file_base = "testing_fodder/sample_"; + int frame_num = 42; + int targets_read = 0; + + targets_read = read_targets(tbuf, file_base, frame_num); + fail_unless(targets_read == 2); + fail_unless(compare_targets(tbuf, &t1)); + fail_unless(compare_targets(tbuf + 1, &t2)); +} +END_TEST + +START_TEST(test_write_targets) +{ + /* Write and read back two targets, make sure they're the same. + Assumes that read_targets is ok, which is tested separately. */ + + target tbuf[2]; /* Two targets in the sample target file */ + target t1 = {0, 1127.0000, 796.0000, 13320, 111, 120, 828903, 1}; + target t2 = {1, 796.0000, 809.0000, 13108, 113, 116, 658928, 0}; + + char *file_base = "testing_fodder/test_"; + int frame_num = 42; + int num_targets = 2; + + tbuf[0] = t1; tbuf[1] = t2; + fail_unless(write_targets(tbuf, num_targets, file_base, frame_num)); + + num_targets = read_targets(tbuf, file_base, frame_num); + fail_unless(num_targets == 2); + fail_unless(compare_targets(tbuf, &t1)); + fail_unless(compare_targets(tbuf + 1, &t2)); + + // Leave the test directory clean: + remove("testing_fodder/test_0042_targets"); +} +END_TEST + +START_TEST(test_read_path_frame) +{ + corres cor_buf[80]; + P path_buf[80]; + int alt_link; + + /* Correct values for particle 3 */ + P path_correct = { + .x = {45.219, -20.269, 25.946}, + .prev = -1, + .next = -2, + .prio = 4, + .finaldecis = 1000000.0, + .inlist = 0. + }; + for (alt_link = 0; alt_link < POSI; alt_link++) { + path_correct.decis[alt_link] = 0.0; + path_correct.linkdecis[alt_link] = -999; + } + corres c_correct = { 3, {96, 66, 26, 26} }; + + char *file_base = "testing_fodder/rt_is"; + int frame_num = 818; + int targets_read = 0; + + /* Test unlinked frame: */ + targets_read = read_path_frame(cor_buf, path_buf, file_base, NULL, NULL, + frame_num); + fail_unless(targets_read == 80); + + fail_unless(compare_corres(cor_buf + 2, &c_correct), \ + "Got corres: %d, [%d %d %d %d]", cor_buf[2].nr, \ + cor_buf[2].p[0], cor_buf[2].p[1], cor_buf[2].p[2], cor_buf[2].p[3]); + fail_unless(compare_path_info(path_buf + 2, &path_correct)); + + /* Test frame with links */ + path_correct.prev = 0; + path_correct.next = 0; + path_correct.prio = 0; + char *linkage_base = "testing_fodder/ptv_is"; + char *prio_base = "testing_fodder/added"; + + targets_read = read_path_frame(cor_buf, path_buf, file_base, linkage_base, + prio_base, frame_num); + fail_unless(targets_read == 80); + fail_unless(compare_corres(cor_buf + 2, &c_correct), \ + "Got corres: %d, [%d %d %d %d]", cor_buf[2].nr, \ + cor_buf[2].p[0], cor_buf[2].p[1], cor_buf[2].p[2], cor_buf[2].p[3]); + fail_unless(compare_path_info(path_buf + 2, &path_correct)); +} +END_TEST + +START_TEST(test_write_path_frame) +{ + corres cor_buf[] = { {1, {96, 66, 26, 26}}, {2, {30, 31, 32, 33}} }; + P path_buf[] = { + { + .x = {45.219, -20.269, 25.946}, + .prev = -1, + .next = -2, + .prio = 4, + .finaldecis = 1000000.0, + .inlist = 0. + }, + { + .x = {45.219, -20.269, 25.946}, + .prev = -1, + .next = -2, + .prio = 0, + .finaldecis = 2000000.0, + .inlist = 1. + } + }; + + char *corres_file_base = "testing_fodder/rt_is"; + char *linkage_file_base = "testing_fodder/ptv_is"; + int frame_num = 42; + + fail_unless(write_path_frame(cor_buf, path_buf, 2,\ + corres_file_base, linkage_file_base, NULL, frame_num)); + + remove("testing_fodder/rt_is.42"); + remove("testing_fodder/ptv_is.42"); +} +END_TEST + +START_TEST(test_init_frame) +{ + frame frm; + + // Dummy things to store in the frame's buffers: + target t_target; + corres t_corres; + P t_path; + + int cams = 4; + int max_targets = 100; + int cam_ix = 0; + + frame_init(&frm, cams, max_targets); + + /* Try to write stuff into the allocated memory and see it doesn't + segfault.*/ + frm.correspond[42] = t_corres; + frm.path_info[42] = t_path; + + for (cam_ix = 0; cam_ix < cams; cam_ix ++) { + frm.targets[cam_ix][42] = t_target; + } + + fail_unless(frm.num_cams == cams); + fail_unless(frm.max_targets == max_targets); +} +END_TEST + +/* *_frame() are just simple wrappers around *_path_frame and *_targets, so + we only do a simple write-read cycle. The heavy testing is in the wrapped + functions. */ +START_TEST(test_read_write_frame) +{ + frame frm, readback; + char* target_files[2] = { + "testing_fodder/target_test_cam0", "testing_fodder/target_test_cam1"}; + char *corres_base = "testing_fodder/corres_test"; + char *linkage_base = "testing_fodder/ptv_test"; + char *prio_base = "testing_fodder/added_test"; + char namebuf[100]; /* For removals */ + int alt_link; + + // Dummy things to store in the frame's buffers: + target t_target = {0, 1127.0000, 796.0000, 13320, 111, 120, 828903, 1}; + corres t_corres = { 3, {96, 66, 26, 26} }; + P t_path = { + .x = {45.219, -20.269, 25.946}, + .prev = -1, + .next = -2, + .prio = 4, + .finaldecis = 1000000.0, + .inlist = 0. + }; + for (alt_link = 0; alt_link < POSI; alt_link++) { + t_path.decis[alt_link] = 0.0; + t_path.linkdecis[alt_link] = -999; + } + + int cams = 2; + int max_targets = 100; + int cam_ix = 0; + int frame_num = 7; + + frame_init(&frm, cams, max_targets); + + /* Try to write stuff into the allocated memory and see it doesn't + segfault.*/ + frm.correspond[2] = t_corres; + frm.path_info[2] = t_path; + frm.num_parts = 3; + + for (cam_ix = 0; cam_ix < cams; cam_ix++) { + frm.targets[cam_ix][42] = t_target; + frm.num_targets[cam_ix] = 43; + } + + fail_unless(write_frame(&frm, corres_base, linkage_base, NULL, + target_files, frame_num)); + + frame_init(&readback, cams, max_targets); + fail_unless(read_frame(&readback, corres_base, NULL, NULL, target_files, + frame_num)); + + fail_unless(compare_corres(&t_corres, readback.correspond + 2)); + fail_unless(compare_path_info(&t_path, readback.path_info + 2)); + fail_unless(compare_targets(&t_target, readback.targets[0] + 42)); + + /* Now read frame with links: */ + t_path.prev = 0; + t_path.next = 0; + t_path.prio = 0; + frm.path_info[2] = t_path; + + fail_unless(write_frame(&frm, corres_base, linkage_base, prio_base, + target_files, frame_num)); + + frame_init(&readback, cams, max_targets); + fail_unless(read_frame(&readback, corres_base, linkage_base, prio_base, + target_files, frame_num)); + + fail_unless(compare_corres(&t_corres, readback.correspond + 2)); + fail_unless(compare_path_info(&t_path, readback.path_info + 2)); + fail_unless(compare_targets(&t_target, readback.targets[0] + 42)); + + sprintf(namebuf, "%s.%d", corres_base, frame_num); + remove(namebuf); + sprintf(namebuf, "%s.%d", linkage_base, frame_num); + remove(namebuf); + sprintf(namebuf, "%s.%d", prio_base, frame_num); + remove(namebuf); + remove("testing_fodder/target_test_cam10007_targets"); + remove("testing_fodder/target_test_cam00007_targets"); +} +END_TEST + +Suite* fb_suite(void) { + Suite *s = suite_create ("Frame Buffer"); + + TCase *tc_trt = tcase_create ("Read targets"); + tcase_add_test(tc_trt, test_read_targets); + suite_add_tcase (s, tc_trt); + + TCase *tc_twt = tcase_create ("Write targets"); + tcase_add_test(tc_twt, test_write_targets); + suite_add_tcase (s, tc_twt); + + TCase *tc_trpf = tcase_create ("Read path frame"); + tcase_add_test(tc_trpf, test_read_path_frame); + suite_add_tcase (s, tc_trpf); + + TCase *tc_twpf = tcase_create ("Write path frame"); + tcase_add_test(tc_twpf, test_write_path_frame); + suite_add_tcase (s, tc_twpf); + + TCase *tc_tcf = tcase_create ("Create frame"); + tcase_add_test(tc_tcf, test_init_frame); + suite_add_tcase (s, tc_tcf); + + TCase *tc_trwf = tcase_create ("Write/read frame"); + tcase_add_test(tc_trwf, test_read_write_frame); + suite_add_tcase (s, tc_trwf); + + return s; +} + +int main(void) { + int number_failed; + Suite *s = fb_suite (); + SRunner *sr = srunner_create (s); + srunner_run_all (sr, CK_ENV); + number_failed = srunner_ntests_failed (sr); + srunner_free (sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + diff --git a/liboptv/tests/testing_fodder/added.818 b/liboptv/tests/testing_fodder/added.818 new file mode 100644 index 00000000..d3e23e71 --- /dev/null +++ b/liboptv/tests/testing_fodder/added.818 @@ -0,0 +1,81 @@ +80 + -1 -2 -7.011 -21.501 12.349 4 + -1 -2 36.471 -21.194 8.032 4 + 1 -2 30.712 -24.193 -2.844 0 + 2 -2 5.339 -21.580 24.271 4 + 4 -2 15.261 -21.394 15.612 4 + 3 -2 -7.042 -26.648 12.453 4 + -1 -2 32.151 -21.596 0.759 4 + 9 -2 -4.959 -21.481 14.949 4 + 8 -2 31.805 -26.822 1.991 4 + 13 -2 9.583 -22.328 7.732 4 + -1 -2 29.265 -21.103 3.220 4 + -1 -2 28.049 -24.262 -5.598 4 + 14 -2 11.700 -25.519 22.126 4 + 16 -2 28.056 -27.064 4.365 4 + -1 -2 25.904 -19.870 23.958 4 + 18 -2 -0.718 -23.333 27.665 4 + 19 -2 38.988 -24.290 19.793 4 + -1 -2 39.399 -21.571 16.467 4 + -1 -2 21.353 -26.432 8.770 4 + 23 -2 17.411 -24.238 17.690 4 + 22 -2 1.460 -20.241 20.514 4 + 49 -2 29.964 -26.855 5.476 4 + -1 -2 22.031 -23.824 -2.434 4 + -1 -2 46.144 -11.354 -14.243 4 + -1 -2 9.559 -27.413 8.360 4 + -1 -2 -12.530 -21.663 -1.709 4 + 29 -2 3.415 -25.547 16.941 4 + 30 -2 2.749 -21.106 19.663 4 + 31 -2 15.368 -26.396 15.932 4 + 32 -2 -4.773 -20.271 21.659 4 + 37 -2 18.753 -21.682 28.538 4 + 36 -2 -12.376 -21.529 8.261 4 + 33 -2 -4.871 -25.378 22.165 4 + -1 -2 42.804 -17.877 17.192 4 + 35 -2 34.264 -24.097 1.231 4 + 78 -2 38.218 -26.769 28.695 4 + 40 -2 -11.926 -26.151 8.338 4 + -1 -2 -10.014 -22.533 15.683 4 + -1 -2 41.195 -29.150 15.181 4 + -1 -2 35.357 -28.461 5.777 4 + -1 -2 38.886 -22.541 27.330 4 + -1 -2 13.582 -21.537 15.219 4 + -1 -2 46.428 -21.184 18.236 4 + 45 -2 19.958 -21.548 30.494 4 + -1 -2 33.154 -21.303 -1.941 4 + -1 -2 30.988 -26.313 29.509 4 + 48 -2 10.561 -26.677 22.864 4 + -1 -2 26.827 1.093 -78.719 4 + 51 -2 43.296 -21.655 37.017 4 + -1 -2 25.796 -27.228 2.619 4 + -1 -2 16.972 -21.961 31.248 4 + -1 -2 38.401 -28.076 23.315 4 + -1 -2 34.418 -21.338 23.387 4 + 58 -2 5.805 -26.829 1.070 4 + 53 -2 17.034 -26.669 34.028 4 + 57 -2 -5.145 -26.814 16.195 4 + -1 -2 40.938 -23.954 25.872 4 + -1 -2 20.129 -18.745 21.287 4 + -1 -2 -5.240 -27.815 23.155 4 + 62 -2 -1.266 -26.233 -6.457 4 + 64 -2 42.785 -24.124 0.943 4 + -1 -2 46.226 -10.231 -18.858 4 + -1 -2 -16.153 -23.722 2.242 4 + -1 -2 42.194 -29.308 26.070 4 + -1 -2 23.942 -27.157 32.366 4 + -1 -2 -9.019 -20.723 15.812 4 + -1 -2 33.667 -16.808 -19.826 4 + 74 -2 -8.663 -24.198 -11.713 4 + 73 -2 3.013 -26.408 6.379 4 + -1 -2 51.143 -2.139 29.172 4 + -1 -2 29.066 -27.573 -8.127 4 + 77 -2 53.620 -20.393 10.205 4 + -1 -2 11.549 -2.768 -77.555 4 + -1 -2 33.667 -16.808 -19.826 4 + 74 -2 -8.663 -24.198 -11.713 4 + 73 -2 3.013 -26.408 6.379 4 + -1 -2 51.143 -2.139 29.172 4 + -1 -2 29.066 -27.573 -8.127 4 + 77 -2 53.620 -20.393 10.205 4 + -1 -2 11.549 -2.768 -77.555 4 diff --git a/liboptv/tests/testing_fodder/ptv_is.818 b/liboptv/tests/testing_fodder/ptv_is.818 new file mode 100644 index 00000000..afa451d2 --- /dev/null +++ b/liboptv/tests/testing_fodder/ptv_is.818 @@ -0,0 +1,81 @@ +80 + -1 -2 -7.011 -21.501 12.349 + -1 -2 36.471 -21.194 8.032 + 0 0 30.712 -24.193 -2.844 + 2 -2 5.339 -21.580 24.271 + 4 -2 15.261 -21.394 15.612 + 3 -2 -7.042 -26.648 12.453 + -1 -2 32.151 -21.596 0.759 + 9 -2 -4.959 -21.481 14.949 + 8 -2 31.805 -26.822 1.991 + 13 -2 9.583 -22.328 7.732 + -1 -2 29.265 -21.103 3.220 + -1 -2 28.049 -24.262 -5.598 + 14 -2 11.700 -25.519 22.126 + 16 -2 28.056 -27.064 4.365 + -1 -2 25.904 -19.870 23.958 + 18 -2 -0.718 -23.333 27.665 + 19 -2 38.988 -24.290 19.793 + -1 -2 39.399 -21.571 16.467 + -1 -2 21.353 -26.432 8.770 + 23 -2 17.411 -24.238 17.690 + 22 -2 1.460 -20.241 20.514 + 49 -2 29.964 -26.855 5.476 + -1 -2 22.031 -23.824 -2.434 + -1 -2 46.144 -11.354 -14.243 + -1 -2 9.559 -27.413 8.360 + -1 -2 -12.530 -21.663 -1.709 + 29 -2 3.415 -25.547 16.941 + 30 -2 2.749 -21.106 19.663 + 31 -2 15.368 -26.396 15.932 + 32 -2 -4.773 -20.271 21.659 + 37 -2 18.753 -21.682 28.538 + 36 -2 -12.376 -21.529 8.261 + 33 -2 -4.871 -25.378 22.165 + -1 -2 42.804 -17.877 17.192 + 35 -2 34.264 -24.097 1.231 + 78 -2 38.218 -26.769 28.695 + 40 -2 -11.926 -26.151 8.338 + -1 -2 -10.014 -22.533 15.683 + -1 -2 41.195 -29.150 15.181 + -1 -2 35.357 -28.461 5.777 + -1 -2 38.886 -22.541 27.330 + -1 -2 13.582 -21.537 15.219 + -1 -2 46.428 -21.184 18.236 + 45 -2 19.958 -21.548 30.494 + -1 -2 33.154 -21.303 -1.941 + -1 -2 30.988 -26.313 29.509 + 48 -2 10.561 -26.677 22.864 + -1 -2 26.827 1.093 -78.719 + 51 -2 43.296 -21.655 37.017 + -1 -2 25.796 -27.228 2.619 + -1 -2 16.972 -21.961 31.248 + -1 -2 38.401 -28.076 23.315 + -1 -2 34.418 -21.338 23.387 + 58 -2 5.805 -26.829 1.070 + 53 -2 17.034 -26.669 34.028 + 57 -2 -5.145 -26.814 16.195 + -1 -2 40.938 -23.954 25.872 + -1 -2 20.129 -18.745 21.287 + -1 -2 -5.240 -27.815 23.155 + 62 -2 -1.266 -26.233 -6.457 + 64 -2 42.785 -24.124 0.943 + -1 -2 46.226 -10.231 -18.858 + -1 -2 -16.153 -23.722 2.242 + -1 -2 42.194 -29.308 26.070 + -1 -2 23.942 -27.157 32.366 + -1 -2 -9.019 -20.723 15.812 + -1 -2 33.667 -16.808 -19.826 + 74 -2 -8.663 -24.198 -11.713 + 73 -2 3.013 -26.408 6.379 + -1 -2 51.143 -2.139 29.172 + -1 -2 29.066 -27.573 -8.127 + 77 -2 53.620 -20.393 10.205 + -1 -2 11.549 -2.768 -77.555 + -1 -2 33.667 -16.808 -19.826 + 74 -2 -8.663 -24.198 -11.713 + 73 -2 3.013 -26.408 6.379 + -1 -2 51.143 -2.139 29.172 + -1 -2 29.066 -27.573 -8.127 + 77 -2 53.620 -20.393 10.205 + -1 -2 11.549 -2.768 -77.555 diff --git a/liboptv/tests/testing_fodder/rt_is.818 b/liboptv/tests/testing_fodder/rt_is.818 new file mode 100644 index 00000000..43e6790f --- /dev/null +++ b/liboptv/tests/testing_fodder/rt_is.818 @@ -0,0 +1,81 @@ +80 + 1 9.170 -20.365 20.781 57 74 32 49 + 2 6.526 -22.297 34.317 106 123 18 44 + 3 45.219 -20.269 25.946 96 66 26 26 + 4 33.024 -21.783 6.242 54 44 82 71 + 5 32.979 -24.271 -3.250 59 51 127 115 + 6 42.905 -21.814 25.693 113 73 41 27 + 7 4.341 -25.495 14.405 82 103 94 117 + 8 35.079 -21.146 6.780 53 41 72 63 + 9 33.056 -27.098 6.396 110 81 132 122 + 10 18.573 -21.424 27.034 83 95 27 41 + 11 53.554 -26.844 8.902 115 83 130 100 + 12 53.310 -21.422 10.863 70 49 81 39 + 13 34.755 -24.286 -7.157 44 42 137 127 + 14 -0.545 -26.370 15.841 87 118 101 133 + 15 17.146 -21.255 14.391 55 63 56 58 + 16 21.846 -22.655 13.419 67 68 71 85 + 17 34.723 -26.847 7.947 107 92 123 116 + 18 47.591 -21.233 10.068 66 45 73 48 + 19 49.490 -27.767 8.278 122 90 147 109 + 20 14.237 -23.933 3.655 56 61 109 113 + 21 11.522 -27.653 8.813 101 104 120 146 + 22 47.092 -21.252 21.216 91 -1 49 30 + 23 19.956 -24.978 25.574 -1 111 65 74 + 24 26.423 -21.875 29.213 -1 100 33 37 + 25 46.457 -26.892 23.656 -1 110 104 76 + 26 47.978 -27.029 24.095 -1 112 103 73 + 27 44.448 -26.828 24.199 -1 116 93 79 + 28 11.689 -23.919 36.164 -1 133 34 50 + 29 42.165 -23.164 15.011 93 -1 84 55 + 30 14.560 -19.792 16.757 50 -1 36 46 + 31 21.951 -21.705 30.464 -1 99 25 36 + 32 13.949 -23.709 13.856 75 82 -1 92 + 33 10.148 -24.958 11.096 -1 91 95 108 + 34 6.187 -25.686 34.921 -1 150 46 78 + 35 21.043 -22.770 22.574 89 -1 48 61 + 36 23.271 -24.997 23.825 114 -1 69 81 + 37 29.558 -29.612 -2.433 108 89 -1 165 + 38 6.210 -21.888 22.360 71 93 -1 67 + 39 33.566 -21.522 10.286 -1 57 70 65 + 40 31.568 -21.605 9.458 58 58 67 -1 + 41 1.662 -22.751 22.988 76 -1 40 82 + 42 36.576 -26.506 -1.884 81 -1 148 137 + 43 32.875 -18.697 -3.807 29 -1 79 64 + 44 52.778 -24.284 8.790 95 -1 112 77 + 45 50.874 -25.538 38.626 -1 138 55 32 + 46 62.750 -24.533 4.234 103 56 -1 69 + 47 52.834 -19.582 24.969 84 -1 23 24 + 48 0.284 -24.110 38.684 -1 149 22 56 + 49 33.202 -26.988 9.729 -1 97 124 110 + 50 17.389 -23.628 15.171 -1 87 76 86 + 51 -14.071 0.678 22.782 23 26 12 -1 + 52 -14.388 -23.736 2.817 40 -1 97 140 + 53 9.706 -27.131 28.655 -1 145 75 94 + 54 -11.490 -21.790 -1.759 -1 48 90 135 + 55 -16.157 -23.739 2.240 38 -1 98 142 + 56 -2.436 11.644 -8.389 15 -1 11 11 + 57 55.251 -21.039 14.385 80 -1 68 31 + 58 -0.239 -29.377 6.828 -1 121 146 171 + 59 39.372 -26.921 -12.514 65 47 -1 157 + 60 16.971 -22.894 29.463 -1 105 37 51 + 61 9.888 -29.845 8.361 116 124 -1 162 + 62 -10.014 -21.628 17.482 49 85 39 -1 + 63 16.288 -28.258 20.087 -1 141 108 124 + 64 14.316 -29.324 14.997 -1 131 129 141 + 65 30.292 -3.467 -80.573 -1 15 113 68 + 66 13.464 24.797 9.571 6 5 4 -1 + 67 19.786 -29.521 21.236 -1 143 116 131 + 68 46.320 -26.133 4.619 97 -1 138 104 + 69 1.699 -28.649 5.167 98 -1 144 164 + 70 41.179 -21.692 -13.638 31 33 133 -1 + 71 61.758 -18.985 5.890 47 37 -1 28 + 72 -1.664 11.511 22.846 19 18 9 -1 + 73 -12.714 -21.612 -1.050 -1 55 87 125 + 74 -8.639 -24.216 -11.870 -1 46 134 170 + 75 44.538 -11.667 -42.637 26 23 105 -1 + 76 25.250 -20.971 13.559 62 -1 57 54 + 77 54.890 19.986 9.558 10 7 7 -1 + 78 8.673 -25.192 26.434 -1 -1 63 88 + 79 9.223 -25.463 20.951 112 -1 78 95 + 80 49.717 -26.877 3.661 -1 69 -1 111 diff --git a/liboptv/tests/testing_fodder/sample_0042_targets b/liboptv/tests/testing_fodder/sample_0042_targets new file mode 100644 index 00000000..35fae4d5 --- /dev/null +++ b/liboptv/tests/testing_fodder/sample_0042_targets @@ -0,0 +1,3 @@ +2 + 0 1127.0000 796.0000 13320 111 120 828903 1 + 1 796.0000 809.0000 13108 113 116 658928 0