|
|
@ -222,17 +222,15 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
|
|
|
|
// we can only write 4KiB at a time. we're writing base64-encoded RGBA. each
|
|
|
|
// we can only write 4KiB at a time. we're writing base64-encoded RGBA. each
|
|
|
|
// pixel is 4B raw (32 bits). each chunk of three pixels is then 12 bytes, or
|
|
|
|
// pixel is 4B raw (32 bits). each chunk of three pixels is then 12 bytes, or
|
|
|
|
// 16 base64-encoded bytes. 4096 / 16 == 256 3-pixel groups, or 768 pixels.
|
|
|
|
// 16 base64-encoded bytes. 4096 / 16 == 256 3-pixel groups, or 768 pixels.
|
|
|
|
static sprixcell_e*
|
|
|
|
// closes |fp| on all paths.
|
|
|
|
write_kitty_data(FILE* fp, int rows, int cols, int linesize, int leny, int lenx,
|
|
|
|
static int
|
|
|
|
const uint32_t* data, int sprixelid, int* parse_start){
|
|
|
|
write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
|
|
|
|
|
|
|
|
const uint32_t* data, int sprixelid, sprixcell_e* tacache,
|
|
|
|
|
|
|
|
int* parse_start){
|
|
|
|
if(linesize % sizeof(*data)){
|
|
|
|
if(linesize % sizeof(*data)){
|
|
|
|
return NULL;
|
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
sprixcell_e* tacache = malloc(sizeof(*tacache) * rows * cols);
|
|
|
|
|
|
|
|
if(tacache == NULL){
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
memset(tacache, 0, sizeof(*tacache) * rows * cols);
|
|
|
|
|
|
|
|
(void)tacache; // FIXME populate tacache with 1s for cells with transparency
|
|
|
|
(void)tacache; // FIXME populate tacache with 1s for cells with transparency
|
|
|
|
int total = leny * lenx; // total number of pixels (4 * total == bytecount)
|
|
|
|
int total = leny * lenx; // total number of pixels (4 * total == bytecount)
|
|
|
|
// number of 4KiB chunks we'll need
|
|
|
|
// number of 4KiB chunks we'll need
|
|
|
@ -276,16 +274,15 @@ write_kitty_data(FILE* fp, int rows, int cols, int linesize, int leny, int lenx,
|
|
|
|
fprintf(fp, "\e\\");
|
|
|
|
fprintf(fp, "\e\\");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(fclose(fp) == EOF){
|
|
|
|
if(fclose(fp) == EOF){
|
|
|
|
free(tacache);
|
|
|
|
return -1;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return tacache;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef RGBA_MAXLEN
|
|
|
|
#undef RGBA_MAXLEN
|
|
|
|
|
|
|
|
|
|
|
|
// Kitty graphics blitter. Kitty can take in up to 4KiB at a time of (optionally
|
|
|
|
// Kitty graphics blitter. Kitty can take in up to 4KiB at a time of (optionally
|
|
|
|
// deflate-compressed) 24bit RGB. Returns -1 on error, 1 on success.
|
|
|
|
// deflate-compressed) 24bit RGB. Returns -1 on error, 1 on success.
|
|
|
|
int kitty_blit(ncplane* nc, int linesize, const void* data,
|
|
|
|
int kitty_blit(ncplane* n, int linesize, const void* data,
|
|
|
|
int leny, int lenx, const blitterargs* bargs){
|
|
|
|
int leny, int lenx, const blitterargs* bargs){
|
|
|
|
int rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy);
|
|
|
|
int rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy);
|
|
|
|
int cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx);
|
|
|
|
int cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx);
|
|
|
@ -295,17 +292,44 @@ int kitty_blit(ncplane* nc, int linesize, const void* data,
|
|
|
|
if(fp == NULL){
|
|
|
|
if(fp == NULL){
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sprixcell_e* tacache = NULL;
|
|
|
|
|
|
|
|
bool reuse = false;
|
|
|
|
|
|
|
|
// if we have a sprixel attached to this plane, see if we can reuse it
|
|
|
|
|
|
|
|
// (we need the same dimensions) and thus immediately apply its T-A table.
|
|
|
|
|
|
|
|
int sprixelid;
|
|
|
|
|
|
|
|
fprintf(stderr, "n: %p n->srite: %p\n", n, n->sprite);
|
|
|
|
|
|
|
|
if(n->sprite){
|
|
|
|
|
|
|
|
sprixel* s = n->sprite;
|
|
|
|
|
|
|
|
if(s->dimy == rows && s->dimx == cols){
|
|
|
|
|
|
|
|
fprintf(stderr, "REUSING\n");
|
|
|
|
|
|
|
|
tacache = s->tacache;
|
|
|
|
|
|
|
|
s->tacache = NULL;
|
|
|
|
|
|
|
|
reuse = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
int parse_start = 0;
|
|
|
|
int parse_start = 0;
|
|
|
|
// closes fp on success
|
|
|
|
if(!reuse){
|
|
|
|
sprixcell_e* tacache = write_kitty_data(fp, rows, cols, linesize, leny, lenx, data,
|
|
|
|
fprintf(stderr, "DIDN'T REUSE\n");
|
|
|
|
bargs->u.pixel.sprixelid, &parse_start);
|
|
|
|
tacache = malloc(sizeof(*tacache) * rows * cols);
|
|
|
|
if(tacache == NULL){
|
|
|
|
if(tacache == NULL){
|
|
|
|
fclose(fp);
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(tacache, 0, sizeof(*tacache) * rows * cols);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sprixelid = bargs->u.pixel.sprixelid;
|
|
|
|
|
|
|
|
// closes fp on all paths
|
|
|
|
|
|
|
|
if(write_kitty_data(fp, linesize, leny, lenx, data,
|
|
|
|
|
|
|
|
sprixelid, tacache, &parse_start)){
|
|
|
|
|
|
|
|
if(!reuse){
|
|
|
|
|
|
|
|
free(tacache);
|
|
|
|
|
|
|
|
}
|
|
|
|
free(buf);
|
|
|
|
free(buf);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// takes ownership of |buf| on success
|
|
|
|
// take ownership of |buf| on success
|
|
|
|
if(plane_blit_sixel(nc, buf, size, bargs->placey, bargs->placex,
|
|
|
|
if(plane_blit_sixel(n, buf, size, bargs->placey, bargs->placex,
|
|
|
|
rows, cols, bargs->u.pixel.sprixelid, leny, lenx,
|
|
|
|
rows, cols, bargs->u.pixel.sprixelid, leny, lenx,
|
|
|
|
parse_start, tacache) < 0){
|
|
|
|
parse_start, tacache) < 0){
|
|
|
|
free(tacache);
|
|
|
|
free(tacache);
|
|
|
|