From da98a2d2405955d8a9eeef6074b18c6e016f8fd9 Mon Sep 17 00:00:00 2001 From: Scoopta Date: Sat, 11 Jul 2020 17:39:09 -0700 Subject: [PATCH] Added base64 image support --- inc/utils_g.h | 29 ++++++++++++++++++++ meson.build | 2 ++ modes/drun.c | 17 ++---------- src/utils_g.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/wofi.c | 44 +++++++++++++++++++---------- 5 files changed, 138 insertions(+), 30 deletions(-) create mode 100644 inc/utils_g.h create mode 100644 src/utils_g.c diff --git a/inc/utils_g.h b/inc/utils_g.h new file mode 100644 index 0000000..ddfbd74 --- /dev/null +++ b/inc/utils_g.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 Scoopta + * This file is part of Wofi + * Wofi is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Wofi is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Wofi. If not, see . + */ + +#ifndef UTILS_G_H +#define UTILS_G_H + +#include + +#include + +GdkPixbuf* utils_g_resize_pixbuf(GdkPixbuf* pixbuf, uint64_t image_size, GdkInterpType interp); + +GdkPixbuf* utils_g_pixbuf_from_base64(char* base64); + +#endif diff --git a/meson.build b/meson.build index 7b336c0..69eb8b6 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,7 @@ sources = ['src/config.c', 'src/main.c', 'src/map.c', 'src/property_box.c', + 'src/utils_g.c', 'src/utils.c', 'src/widget_builder.c', 'src/wofi.c', @@ -60,6 +61,7 @@ subdir = 'wofi-1' install_headers('inc/config.h', 'inc/map.h', + 'inc/utils_g.h', 'inc/utils.h', 'inc/widget_builder_api.h', 'inc/wofi_api.h', diff --git a/modes/drun.c b/modes/drun.c index 13e848d..e541296 100644 --- a/modes/drun.c +++ b/modes/drun.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -118,21 +119,7 @@ static bool populate_widget(char* file, char* action, struct widget_builder* bui pixbuf = gtk_icon_info_load_icon(info, NULL); } - int width = gdk_pixbuf_get_width(pixbuf); - int height = gdk_pixbuf_get_height(pixbuf); - uint64_t image_size = wofi_get_image_size(); - - if(height > width) { - float percent = (float) image_size / height; - GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, width * percent, image_size, GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - pixbuf = tmp; - } else { - float percent = (float) image_size / width; - GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, image_size, height * percent, GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - pixbuf = tmp; - } + pixbuf = utils_g_resize_pixbuf(pixbuf, wofi_get_image_size(), GDK_INTERP_BILINEAR); wofi_widget_builder_insert_image(builder, pixbuf, "icon"); g_object_unref(pixbuf); diff --git a/src/utils_g.c b/src/utils_g.c new file mode 100644 index 0000000..4371bdb --- /dev/null +++ b/src/utils_g.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 Scoopta + * This file is part of Wofi + * Wofi is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Wofi is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Wofi. If not, see . + */ + +#include + +#include + +GdkPixbuf* utils_g_resize_pixbuf(GdkPixbuf* pixbuf, uint64_t image_size, GdkInterpType interp) { + int width = gdk_pixbuf_get_width(pixbuf); + int height = gdk_pixbuf_get_height(pixbuf); + + if(height > width) { + float percent = (float) image_size / height; + GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, width * percent, image_size, interp); + g_object_unref(pixbuf); + return tmp; + } else { + float percent = (float) image_size / width; + GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, image_size, height * percent, interp); + g_object_unref(pixbuf); + return tmp; + } +} + +GdkPixbuf* utils_g_pixbuf_from_base64(char* base64) { + char* str = strdup(base64); + char* original_str = str; + + GError* err = NULL; + GdkPixbufLoader* loader; + if(strncmp(str, "image/", sizeof("image/") - 1) == 0) { + char* mime = strchr(str, ';'); + *mime = 0; + loader = gdk_pixbuf_loader_new_with_mime_type(str, &err); + if(err != NULL) { + goto fail; + } + str = mime + 1; + str = strchr(str, ',') + 1; + } else { + loader = gdk_pixbuf_loader_new(); + } + + gsize data_l; + guchar* data = g_base64_decode(str, &data_l); + + gdk_pixbuf_loader_write(loader, data, data_l, &err); + if(err != NULL) { + g_free(data); + goto fail; + } + + g_free(data); + + free(original_str); + return gdk_pixbuf_loader_get_pixbuf(loader); + + fail: + free(str); + fprintf(stderr, "Error loading base64 %s\n", err->message); + return NULL; +} diff --git a/src/wofi.c b/src/wofi.c index b41d79f..1c510b6 100644 --- a/src/wofi.c +++ b/src/wofi.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -216,6 +217,8 @@ static char* parse_images(WofiPropertyBox* box, const char* text, bool create_wi struct map* mode_map = map_init(); map_put(mode_map, "img", "true"); map_put(mode_map, "img-noscale", "true"); + map_put(mode_map, "img-base64", "true"); + map_put(mode_map, "img-base64-noscale", "true"); map_put(mode_map, "text", "true"); char* tmp = strdup(text); @@ -286,19 +289,9 @@ static char* parse_images(WofiPropertyBox* box, const char* text, bool create_wi fprintf(stderr, "Image %s cannot be loaded\n", str); goto done; } - int width = gdk_pixbuf_get_width(buf); - int height = gdk_pixbuf_get_height(buf); - if(height > width) { - float percent = (float) image_size / height; - GdkPixbuf* tmp = gdk_pixbuf_scale_simple(buf, width * percent, image_size, GDK_INTERP_BILINEAR); - g_object_unref(buf); - buf = tmp; - } else { - float percent = (float) image_size / width; - GdkPixbuf* tmp = gdk_pixbuf_scale_simple(buf, image_size, height * percent, GDK_INTERP_BILINEAR); - g_object_unref(buf); - buf = tmp; - } + + buf = utils_g_resize_pixbuf(buf, image_size, GDK_INTERP_BILINEAR); + GtkWidget* img = gtk_image_new_from_pixbuf(buf); gtk_widget_set_name(img, "img"); gtk_container_add(GTK_CONTAINER(box), img); @@ -311,6 +304,27 @@ static char* parse_images(WofiPropertyBox* box, const char* text, bool create_wi GtkWidget* img = gtk_image_new_from_pixbuf(buf); gtk_widget_set_name(img, "img"); gtk_container_add(GTK_CONTAINER(box), img); + } else if(strcmp(mode, "img-base64") == 0 && create_widgets) { + GdkPixbuf* buf = utils_g_pixbuf_from_base64(str); + if(buf == NULL) { + fprintf(stderr, "base64 image cannot be loaded\n"); + goto done; + } + + buf = utils_g_resize_pixbuf(buf, image_size, GDK_INTERP_BILINEAR); + + GtkWidget* img = gtk_image_new_from_pixbuf(buf); + gtk_widget_set_name(img, "img"); + gtk_container_add(GTK_CONTAINER(box), img); + } else if(strcmp(mode, "img-base64-noscale") == 0 && create_widgets) { + GdkPixbuf* buf = utils_g_pixbuf_from_base64(str); + if(buf == NULL) { + fprintf(stderr, "base64 image cannot be loaded\n"); + goto done; + } + GtkWidget* img = gtk_image_new_from_pixbuf(buf); + gtk_widget_set_name(img, "img"); + gtk_container_add(GTK_CONTAINER(box), img); } else if(strcmp(mode, "text") == 0) { if(create_widgets) { GtkWidget* label = gtk_label_new(str); @@ -855,8 +869,8 @@ void wofi_term_run(const char* cmd) { static void flag_box(GtkBox* box, GtkStateFlags flags) { GList* selected_children = gtk_container_get_children(GTK_CONTAINER(box)); - GList* list = selected_children; - for(GtkWidget* child = list->data; list != NULL; list = list->next) { + for(GList* list = selected_children; list != NULL; list = list->next) { + GtkWidget* child = list->data; gtk_widget_set_state_flags(child, flags, TRUE); } g_list_free(selected_children);