aboutsummaryrefslogtreecommitdiff
path: root/src/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file.c')
-rw-r--r--src/file.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..dcbcbf0
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,131 @@
+#define _DEFAULT_SOURCE
+#include "file.h"
+#include "image.h"
+#include <dirent.h>
+#include <gtk-3.0/gtk/gtk.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+static char **extensions = NULL;
+
+char *get_filename_ext(const char *file_name)
+{
+ char *dot = strrchr(file_name, '.');
+ if (!dot || dot == file_name)
+ return "";
+ return dot + 1;
+}
+
+int is_file_format_supported(const char *file_name)
+{
+ char *file_ext = get_filename_ext(file_name);
+ char **it = extensions;
+ while (*it != NULL) {
+ if (!strcmp(*it++, file_ext)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void scan_supported_formats()
+{
+ GSList *list, *it;
+ GdkPixbufFormat *format;
+ gchar **exts, **ex_it;
+ int i = 0;
+
+ list = gdk_pixbuf_get_formats();
+ if (list != NULL) {
+ for (it = list; it->next != NULL; it = it->next) {
+ format = (GdkPixbufFormat *)it->data;
+ exts = gdk_pixbuf_format_get_extensions(format);
+ if (exts != NULL) {
+ ex_it = exts;
+ while (*ex_it != NULL) {
+ extensions = realloc(extensions, sizeof(char *) * (i + 1));
+ extensions[i++] = strdup(*ex_it);
+ g_free(*ex_it);
+ ex_it++;
+ }
+ g_free(exts);
+ }
+ }
+ g_slist_free(list);
+ extensions[i] = NULL;
+ }
+}
+
+int image_filter(const struct dirent *dir)
+{
+ if (dir->d_type == DT_REG && is_file_format_supported(dir->d_name)) {
+ return 1;
+ }
+ return 0;
+}
+
+int scan(const char *file_name)
+{
+ scan_supported_formats();
+ struct dirent **name_list;
+ char *dir_name = dirname(strdup(file_name));
+ file_list_count = scandir(dir_name, &name_list, image_filter, alphasort);
+ if (file_list_count < 0) {
+ return -1;
+ }
+
+ file_list = malloc(file_list_count * sizeof(char *));
+ char *file_basename = basename(strdup(file_name));
+ int i = 0;
+ while (i < file_list_count) {
+ if (!strcmp(file_basename, name_list[i]->d_name))
+ curr_file_index = i;
+ file_list[i] = g_build_filename(dir_name, name_list[i]->d_name, NULL);
+ free(name_list[i]);
+ i++;
+ }
+ free(name_list);
+
+ return 0;
+}
+
+char *get_next_file()
+{
+ if (curr_file_index >= file_list_count - 1)
+ return NULL;
+ return file_list[++curr_file_index];
+}
+
+char *get_prev_file()
+{
+ if (curr_file_index <= 0)
+ return NULL;
+ return file_list[--curr_file_index];
+}
+
+char *get_first_file()
+{
+ if (curr_file_index == 0)
+ return NULL;
+ curr_file_index = 0;
+ return file_list[curr_file_index];
+}
+
+char *get_last_file()
+{
+ if (curr_file_index == file_list_count - 1)
+ return NULL;
+ curr_file_index = file_list_count - 1;
+ return file_list[curr_file_index];
+}
+
+void clean()
+{
+ for (int i = 0; i < file_list_count; ++i) {
+ g_free(file_list[i]);
+ }
+ g_free(file_list);
+}