diff --git a/Makefile b/Makefile index b7d9f80..2d4cde2 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,7 @@ PREFIX ?= /usr/local BINDIR = $(PREFIX)/bin MANDIR = $(PREFIX)/share/man/man1 -LDFLAGS != pkg-config --libs libsixel -INCFLAGS != pkg-config --cflags libsixel -CFLAGS = -Os -march=native -mtune=native -pipe -s -flto -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 $(INCFLAGS) +CFLAGS = -Os -march=native -mtune=native -pipe -s -flto -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 SRC = ccc.c util.c file.c icons.c diff --git a/ccc.c b/ccc.c index 225b120..feb9791 100644 --- a/ccc.c +++ b/ccc.c @@ -13,8 +13,6 @@ #include #include -#include - #include "config.h" #include "file.h" #include "icons.h" @@ -872,14 +870,12 @@ void show_file_content(void) return; } - if (strstr(current_file.name, ".jpg") == NULL && strstr(current_file.name, ".png") == NULL) { - int c; - /* Check if its binary */ - while ((c = fgetc(file)) != EOF) { - if (c == '\0') { - bprintf("binary"); - return; - } + int c; + /* Check if its binary */ + while ((c = fgetc(file)) != EOF) { + if (c == '\0') { + bprintf("binary"); + return; } } int pipe_fd[2]; @@ -891,83 +887,70 @@ void show_file_content(void) if (pid == 0) { /* Child */ move_cursor(1, half_width); - if (strstr(current_file.name, ".jpg") || strstr(current_file.name, ".png")) { - sixel_encoder_t *encoder = NULL; - sixel_encoder_new(&encoder, NULL); - /* Should be enough for most terminal */ - char width[5]; - snprintf(width, 5, "%d", (cols - half_width) * 6); - sixel_encoder_setopt(encoder, 'w', width); - sixel_encoder_encode(encoder, current_file.name); - sixel_encoder_unref(encoder); - } else { - close(pipe_fd[0]); - dup2(pipe_fd[1], STDOUT_FILENO); - dup2(pipe_fd[1], STDERR_FILENO); - close(pipe_fd[1]); - execlp("vip", "vip", "-c", current_file.name, NULL); - } + close(pipe_fd[0]); + dup2(pipe_fd[1], STDOUT_FILENO); + dup2(pipe_fd[1], STDERR_FILENO); + close(pipe_fd[1]); + execlp("vip", "vip", "-c", current_file.name, NULL); _exit(1); } else if (pid > 0) { /* Parent */ - if (!strstr(current_file.name, ".jpg") && !strstr(current_file.name, ".png")) { - close(pipe_fd[1]); - char buffer[4096]; - int row = 1; - FILE *stream = fdopen(pipe_fd[0], "r"); - while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { - buffer[strcspn(buffer, "\n")] = 0; + close(pipe_fd[1]); + char buffer[4096]; + int row = 1; + FILE *stream = fdopen(pipe_fd[0], "r"); + while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { + buffer[strcspn(buffer, "\n")] = 0; - if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { - move_cursor(row++, half_width); - putchar('\n'); - continue; - } - /* Length without ANSI codes */ - size_t effective_len = get_effective_length(buffer); - size_t offset = 0; - while (effective_len > 0 && row <= rows - 1) { - move_cursor(row++, half_width); - - /* Calculate the chunk size based on effective length */ - size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len; - - /* Find the actual end position in the string to avoid cutting ANSI sequences */ - size_t actual_end = offset; - size_t visible_count = 0; - bool in_ansi_sequence = false; - - while (visible_count < chunk_size && buffer[actual_end] != '\0') { - if (buffer[actual_end] == '\033') { - in_ansi_sequence = true; - } - if (!in_ansi_sequence) { - visible_count++; - } - if (in_ansi_sequence && buffer[actual_end] == 'm') { - in_ansi_sequence = false; - } - actual_end++; - } - - /* Print the chunk from `offset` to `actual_end` */ - print_chunk(buffer, offset, actual_end); - - /* Update offsets based on the effective length and ANSI-aware chunk */ - offset = actual_end; - effective_len -= chunk_size; - - putchar('\n'); - } - /* Check if the line ends with the ANSI reset sequence `\033[0m` */ - size_t len = strlen(buffer); - if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) { - /* Line ends with ANSI reset, print it */ - printf("\033[0m"); - } + if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { + move_cursor(row++, half_width); + putchar('\n'); + continue; + } + /* Length without ANSI codes */ + size_t effective_len = get_effective_length(buffer); + size_t offset = 0; + while (effective_len > 0 && row <= rows - 1) { + move_cursor(row++, half_width); + + /* Calculate the chunk size based on effective length */ + size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len; + + /* Find the actual end position in the string to avoid cutting ANSI sequences */ + size_t actual_end = offset; + size_t visible_count = 0; + bool in_ansi_sequence = false; + + while (visible_count < chunk_size && buffer[actual_end] != '\0') { + if (buffer[actual_end] == '\033') { + in_ansi_sequence = true; + } + if (!in_ansi_sequence) { + visible_count++; + } + if (in_ansi_sequence && buffer[actual_end] == 'm') { + in_ansi_sequence = false; + } + actual_end++; + } + + /* Print the chunk from `offset` to `actual_end` */ + print_chunk(buffer, offset, actual_end); + + /* Update offsets based on the effective length and ANSI-aware chunk */ + offset = actual_end; + effective_len -= chunk_size; + + putchar('\n'); + } + /* Check if the line ends with the ANSI reset sequence `\033[0m` */ + size_t len = strlen(buffer); + if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) { + /* Line ends with ANSI reset, print it */ + printf("\033[0m"); } - fclose(stream); } + fclose(stream); waitpid(pid, NULL, 0); } else { wpprintw("fork failed: %s", strerror(errno)); diff --git a/patches/image-preview.patch b/patches/image-preview.patch new file mode 100644 index 0000000..6fc653d --- /dev/null +++ b/patches/image-preview.patch @@ -0,0 +1,197 @@ +From a50fcb841a399f45b6fae92aecec4bf1cb3f6e66 Mon Sep 17 00:00:00 2001 +From: night0721 +Date: Wed, 13 Nov 2024 09:44:54 +0000 +Subject: [PATCH] Image support with libsixel + +--- + Makefile | 4 +- + ccc.c | 137 +++++++++++++++++++++++++++++++------------------------ + 2 files changed, 80 insertions(+), 61 deletions(-) + +diff --git a/Makefile b/Makefile +index 2d4cde2..b7d9f80 100644 +--- a/Makefile ++++ b/Makefile +@@ -8,7 +8,9 @@ PREFIX ?= /usr/local + BINDIR = $(PREFIX)/bin + MANDIR = $(PREFIX)/share/man/man1 + +-CFLAGS = -Os -march=native -mtune=native -pipe -s -flto -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 ++LDFLAGS != pkg-config --libs libsixel ++INCFLAGS != pkg-config --cflags libsixel ++CFLAGS = -Os -march=native -mtune=native -pipe -s -flto -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 $(INCFLAGS) + + SRC = ccc.c util.c file.c icons.c + +diff --git a/ccc.c b/ccc.c +index feb9791..225b120 100644 +--- a/ccc.c ++++ b/ccc.c +@@ -13,6 +13,8 @@ + #include + #include + ++#include ++ + #include "config.h" + #include "file.h" + #include "icons.h" +@@ -870,12 +872,14 @@ void show_file_content(void) + return; + } + +- int c; +- /* Check if its binary */ +- while ((c = fgetc(file)) != EOF) { +- if (c == '\0') { +- bprintf("binary"); +- return; ++ if (strstr(current_file.name, ".jpg") == NULL && strstr(current_file.name, ".png") == NULL) { ++ int c; ++ /* Check if its binary */ ++ while ((c = fgetc(file)) != EOF) { ++ if (c == '\0') { ++ bprintf("binary"); ++ return; ++ } + } + } + int pipe_fd[2]; +@@ -887,70 +891,83 @@ void show_file_content(void) + if (pid == 0) { + /* Child */ + move_cursor(1, half_width); +- close(pipe_fd[0]); +- dup2(pipe_fd[1], STDOUT_FILENO); +- dup2(pipe_fd[1], STDERR_FILENO); +- close(pipe_fd[1]); +- execlp("vip", "vip", "-c", current_file.name, NULL); ++ if (strstr(current_file.name, ".jpg") || strstr(current_file.name, ".png")) { ++ sixel_encoder_t *encoder = NULL; ++ sixel_encoder_new(&encoder, NULL); ++ /* Should be enough for most terminal */ ++ char width[5]; ++ snprintf(width, 5, "%d", (cols - half_width) * 6); ++ sixel_encoder_setopt(encoder, 'w', width); ++ sixel_encoder_encode(encoder, current_file.name); ++ sixel_encoder_unref(encoder); ++ } else { ++ close(pipe_fd[0]); ++ dup2(pipe_fd[1], STDOUT_FILENO); ++ dup2(pipe_fd[1], STDERR_FILENO); ++ close(pipe_fd[1]); ++ execlp("vip", "vip", "-c", current_file.name, NULL); ++ } + _exit(1); + } else if (pid > 0) { + /* Parent */ +- close(pipe_fd[1]); +- char buffer[4096]; +- int row = 1; +- FILE *stream = fdopen(pipe_fd[0], "r"); +- while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { +- buffer[strcspn(buffer, "\n")] = 0; ++ if (!strstr(current_file.name, ".jpg") && !strstr(current_file.name, ".png")) { ++ close(pipe_fd[1]); ++ char buffer[4096]; ++ int row = 1; ++ FILE *stream = fdopen(pipe_fd[0], "r"); ++ while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { ++ buffer[strcspn(buffer, "\n")] = 0; + +- if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { +- move_cursor(row++, half_width); +- putchar('\n'); +- continue; +- } +- /* Length without ANSI codes */ +- size_t effective_len = get_effective_length(buffer); +- size_t offset = 0; +- while (effective_len > 0 && row <= rows - 1) { +- move_cursor(row++, half_width); +- +- /* Calculate the chunk size based on effective length */ +- size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len; +- +- /* Find the actual end position in the string to avoid cutting ANSI sequences */ +- size_t actual_end = offset; +- size_t visible_count = 0; +- bool in_ansi_sequence = false; +- +- while (visible_count < chunk_size && buffer[actual_end] != '\0') { +- if (buffer[actual_end] == '\033') { +- in_ansi_sequence = true; +- } +- if (!in_ansi_sequence) { +- visible_count++; +- } +- if (in_ansi_sequence && buffer[actual_end] == 'm') { +- in_ansi_sequence = false; +- } +- actual_end++; ++ if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { ++ move_cursor(row++, half_width); ++ putchar('\n'); ++ continue; + } ++ /* Length without ANSI codes */ ++ size_t effective_len = get_effective_length(buffer); ++ size_t offset = 0; ++ while (effective_len > 0 && row <= rows - 1) { ++ move_cursor(row++, half_width); + +- /* Print the chunk from `offset` to `actual_end` */ +- print_chunk(buffer, offset, actual_end); ++ /* Calculate the chunk size based on effective length */ ++ size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len; + +- /* Update offsets based on the effective length and ANSI-aware chunk */ +- offset = actual_end; +- effective_len -= chunk_size; ++ /* Find the actual end position in the string to avoid cutting ANSI sequences */ ++ size_t actual_end = offset; ++ size_t visible_count = 0; ++ bool in_ansi_sequence = false; + +- putchar('\n'); +- } +- /* Check if the line ends with the ANSI reset sequence `\033[0m` */ +- size_t len = strlen(buffer); +- if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) { +- /* Line ends with ANSI reset, print it */ +- printf("\033[0m"); ++ while (visible_count < chunk_size && buffer[actual_end] != '\0') { ++ if (buffer[actual_end] == '\033') { ++ in_ansi_sequence = true; ++ } ++ if (!in_ansi_sequence) { ++ visible_count++; ++ } ++ if (in_ansi_sequence && buffer[actual_end] == 'm') { ++ in_ansi_sequence = false; ++ } ++ actual_end++; ++ } ++ ++ /* Print the chunk from `offset` to `actual_end` */ ++ print_chunk(buffer, offset, actual_end); ++ ++ /* Update offsets based on the effective length and ANSI-aware chunk */ ++ offset = actual_end; ++ effective_len -= chunk_size; ++ ++ putchar('\n'); ++ } ++ /* Check if the line ends with the ANSI reset sequence `\033[0m` */ ++ size_t len = strlen(buffer); ++ if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) { ++ /* Line ends with ANSI reset, print it */ ++ printf("\033[0m"); ++ } + } ++ fclose(stream); + } +- fclose(stream); + waitpid(pid, NULL, 0); + } else { + wpprintw("fork failed: %s", strerror(errno));