aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-02-18 18:18:06 +0000
committerbptato <nincsnevem662@gmail.com>2021-02-18 18:18:06 +0000
commit3304675affd22e9ede2c92b5c0085961a797485e (patch)
treef476160aca8d8700798d5ec97b33339d2514f025
parentHandle iTerm2 images more efficiently (diff)
downloadw3m-3304675affd22e9ede2c92b5c0085961a797485e.tar.gz
w3m-3304675affd22e9ede2c92b5c0085961a797485e.zip
Support kitty image protocol
-rw-r--r--etc.c4
-rw-r--r--fm.h1
-rw-r--r--image.c4
-rw-r--r--rc.c1
-rw-r--r--terms.c80
5 files changed, 89 insertions, 1 deletions
diff --git a/etc.c b/etc.c
index 2870caf..bc72005 100644
--- a/etc.c
+++ b/etc.c
@@ -2016,6 +2016,10 @@ base64_encode(const unsigned char *src, size_t len)
unsigned long j;
size_t k;
+
+ if (!len)
+ return NULL;
+
k = len;
if (k % 3)
k += 3 - (k % 3);
diff --git a/fm.h b/fm.h
index c4a951f..997574a 100644
--- a/fm.h
+++ b/fm.h
@@ -316,6 +316,7 @@ extern int REV_LB[];
#define INLINE_IMG_OSC5379 1
#define INLINE_IMG_SIXEL 2
#define INLINE_IMG_ITERM2 3
+#define INLINE_IMG_KITTY 4
/*
* Types.
diff --git a/image.c b/image.c
index 6e4e9b4..f25c895 100644
--- a/image.c
+++ b/image.c
@@ -198,6 +198,8 @@ syncImage(void)
void put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh);
void put_image_sixel(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image);
void put_image_iterm2(char *url, int x, int y, int w, int h);
+void put_image_kitty(char *url, int x, int y, int w, int h, int sx, int sy, int
+ sw, int sh, int c, int r);
void
drawImage()
@@ -256,6 +258,8 @@ drawImage()
put_image_osc5379(url, x, y, w, h, sx, sy, sw, sh);
} else if (enable_inline_image == INLINE_IMG_ITERM2) {
put_image_iterm2(url, x, y, sw, sh);
+ } else if (enable_inline_image == INLINE_IMG_KITTY) {
+ put_image_kitty(url, x, y, w, h, i->sx, i->sy, sw * pixel_per_char, sh * pixel_per_line_i, sw, sh);
}
continue ;
diff --git a/rc.c b/rc.c
index 3c72ffb..18693a5 100644
--- a/rc.c
+++ b/rc.c
@@ -374,6 +374,7 @@ static struct sel_c inlineimgstr[] = {
{N_S(INLINE_IMG_OSC5379), N_("OSC 5379 (mlterm)")},
{N_S(INLINE_IMG_SIXEL), N_("sixel (img2sixel)")},
{N_S(INLINE_IMG_ITERM2), N_("OSC 1337 (iTerm2)")},
+ {N_S(INLINE_IMG_KITTY), N_("kitty (PNG only)")},
{0, NULL, NULL}
};
#endif /* USE_IMAGE */
diff --git a/terms.c b/terms.c
index f7c300e..45c5f86 100644
--- a/terms.c
+++ b/terms.c
@@ -521,7 +521,6 @@ put_image_iterm2(char *url, int x, int y, int w, int h)
i = 0;
while ((c = fgetc(fp)) != EOF) {
cbuf[i] = c;
- Strcat_char(buf, c);
++i;
if (i == 3072) {
base64 = base64_encode(cbuf, i);
@@ -547,6 +546,85 @@ put_image_iterm2(char *url, int x, int y, int w, int h)
MOVE(Currentbuf->cursorY,Currentbuf->cursorX);
}
+void
+put_image_kitty(char *url, int x, int y, int w, int h, int sx, int sy, int sw,
+ int sh, int cols, int rows)
+{
+ Str buf;
+ char *base64, *cbuf, *type;
+ FILE *fp;
+ int c, i, j, k, t;
+ struct stat st;
+
+ if (stat(url, &st))
+ return;
+
+ fp = fopen(url, "r");
+ if (!fp)
+ return;
+
+ type = guessContentType(url);
+ if(!strcasecmp(type, "image/png")) {
+ t = 100;
+ } else {
+ /* TODO: kitty +kitten icat or link imlib/gdkpixbuf? */
+ return;
+ }
+
+ MOVE(y, x);
+ buf = Sprintf("\x1b_Gf=100,s=%d,v=%d,a=T,m=1,X=%d,Y=%d,x=%d,y=%d,"
+ "w=%d,h=%d,c=%d,r=%d;",
+ w, h, x, y, sx, sy, sw, sh, cols, rows);
+
+ writestr(buf->ptr);
+
+ cbuf = GC_MALLOC_ATOMIC(3072);
+ i = 0;
+ j = buf->length;
+
+ while (buf->length + i / 3 * 4 < 4096 && (c = fgetc(fp)) != EOF) {
+ cbuf[i] = c;
+ ++i;
+ }
+
+ base64 = base64_encode(cbuf, i);
+ if (!base64)
+ return;
+
+ buf = Sprintf("%s\x1b\\", base64);
+ writestr(buf->ptr);
+ i = 0;
+ base64 = NULL;
+
+ while ((c = fgetc(fp)) != EOF) {
+ if (!i && base64) {
+ buf = Sprintf("\x1b_Gm=1;%s\x1b\\", base64);
+ writestr(buf->ptr);
+ }
+ cbuf[i] = c;
+ ++i;
+ if (i == 3072) {
+ base64 = base64_encode(cbuf, i);
+ if (!base64)
+ return;
+
+ i = 0;
+ }
+ }
+
+ if (i) {
+ base64 = base64_encode(cbuf, i);
+ if (!base64)
+ return;
+ }
+
+ if (base64) {
+ buf = Sprintf("\x1b_Gm=0;%s\x1b\\", base64);
+ writestr(buf->ptr);
+ }
+ MOVE(Currentbuf->cursorY, Currentbuf->cursorX);
+}
+
static void
save_gif(const char *path, u_char *header, size_t header_size, u_char *body, size_t body_size)
{