aboutsummaryrefslogtreecommitdiff
path: root/view.c
diff options
context:
space:
mode:
authorJavier S. Pedro <javier@javispedro.com>2012-11-14 18:04:03 +0100
committerJavier S. Pedro <javier@javispedro.com>2012-11-14 18:04:03 +0100
commit2f2654c57f3ff0d963f8ba21d2c944a458204394 (patch)
treebf6818f0b4018050b0c60d1d34e609cafc49d88c /view.c
downloadvteimg-2f2654c57f3ff0d963f8ba21d2c944a458204394.tar.gz
vteimg-2f2654c57f3ff0d963f8ba21d2c944a458204394.zip
initial import
Diffstat (limited to 'view.c')
-rw-r--r--view.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/view.c b/view.c
new file mode 100644
index 0000000..af237c9
--- /dev/null
+++ b/view.c
@@ -0,0 +1,112 @@
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <gio/gunixinputstream.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+// TODO Unhardcode these
+const int char_width = 8;
+const int char_height = 15;
+
+const int window_width = 8 * 80;
+const int window_height = 15 * 25;
+
+static gboolean view_pixbuf(GdkPixbuf *pixbuf)
+{
+ gint width = gdk_pixbuf_get_width(pixbuf);
+ gint height = gdk_pixbuf_get_height(pixbuf);
+
+ double scale = 1.0;
+ if (width > window_width) {
+ scale *= (double)window_width / width;
+ width = width * scale;
+ height = height * scale;
+ }
+ if (height > window_height || FALSE) {
+ scale *= (double)window_height / height;
+ width = width * scale;
+ height = height * scale;
+ }
+
+ GdkPixbuf *scaled;
+
+ if (scale != 1.0) {
+ scaled = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR);
+ } else {
+ scaled = GDK_PIXBUF(g_object_ref(pixbuf));
+ }
+
+ GdkPixdata pixdata;
+ gpointer pixdata_p = gdk_pixdata_from_pixbuf(&pixdata, scaled, TRUE);
+
+ if (pixdata_p == NULL) {
+ g_object_unref(scaled);
+ return FALSE;
+ }
+
+ guint size;
+ guint8 *data = gdk_pixdata_serialize(&pixdata, &size);
+ gchar *str = g_base64_encode(data, size);
+
+ g_print("\033]v;%s\007", str);
+
+ int rows = ceil(height / (double)char_height);
+ while (rows > 0) {
+ g_print("\n");
+ rows--;
+ }
+
+ g_free(str);
+ g_free(data);
+ g_free(pixdata.pixel_data);
+ g_object_unref(scaled);
+
+ return TRUE;
+}
+
+
+int main(int argc, char * argv[])
+{
+ g_type_init();
+
+ GError *error = NULL;
+
+ if (!isatty(STDOUT_FILENO)) {
+ g_printerr("Refusing to display image on not-terminal\n");
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 1) {
+ int i;
+ for (i = 1; i < argc; i++) {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(argv[i], &error);
+ if (pixbuf == NULL) {
+ g_printerr("Failed to open image '%s': %s\n", argv[i], error->message);
+ return EXIT_FAILURE;
+ }
+ if (!view_pixbuf(pixbuf)) {
+ g_printerr("Failed to view image '%s'\n", argv[i]);
+ return EXIT_FAILURE;
+ }
+ g_object_unref(pixbuf);
+ }
+ } else {
+ GInputStream *input = g_unix_input_stream_new(STDIN_FILENO, FALSE);
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_stream(input, NULL, &error);
+ if (pixbuf == NULL) {
+ g_printerr("Failed to open stdin image: %s\n", error->message);
+ return EXIT_FAILURE;
+ }
+ if (!view_pixbuf(pixbuf)) {
+ g_printerr("Failed to view stdin image\n");
+ return EXIT_FAILURE;
+ }
+ g_object_unref(pixbuf);
+ }
+
+ return EXIT_SUCCESS;
+}