Add image preview support with libsixel
This commit is contained in:
parent
ec67b06594
commit
0caf9527a5
1 changed files with 76 additions and 59 deletions
135
ccc.c
135
ccc.c
|
@ -13,6 +13,8 @@
|
||||||
#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"
|
||||||
|
@ -870,12 +872,14 @@ void show_file_content(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int c;
|
if (strstr(current_file.name, ".jpg") == NULL && strstr(current_file.name, ".png") == NULL) {
|
||||||
/* Check if its binary */
|
int c;
|
||||||
while ((c = fgetc(file)) != EOF) {
|
/* Check if its binary */
|
||||||
if (c == '\0') {
|
while ((c = fgetc(file)) != EOF) {
|
||||||
bprintf("binary");
|
if (c == '\0') {
|
||||||
return;
|
bprintf("binary");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int pipe_fd[2];
|
int pipe_fd[2];
|
||||||
|
@ -887,67 +891,80 @@ void show_file_content(void)
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
move_cursor(1, half_width);
|
move_cursor(1, half_width);
|
||||||
close(pipe_fd[0]);
|
if (strstr(current_file.name, ".jpg") || strstr(current_file.name, ".png")) {
|
||||||
dup2(pipe_fd[1], STDOUT_FILENO);
|
sixel_encoder_t *encoder = NULL;
|
||||||
dup2(pipe_fd[1], STDERR_FILENO);
|
sixel_encoder_new(&encoder, NULL);
|
||||||
close(pipe_fd[1]);
|
/* Should be enough for most terminal */
|
||||||
execlp("vip", "vip", "-c", current_file.name, NULL);
|
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);
|
_exit(1);
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
/* Parent */
|
/* Parent */
|
||||||
close(pipe_fd[1]);
|
if (!strstr(current_file.name, ".jpg") && !strstr(current_file.name, ".png")) {
|
||||||
char buffer[4096];
|
close(pipe_fd[1]);
|
||||||
int row = 1;
|
char buffer[4096];
|
||||||
FILE *stream = fdopen(pipe_fd[0], "r");
|
int row = 1;
|
||||||
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) {
|
FILE *stream = fdopen(pipe_fd[0], "r");
|
||||||
buffer[strcspn(buffer, "\n")] = 0;
|
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) {
|
||||||
|
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 */
|
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
/* 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` */
|
/* Calculate the chunk size based on effective length */
|
||||||
print_chunk(buffer, offset, actual_end);
|
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 */
|
/* Find the actual end position in the string to avoid cutting ANSI sequences */
|
||||||
offset = actual_end;
|
size_t actual_end = offset;
|
||||||
effective_len -= chunk_size;
|
size_t visible_count = 0;
|
||||||
|
bool in_ansi_sequence = false;
|
||||||
|
|
||||||
putchar('\n');
|
while (visible_count < chunk_size && buffer[actual_end] != '\0') {
|
||||||
}
|
if (buffer[actual_end] == '\033') {
|
||||||
/* Check if the line ends with the ANSI reset sequence `\033[0m` */
|
in_ansi_sequence = true;
|
||||||
size_t len = strlen(buffer);
|
}
|
||||||
if (len >= 4 && strcmp(&buffer[len - 4], "\033[0m") == 0) {
|
if (!in_ansi_sequence) {
|
||||||
/* Line ends with ANSI reset, print it */
|
visible_count++;
|
||||||
printf("\033[0m");
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue