From 1645da679ce50b13b6f19a062eabd2d869762a07 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Wed, 15 Feb 2023 15:07:56 +0100 Subject: add framebuffer image support --- core/Makefile | 2 +- core/for.c | 2 +- core/imgv.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ core/read.c | 16 +++--- 4 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 core/imgv.c (limited to 'core') diff --git a/core/Makefile b/core/Makefile index 99e348d..4232da9 100644 --- a/core/Makefile +++ b/core/Makefile @@ -7,7 +7,7 @@ options: @echo SRC: ${SRC} @echo OBJ: ${OBJ} -objects/%: %.c +objects/%: %.c ../lib/slib.a @echo Building $< @-mkdir -p $$(dirname $@) @gcc $< -o $@ ../lib/slib.a -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -Wno-int-conversion -g diff --git a/core/for.c b/core/for.c index d576bf8..d3d2fd4 100644 --- a/core/for.c +++ b/core/for.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) return -1; } - wait4(pid, 0, 0); + wait4(pid, 0, 0, 0); } return 0; 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; +} diff --git a/core/read.c b/core/read.c index 017fd3c..d91b414 100644 --- a/core/read.c +++ b/core/read.c @@ -2,8 +2,8 @@ #include "../lib/arg/arg.h" #include "../lib/list/list.h" #include "../lib/sys/errno.h" - -#define BUF_SIZE 1024 +#include "../lib/sys/types.h" +#include "../lib/tctl/tctl.h" void mode_all(int fd); void mode_singleline(int fd); @@ -12,9 +12,9 @@ enum Modes { MODE_ALL, MODE_SINGLELINE, MODE_SIZE -} mode; +} mode = MODE_ALL; -char buf[BUF_SIZE] = ""; +char buf[BUFSIZ] = ""; list_t *files; void(*mode_funcs[MODE_SIZE])(int fd) = { mode_all, @@ -42,10 +42,10 @@ void set_singleline_mode() void mode_all(int fd) { u64 rs; - while ((rs = read(fd, buf, BUF_SIZE - 1))) { - buf[rs] = 0; - wstd(buf); + while ((rs = read(fd, buf, BUFSIZ))) { + write(STDOUT_FD, buf, rs); } + flush(STDOUT_FD); } @@ -55,7 +55,7 @@ void mode_singleline(int fd) u64 has_newline_char = 0; char *p; while (!has_newline_char) { - rs = read(fd, buf, BUF_SIZE - 1); + rs = read(fd, buf, BUFSIZ - 1); for (p = buf; p < buf + rs; ++p) { if (*p == '\n') { has_newline_char = 1; -- cgit v1.2.3-70-g09d2