This commit is contained in:
Night Kaly 2024-11-13 09:43:48 +00:00
parent f3986f2acf
commit 0992128a5f
Signed by: night0721
SSH key fingerprint: SHA256:B/hgVwUoBpx5vdNsXl9w8XwZljA9766uk6T4ubZp5HM
2 changed files with 65 additions and 84 deletions

View file

@ -8,9 +8,7 @@ PREFIX ?= /usr/local
BINDIR = $(PREFIX)/bin BINDIR = $(PREFIX)/bin
MANDIR = $(PREFIX)/share/man/man1 MANDIR = $(PREFIX)/share/man/man1
LDFLAGS != pkg-config --libs libsixel CFLAGS = -Os -march=native -mtune=native -pipe -s -flto -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600
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 SRC = ccc.c util.c file.c icons.c

145
ccc.c
View file

@ -13,8 +13,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sixel.h>
#include "config.h" #include "config.h"
#include "file.h" #include "file.h"
#include "icons.h" #include "icons.h"
@ -872,14 +870,12 @@ void show_file_content(void)
return; return;
} }
if (strstr(current_file.name, ".jpg") == NULL && strstr(current_file.name, ".png") == NULL) { int c;
int c; /* Check if its binary */
/* Check if its binary */ while ((c = fgetc(file)) != EOF) {
while ((c = fgetc(file)) != EOF) { if (c == '\0') {
if (c == '\0') { bprintf("binary");
bprintf("binary"); return;
return;
}
} }
} }
int pipe_fd[2]; int pipe_fd[2];
@ -891,83 +887,70 @@ void show_file_content(void)
if (pid == 0) { if (pid == 0) {
/* Child */ /* Child */
move_cursor(1, half_width); move_cursor(1, half_width);
if (strstr(current_file.name, ".jpg") || strstr(current_file.name, ".png")) { close(pipe_fd[0]);
sixel_encoder_t *encoder = NULL; dup2(pipe_fd[1], STDOUT_FILENO);
sixel_encoder_new(&encoder, NULL); dup2(pipe_fd[1], STDERR_FILENO);
/* Should be enough for most terminal */ close(pipe_fd[1]);
char width[5]; execlp("vip", "vip", "-c", current_file.name, NULL);
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); _exit(1);
} else if (pid > 0) { } else if (pid > 0) {
/* Parent */ /* Parent */
if (!strstr(current_file.name, ".jpg") && !strstr(current_file.name, ".png")) { close(pipe_fd[1]);
close(pipe_fd[1]); char buffer[4096];
char buffer[4096]; int row = 1;
int row = 1; FILE *stream = fdopen(pipe_fd[0], "r");
FILE *stream = fdopen(pipe_fd[0], "r"); while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) {
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { buffer[strcspn(buffer, "\n")] = 0;
buffer[strcspn(buffer, "\n")] = 0;
if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) {
move_cursor(row++, half_width); move_cursor(row++, half_width);
putchar('\n'); putchar('\n');
continue; continue;
} }
/* Length without ANSI codes */ /* Length without ANSI codes */
size_t effective_len = get_effective_length(buffer); size_t effective_len = get_effective_length(buffer);
size_t offset = 0; size_t offset = 0;
while (effective_len > 0 && row <= rows - 1) { while (effective_len > 0 && row <= rows - 1) {
move_cursor(row++, half_width); move_cursor(row++, half_width);
/* Calculate the chunk size based on effective length */ /* Calculate the chunk size based on effective length */
size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len; 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 */ /* Find the actual end position in the string to avoid cutting ANSI sequences */
size_t actual_end = offset; size_t actual_end = offset;
size_t visible_count = 0; size_t visible_count = 0;
bool in_ansi_sequence = false; bool in_ansi_sequence = false;
while (visible_count < chunk_size && buffer[actual_end] != '\0') { while (visible_count < chunk_size && buffer[actual_end] != '\0') {
if (buffer[actual_end] == '\033') { if (buffer[actual_end] == '\033') {
in_ansi_sequence = true; in_ansi_sequence = true;
} }
if (!in_ansi_sequence) { if (!in_ansi_sequence) {
visible_count++; visible_count++;
} }
if (in_ansi_sequence && buffer[actual_end] == 'm') { if (in_ansi_sequence && buffer[actual_end] == 'm') {
in_ansi_sequence = false; in_ansi_sequence = false;
} }
actual_end++; actual_end++;
} }
/* Print the chunk from `offset` to `actual_end` */ /* Print the chunk from `offset` to `actual_end` */
print_chunk(buffer, offset, actual_end); print_chunk(buffer, offset, actual_end);
/* Update offsets based on the effective length and ANSI-aware chunk */ /* Update offsets based on the effective length and ANSI-aware chunk */
offset = actual_end; offset = actual_end;
effective_len -= chunk_size; effective_len -= chunk_size;
putchar('\n'); putchar('\n');
} }
/* Check if the line ends with the ANSI reset sequence `\033[0m` */ /* Check if the line ends with the ANSI reset sequence `\033[0m` */
size_t len = strlen(buffer); size_t len = strlen(buffer);
if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) { if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) {
/* Line ends with ANSI reset, print it */ /* Line ends with ANSI reset, print it */
printf("\033[0m"); printf("\033[0m");
}
} }
fclose(stream);
} }
fclose(stream);
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
} else { } else {
wpprintw("fork failed: %s", strerror(errno)); wpprintw("fork failed: %s", strerror(errno));