#include "../src/opticalflow.h"
#endif
+/* functions to load directory */
+
+typedef struct dir_entry {
+ struct dir_entry *next;
+ char name[0];
+} dir_t;
+
+static int cmpstringp(const void *p1, const void *p2)
+{
+ dir_t *entry1 = *(dir_t **)p1;
+ dir_t *entry2 = *(dir_t **)p2;
+
+ return strcmp(entry1->name, entry2->name);
+}
+
+static dir_t *fetch_dir(const char *path) /* NOTE: if path is not empty, it must end with DIR_SEPERATOR */
+{
+ int rc;
+ DIR *dir;
+ struct dirent dirent, *result;
+ dir_t *head = NULL, *entry, **entryp = &head;
+ int count = 0;
+ dir_t **list;
+ int i;
+
+ /* read linked list */
+ dir = opendir(path);
+ if (!dir)
+ return NULL;
+ while (1) {
+ rc = readdir_r(dir, &dirent, &result);
+ if (rc < 0)
+ break;
+ if (result == NULL)
+ break;
+ if (result->d_type != DT_REG && result->d_type != DT_LNK)
+ continue;
+ entry = calloc(1, sizeof(dir_t) + strlen(path) + strlen(result->d_name) + 1);
+ if (!entry) {
+ fprintf(stderr, "no memory");
+ return NULL;
+ }
+ *entryp = entry;
+ entryp = &entry->next;
+ strcpy(entry->name, path);
+ strcat(entry->name, result->d_name);
+ count++;
+ }
+ closedir(dir);
+
+ /* sort linked list */
+ list = calloc(count, sizeof(*list));
+ if (!list) {
+ fprintf(stderr, "no memory");
+ return NULL;
+ }
+ count = 0;
+ for (entry = head; entry; entry = entry->next) {
+ list[count] = entry;
+ count++;
+ }
+ qsort(list, count, sizeof(*list), cmpstringp);
+ entryp = &head;
+ for (i = 0; i < count; i++) {
+ /* relink */
+ entry = list[i];
+ entry->next = NULL;
+ *entryp = entry;
+ entryp = &entry->next;
+ }
+ free(list);
+
+ return head;
+}
+
+static void free_dir(dir_t *dir)
+{
+ dir_t *entry, *next;
+
+ entry = dir;
+ while (entry) {
+ next = entry->next;
+ free(entry);
+ entry = next;
+ }
+}
+
+
struct frame_list *frame_list = NULL;
/* currently loaded image */
}
}
+/* get path of given file name */
+static char *get_path(const char *filename)
+{
+ static char path[256];
+
+ /* copy name */
+ strcpy(path, filename);
+ /* remove until DIR_SEPERATOR */
+ while (path[0]) {
+ if (path[strlen(path) - 1] == DIR_SEPERATOR)
+ break;
+ path[strlen(path) - 1] = '\0';
+ }
+
+ return path;
+}
+
/* load directory and create pixbuf */
void create_timeline(const char *filename)
{
int i;
const char *p, *q;
- char temp[256], name[256], suffix[256];
+ char temp[256], suffix[256];
FILE *fp;
if (filename) {
strcpy(frame_list[0].filename, filename);
timeline_frames = 1;
} else {
- /* calculate image file name */
+ /* create list of files that have same base name, same number of digits and suffix */
+ int suffix_offset = strlen(filename) - strlen(suffix);
+ int digits_offset = p - filename;
int digits = filename + strlen(filename) - strlen(suffix) - p;
- int start, count = 0;
- strncpy(temp, p, digits);
- temp[digits] = '\0';
- start = atoi(temp);
-// printf("count digits=%s num=%d start=%d\n", temp, digits, start);
- strncpy(temp, filename, p - filename);
- temp[p - filename] = '\0';
-// printf("prefix=%s\n", temp);
- sprintf(strchr(temp, '\0'), "%%0%dd%s", digits, suffix);
-// printf("complete=%s\n", temp);
- /* look back for index */
- while (start > 0) {
- sprintf(name, temp, start - 1);
- fp = fopen(name, "r");
- if (!fp)
- break;
- fclose(fp);
- start--;
+ const char *path = get_path(filename);
+ dir_t *dir_head = fetch_dir(path), *dir, **dirp;
+ int count;
+ if (!dir_head)
+ goto single_file;
+ dir = dir_head;
+ dirp = &dir_head;
+ while (dir) {
+ /* remove files that do not have equal prefix */
+ if (!!strncmp(filename, dir->name, p - filename)) {
+free_file:
+ /* remove entry */
+ *dirp = dir->next;
+ free(dir);
+ dir = *dirp;
+ continue;
+ }
+ /* remove files that have no digits where expected */
+ for (i = 0; i < digits; i++) {
+ if (dir->name[digits_offset+i] < '0' || dir->name[digits_offset+i] > '9')
+ break;
+ }
+ if (i < digits) {
+ goto free_file;
+ }
+ /* remove files that have different suffix */
+ if (!!strcmp(suffix, dir->name + suffix_offset)) {
+ goto free_file;
+ }
+ dirp = &(dir->next);
+ dir = dir->next;
}
- /* count forward index */
- for (i = start; ; i++) {
- sprintf(name, temp, start + count);
- fp = fopen(name, "r");
- if (!fp)
- break;
- fclose(fp);
+ count = 0;
+ dir = dir_head;
+ while (dir) {
count++;
+ dir = dir->next;
}
- if (count == 0)
+ if (count < 2) {
+ free_dir(dir_head);
goto single_file;
+ }
frame_list = malloc(sizeof(struct frame_list) * count);
memset(frame_list, 0, sizeof(struct frame_list) * count);
+ dir = dir_head;
for (i = 0; i < count; i++) {
- sprintf(frame_list[i].filename, temp, start + i);
+ strcpy(frame_list[i].filename, dir->name);
+ dir = dir->next;
}
timeline_frames = count;
+ free_dir(dir_head);
}
/* get marked frames */
for (i = 0; i < timeline_frames; i++) {
}
/* get filename of first grey image directory */
-static char *get_filename(const char *filename)
+static char *get_sequence_name(const char *filename)
{
static char name[256];
/* copy name */
- strcpy(name, filename);
- /* remove until DIR_SEPERATOR */
- while (name[0]) {
- if (name[strlen(name) - 1] == DIR_SEPERATOR)
- break;
- name[strlen(name) - 1] = '\0';
- }
+ strcpy(name, get_path(filename));
/* add palette name */
strcat(name, "sequence");
if (timeline_frames <= 1)
return 0;
- name = get_filename(frame_list[0].filename);
+ name = get_sequence_name(frame_list[0].filename);
// printf("save sequence '%s'\n", name);
fp = fopen(name, "w");
if (!fp) {
if (timeline_frames <= 1)
return 0;
- name = get_filename(frame_list[0].filename);
+ name = get_sequence_name(frame_list[0].filename);
// printf("load sequence '%s'\n", name);
fp = fopen(name, "r");
if (!fp) {
- printf("failed to load sequence '%s'\n", name);
+ printf("no sequence file '%s' created yet\n", name);
return -1;
}
for (i = 0; i < timeline_frames; i++) {