Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Kitty inline image & base64 encoding fixes #177

Merged
merged 1 commit into from
Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 24 additions & 33 deletions etc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
6 changes: 1 addition & 5 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
125 changes: 56 additions & 69 deletions terms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand All @@ -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);
Expand All @@ -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)) {
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down