From 694a10271dd33aeba7a1cf3d72caf4f1384d611a Mon Sep 17 00:00:00 2001 From: bptato Date: Sun, 4 Apr 2021 17:57:13 +0200 Subject: Return Str from base64_encode, fix extraction of first gif frame for animations in put_image_kitty --- etc.c | 57 +++++++++++++---------------- file.c | 6 +--- proto.h | 2 +- terms.c | 125 +++++++++++++++++++++++++++++----------------------------------- 4 files changed, 82 insertions(+), 108 deletions(-) diff --git a/etc.c b/etc.c index bc72005..70735db 100644 --- a/etc.c +++ b/etc.c @@ -2008,32 +2008,25 @@ void (*mySignal(int signal_number, void (*action) (int))) (int) { static char Base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -char * +Str base64_encode(const unsigned char *src, size_t len) { - unsigned char *w, *at; + Str dest; const unsigned char *in, *endw; unsigned long j; size_t k; - - if (!len) - return NULL; - k = len; if (k % 3) - k += 3 - (k % 3); + k += 3 - (k % 3); + k = k / 3 * 4; - if (k + 1 < len) - return NULL; + if (!len || k + 1 < len) + return Strnew(); - w = GC_MALLOC_ATOMIC(k + 1); - if (!w) - return NULL; - w[k] = 0; + dest = Strnew_size(k); - at = w; in = src; endw = src + len - 2; @@ -2043,30 +2036,28 @@ base64_encode(const unsigned char *src, size_t len) j = j << 8 | *in++; j = j << 8 | *in++; - *at++ = Base64Table[(j >> 18) & 0x3f]; - *at++ = Base64Table[(j >> 12) & 0x3f]; - *at++ = Base64Table[(j >> 6) & 0x3f]; - *at++ = Base64Table[j & 0x3f]; + Strcat_char(dest, Base64Table[(j >> 18) & 0x3f]); + Strcat_char(dest, Base64Table[(j >> 12) & 0x3f]); + Strcat_char(dest, Base64Table[(j >> 6) & 0x3f]); + Strcat_char(dest, Base64Table[j & 0x3f]); } - if (in - src - len) { - if (in - src - len == 1) { - j = *in++; - j = j << 8; + if (src + len - in) { + j = *in++; + if (src + len - in) { + j = j << 8 | *in++; j = j << 8; - *at++ = Base64Table[(j >> 18) & 0x3f]; - *at++ = Base64Table[(j >> 12) & 0x3f]; - *at++ = '='; - *at++ = '='; + Strcat_char(dest, Base64Table[(j >> 18) & 0x3f]); + Strcat_char(dest, Base64Table[(j >> 12) & 0x3f]); + Strcat_char(dest, Base64Table[(j >> 6) & 0x3f]); } else { - j = *in++; - j = j << 8 | *in++; j = j << 8; - *at++ = Base64Table[(j >> 18) & 0x3f]; - *at++ = Base64Table[(j >> 12) & 0x3f]; - *at++ = Base64Table[(j >> 6) & 0x3f]; - *at++ = '='; + j = j << 8; + Strcat_char(dest, Base64Table[(j >> 18) & 0x3f]); + Strcat_char(dest, Base64Table[(j >> 12) & 0x3f]); + Strcat_char(dest, '='); } + Strcat_char(dest, '='); } - return (char *)w; + return dest; } diff --git a/file.c b/file.c index 8718dd3..836af97 100644 --- a/file.c +++ b/file.c @@ -1179,11 +1179,7 @@ AuthBasicCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, Str s = Strdup(uname); Strcat_char(s, ':'); Strcat(s, pw); - char *base64 = base64_encode(s->ptr, s->length); - if (!base64) - return Strnew_charp("Basic "); - else - return Strnew_m_charp("Basic ", base64, NULL); + return Strnew_m_charp("Basic ", base64_encode(s->ptr, s->length)->ptr, NULL); } #ifdef USE_DIGEST_AUTH diff --git a/proto.h b/proto.h index 899eec8..aa373dc 100644 --- a/proto.h +++ b/proto.h @@ -829,4 +829,4 @@ void srand48(long); long lrand48(void); #endif -extern char *base64_encode(const unsigned char *src, size_t len); +extern Str base64_encode(const unsigned char *src, size_t len); diff --git a/terms.c b/terms.c index 6189ec0..6dece45 100644 --- a/terms.c +++ b/terms.c @@ -491,7 +491,7 @@ void put_image_iterm2(char *url, int x, int y, int w, int h) { Str buf; - char *base64, *cbuf; + char *cbuf; FILE *fp; int c, i; struct stat st; @@ -518,32 +518,25 @@ put_image_iterm2(char *url, int x, int y, int w, int h) writestr(buf->ptr); cbuf = GC_MALLOC_ATOMIC(3072); + if (!cbuf) + goto cleanup; i = 0; while ((c = fgetc(fp)) != EOF) { cbuf[i++] = c; if (i == 3072) { - base64 = base64_encode(cbuf, i); - if (!base64) { - writestr("\a"); - fclose(fp); - return; - } - writestr(base64); + buf = base64_encode(cbuf, i); + writestr(buf->ptr); i = 0; } } - fclose(fp); - if (i) { - base64 = base64_encode(cbuf, i); - if (!base64) { - writestr("\a"); - return; - } - writestr(base64); + buf = base64_encode(cbuf, i); + writestr(buf->ptr); } +cleanup: + fclose(fp); writestr("\a"); MOVE(Currentbuf->cursorY,Currentbuf->cursorX); } @@ -555,11 +548,11 @@ 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, *tmpf; + Str buf, base64; + char *cbuf, *type, *tmpf; char *argv[4]; FILE *fp; - int c, i, j, k, t; + int c, i, j, m, t, is_anim; struct stat st; pid_t pid; MySignalHandler(*volatile previntr) (SIGNAL_ARG); @@ -573,9 +566,14 @@ put_image_kitty(char *url, int x, int y, int w, int h, int sx, int sy, int sw, t = 100; /* always convert to png for now. */ if(!(type && !strcasecmp(type, "image/png"))) { - buf = Strnew(); tmpf = Sprintf("%s/%s.png", tmp_dir, mybasename(url))->ptr; + if (!strcasecmp(type, "image/gif")) { + is_anim = 1; + } else { + is_anim = 0; + } + /* convert only if png doesn't exist yet. */ if (stat(tmpf, &st)) { @@ -599,7 +597,13 @@ put_image_kitty(char *url, int x, int y, int w, int h, int sx, int sy, int sw, else argv[i++] = "convert"; - argv[i++] = url; + if (is_anim) { + buf = Strnew_charp(url); + Strcat_charp(buf, "[0]"); + argv[i++] = buf->ptr; + } else { + argv[i++] = url; + } argv[i++] = tmpf; argv[i++] = NULL; execvp(argv[0],argv); @@ -626,67 +630,50 @@ put_image_kitty(char *url, int x, int y, int w, int h, int sx, int sy, int sw, return; MOVE(y, x); - buf = Sprintf("\x1b_Gf=100,s=%d,v=%d,a=T,m=1,x=%d,y=%d," - "w=%d,h=%d,c=%d,r=%d;", - w, h, sx, sy, sw, sh, cols, rows); - cbuf = GC_MALLOC_ATOMIC(3072); + cbuf = GC_MALLOC_ATOMIC(3072); /* base64-encoded chunks of 4096 bytes */ + if (!cbuf) + goto cleanup; i = 0; - j = buf->length; - while (buf->length + i / 3 * 4 < 4096 && (c = fgetc(fp)) != EOF) { + while (i < 3072 && (c = fgetc(fp)) != EOF) cbuf[i++] = c; - } + base64 = base64_encode(cbuf, i); - if (!base64) { - fclose(fp); - return; - } if (c == EOF) - buf = Sprintf("\x1b_Gf=100,s=%d,v=%d,a=T,m=0,x=%d,y=%d," - "w=%d,h=%d,c=%d,r=%d;", - w, h, sx, sy, sw, sh, cols, rows); + m = 0; + else + m = 1; + buf = Sprintf("\x1b_Gf=%d,s=%d,v=%d,a=T,m=%d,x=%d,y=%d,w=%d,h=%d,c=%d,r=%d;" + "%s\x1b\\", t, w, h, m, sx, sy, sw, sh, cols, rows, base64->ptr); writestr(buf->ptr); - buf = Sprintf("%s\x1b\\", base64); - writestr(buf->ptr); + if (m) { + i = 0; + j = 0; + while ((c = fgetc(fp)) != EOF) { + if (j) { + base64 = base64_encode(cbuf, i); + buf = Sprintf("\x1b_Gm=1;%s\x1b\\", base64->ptr); + writestr(buf->ptr); + i = 0; + j = 0; + } + cbuf[i++] = c; + if (i == 3072) + j = 1; + } - if (c != EOF) { - 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; - if (i == 3072) { - base64 = base64_encode(cbuf, i); - if (!base64) { - fclose(fp); - return; - } - - i = 0; - } - } - - if (i) { - base64 = base64_encode(cbuf, i); - if (!base64) { - fclose(fp); - return; - } - } - - if (base64) { - buf = Sprintf("\x1b_Gm=0;%s\x1b\\", base64); - writestr(buf->ptr); - } + if (i) { + base64 = base64_encode(cbuf, i); + buf = Sprintf("\x1b_Gm=0;%s\x1b\\", base64->ptr); + writestr(buf->ptr); + } } +cleanup: fclose(fp); MOVE(Currentbuf->cursorY, Currentbuf->cursorX); } -- cgit v1.2.3