aboutsummaryrefslogtreecommitdiff
path: root/core/imgv.c
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-02-15 15:07:56 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-02-15 15:07:56 +0100
commit1645da679ce50b13b6f19a062eabd2d869762a07 (patch)
tree37e19f84000df69bb2a7d88a2f3db800ead6a85a /core/imgv.c
parent3a369468f7daae5b3a60feaa50c6050b240be6d4 (diff)
add framebuffer image support
Diffstat (limited to 'core/imgv.c')
-rw-r--r--core/imgv.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/core/imgv.c b/core/imgv.c
new file mode 100644
index 0000000..c9f9efb
--- /dev/null
+++ b/core/imgv.c
@@ -0,0 +1,164 @@
+#include "../lib/io/io.h"
+#include "../lib/fb/fb.h"
+#include "../lib/tctl/tctl.h"
+#include "../lib/aec/aec.h"
+#include "../lib/ff/ff.h"
+#include "../lib/arg/arg.h"
+#include "../lib/cstr/cstr.h"
+
+u8 centerx = 0;
+u8 centery = 0;
+i64 width = -1;
+i64 height = -1;
+u8 fill = 0;
+u8 only_print = 0;
+
+
+void set_only_print()
+{
+ only_print = 1;
+}
+
+
+void set_width(const char *buf)
+{
+ width = cstr_to_i64(buf);
+}
+
+
+void set_height(const char *buf)
+{
+ height = cstr_to_i64(buf);
+}
+
+
+void set_fill()
+{
+ fill = 1;
+}
+
+
+void set_centerx()
+{
+ centerx = 1;
+}
+
+
+void set_centery()
+{
+ centery = 1;
+}
+
+
+void draw_image(canvas_t canvas, image_t *img)
+{
+ canvas_pixel_t p;
+ u64 offset_x = 0;
+ u64 offset_y = 0;
+ float scalex = 1;
+ float scaley = 1;
+
+ if (width != -1) {
+ scalex = width;
+ scalex /= img->width;
+ }
+
+ if (height != -1) {
+ scaley = height;
+ scaley /= img->height;
+ }
+
+ if (centerx) {
+ offset_x = (canvas.width - img->width) / 2;
+ }
+
+ if (centery) {
+ offset_y = (canvas.height - img->height) / 2;
+ }
+
+ for (u32 y = 0; y < img->height; ++y) {
+ for (u32 x = 0; x < img->width; ++x) {
+ p = image_pixel_to_canvas_pixel(img->data[x + y * img->width]);
+ put_pixel(canvas, (x * scalex) + offset_x, (y * scaley) + offset_y, p);
+ }
+ }
+}
+
+
+void black_clear(canvas_t canvas)
+{
+ canvas_pixel_t p = { 0x00, 0x00, 0x00 };
+ for (int x = 0; x < canvas.width; ++x) {
+ for (int y = 0; y < canvas.height; ++y) {
+ put_pixel(canvas, x, y, p);
+ }
+ }
+}
+
+
+int main(int argc, const char **argv)
+{
+ arg_register_flag("-p", &set_only_print);
+ arg_register_flag("-c", &set_centerx);
+ arg_register_flag("-z", &set_centery);
+ arg_register_arg("-h", &set_height);
+ arg_register_arg("-w", &set_width);
+ arg_parse_arg(argc, argv);
+
+ canvas_t canvas = open_framebuffer();
+ termios_t term;
+ termios_t orig;
+
+ image_t *img = new_image_from_fd(STDIN_FD);
+
+ tcgetattr(STDOUT_FD, &term);
+ orig = term;
+ setcanonical(&term, 0);
+ setecho(&term, 0);
+ cursor_enabled(0);
+ tcsetattr(STDOUT_FD, &term);
+
+ if (!img) {
+ free_image(img);
+ close_framebuffer(canvas);
+ cursor_enabled(1);
+ tcsetattr(STDOUT_FD, &orig);
+ wf(STDERR_FD, "error: cannot read image\n");
+ return -1;
+ }
+
+ if (width == -1) {
+ width = img->width;
+ }
+
+ if (height == -1) {
+ height = img->width;
+ }
+
+ char key = 0;
+
+ while (key != 'q') {
+ draw_image(canvas, img);
+ if (!only_print)
+ read(STDERR_FD, &key, 1);
+ else
+ break;
+ }
+
+ if (!only_print)
+ black_clear(canvas);
+
+ free_image(img);
+ close_framebuffer(canvas);
+ cursor_enabled(1);
+ tcsetattr(STDOUT_FD, &orig);
+
+ if (!only_print) {
+ move_cursor(1, 1);
+ clear_screen();
+ } else {
+ move_cursor(0, height / 14);
+ }
+
+ return 0;
+}