aboutsummaryrefslogtreecommitdiff
path: root/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'image.c')
-rw-r--r--image.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/image.c b/image.c
new file mode 100644
index 0000000..034dd62
--- /dev/null
+++ b/image.c
@@ -0,0 +1,111 @@
+#include "image.h"
+#include <gtk-3.0/gtk/gtk.h>
+
+GtkWidget* new_image()
+{
+ image = gtk_image_new();
+ return image;
+}
+
+int load_image(char *file_name, int win_width, int win_height)
+{
+ printf("loading: %s\n", file_name);
+ GError *error = NULL;
+ if (pixbuf != NULL)
+ g_object_unref(pixbuf);
+ pixbuf = gdk_pixbuf_new_from_file(file_name, &error);
+ if (error)
+ return -1;
+ pixbuf_width = gdk_pixbuf_get_width(GDK_PIXBUF(pixbuf));
+ pixbuf_height = gdk_pixbuf_get_height(GDK_PIXBUF(pixbuf));
+ aspect_ratio = (double)pixbuf_width / (double)pixbuf_height;
+ curr_zoom = 1.0;
+ fit_image(win_width, win_height);
+ return 1;
+}
+
+void update_pixbuf()
+{
+ if (curr_pixbuf != NULL)
+ g_object_unref(curr_pixbuf);
+ if (pixbuf == NULL)
+ return;
+ curr_pixbuf = gdk_pixbuf_scale_simple(GDK_PIXBUF(pixbuf), pixbuf_width,
+ pixbuf_height, GDK_INTERP_BILINEAR);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(image), GDK_PIXBUF(curr_pixbuf));
+}
+
+void fit_image(int win_width, int win_height)
+{
+ if (pixbuf == NULL || win_width < 1 || win_height < 1)
+ return;
+ if (win_width < pixbuf_width && win_height > pixbuf_height) {
+ pixbuf_width = win_width;
+ pixbuf_height = (double)pixbuf_width / aspect_ratio;
+ } else if (win_width > pixbuf_width && win_height < pixbuf_height) {
+ pixbuf_height = win_height;
+ pixbuf_width = (double)pixbuf_height * aspect_ratio;
+ } else if (win_width < pixbuf_width && win_height < pixbuf_height) {
+ if (((double)win_width / (double)win_height) > aspect_ratio) {
+ pixbuf_height = win_height;
+ pixbuf_width = ((double)pixbuf_height * aspect_ratio);
+ } else {
+ pixbuf_width = win_width;
+ pixbuf_height = (double)pixbuf_width / aspect_ratio;
+ }
+ } else {
+ pixbuf_width = pixbuf_width;
+ pixbuf_height = pixbuf_height;
+ }
+
+ curr_zoom = (double)pixbuf_width / (double)pixbuf_width;
+ if (pixbuf_width < 1 || pixbuf_height < 1)
+ return;
+
+ update_pixbuf();
+}
+
+void zoom(int type)
+{
+ if (pixbuf == NULL)
+ return;
+ if (type == 0) {
+ if (curr_zoom == 1.0)
+ return;
+ curr_zoom = (double)1.0;
+ } else if (type < 0) {
+ if (curr_zoom < 0.2)
+ return;
+ curr_zoom -= (double)ZOOM_FACTOR;
+ } else if (type > 0) {
+ if (curr_zoom > 2)
+ return;
+ curr_zoom += (double)ZOOM_FACTOR;
+ }
+ pixbuf_width *= curr_zoom;
+ pixbuf_height += curr_zoom;
+
+ update_pixbuf();
+}
+
+void print_supported_formats()
+{
+ GSList *list, *it;
+ GdkPixbufFormat *format;
+ gchar **extensions;
+ gchar *ex;
+
+ list = gdk_pixbuf_get_formats();
+ if (list != NULL) {
+ for (it = list; it->next != NULL; it = it->next) {
+ format = (GdkPixbufFormat *)it->data;
+ printf("%s:", gdk_pixbuf_format_get_description(format));
+ extensions = gdk_pixbuf_format_get_extensions(format);
+ for (ex = *extensions; *ex; ex++) {
+ printf(" %s", ex);
+ }
+ printf("\n");
+ }
+ g_slist_free(list);
+ }
+}