1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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;
}
|