mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
[sprixel] unite TAM allocation/resize path #2240
This commit is contained in:
parent
4336aec7d5
commit
5b5e97033d
@ -1054,47 +1054,26 @@ kitty_blit_core(ncplane* n, int linesize, const void* data, int leny, int lenx,
|
||||
const blitterargs* bargs, ncpixelimpl_e level){
|
||||
//fprintf(stderr, "IMAGE: start %p end %p\n", data, (const char*)data + leny * linesize);
|
||||
int cols = bargs->u.pixel.spx->dimx;
|
||||
int rows = bargs->u.pixel.spx->dimy;
|
||||
sprixel* s = bargs->u.pixel.spx;
|
||||
if(init_sprixel_animation(s)){
|
||||
return -1;
|
||||
}
|
||||
tament* tam = 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.
|
||||
if(n->tam){
|
||||
if(n->leny == rows && n->lenx == cols){
|
||||
tam = n->tam;
|
||||
reuse = true;
|
||||
}
|
||||
}
|
||||
int parse_start = 0;
|
||||
if(!reuse){
|
||||
tam = malloc(sizeof(*tam) * rows * cols);
|
||||
if(tam == NULL){
|
||||
goto error;
|
||||
}
|
||||
memset(tam, 0, sizeof(*tam) * rows * cols);
|
||||
}
|
||||
fbuf* f = &s->glyph;
|
||||
if(write_kitty_data(f, linesize, leny, lenx, cols, data,
|
||||
bargs, tam, &parse_start, level)){
|
||||
bargs, n->tam, &parse_start, level)){
|
||||
goto error;
|
||||
}
|
||||
if(level == NCPIXEL_KITTY_STATIC){
|
||||
s->animating = false;
|
||||
}
|
||||
// take ownership of |buf| and |tam| on success.
|
||||
if(plane_blit_sixel(s, &s->glyph, leny, lenx, parse_start, tam, SPRIXEL_UNSEEN) < 0){
|
||||
if(plane_blit_sixel(s, &s->glyph, leny, lenx, parse_start, n->tam, SPRIXEL_UNSEEN) < 0){
|
||||
goto error;
|
||||
}
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if(!reuse){
|
||||
free(tam);
|
||||
}
|
||||
fbuf_free(&s->glyph);
|
||||
return -1;
|
||||
}
|
||||
|
@ -32,8 +32,6 @@ int fbcon_wipe(sprixel* s, int ycell, int xcell){
|
||||
int fbcon_blit(struct ncplane* n, int linesize, const void* data,
|
||||
int leny, int lenx, const struct blitterargs* bargs){
|
||||
uint32_t transcolor = bargs->transcolor;
|
||||
int cols = bargs->u.pixel.spx->dimx;
|
||||
int rows = bargs->u.pixel.spx->dimy;
|
||||
sprixel* s = bargs->u.pixel.spx;
|
||||
int cdimx = s->cellpxx;
|
||||
int cdimy = s->cellpxy;
|
||||
@ -42,21 +40,6 @@ int fbcon_blit(struct ncplane* n, int linesize, const void* data,
|
||||
if(fbuf_reserve(&s->glyph, flen)){
|
||||
return -1;
|
||||
}
|
||||
tament* tam = NULL;
|
||||
bool reuse = false;
|
||||
if(n->tam){
|
||||
if(n->leny == rows && n->lenx == cols){
|
||||
tam = n->tam;
|
||||
reuse = true;
|
||||
}
|
||||
}
|
||||
if(!reuse){
|
||||
tam = malloc(sizeof(*tam) * rows * cols);
|
||||
if(tam == NULL){
|
||||
goto error;
|
||||
}
|
||||
memset(tam, 0, sizeof(*tam) * rows * cols);
|
||||
}
|
||||
for(int l = 0 ; l < leny ; ++l){
|
||||
int ycell = l / cdimy;
|
||||
size_t soffset = l * linesize;
|
||||
@ -66,32 +49,32 @@ int fbcon_blit(struct ncplane* n, int linesize, const void* data,
|
||||
for(int c = 0 ; c < lenx ; ++c){
|
||||
int xcell = c / cdimx;
|
||||
int tyx = xcell + ycell * bargs->u.pixel.spx->dimx;
|
||||
if(tam[tyx].state >= SPRIXCELL_ANNIHILATED){
|
||||
if(n->tam[tyx].state >= SPRIXCELL_ANNIHILATED){
|
||||
if(rgba_trans_p(*(uint32_t*)src, transcolor)){
|
||||
ncpixel_set_a((uint32_t*)src, 0); // in case it was transcolor
|
||||
if(c % cdimx == 0 && l % cdimy == 0){
|
||||
tam[tyx].state = SPRIXCELL_ANNIHILATED_TRANS;
|
||||
n->tam[tyx].state = SPRIXCELL_ANNIHILATED_TRANS;
|
||||
}
|
||||
}else{
|
||||
tam[tyx].state = SPRIXCELL_ANNIHILATED;
|
||||
n->tam[tyx].state = SPRIXCELL_ANNIHILATED;
|
||||
}
|
||||
dst[3] = 0;
|
||||
const int vyx = (l % cdimy) * cdimx + (c % cdimx);
|
||||
tam[tyx].auxvector[vyx] = src[3];
|
||||
n->tam[tyx].auxvector[vyx] = src[3];
|
||||
}else{
|
||||
if(rgba_trans_p(*(uint32_t*)src, transcolor)){
|
||||
ncpixel_set_a((uint32_t*)src, 0); // in case it was transcolor
|
||||
if(c % cdimx == 0 && l % cdimy == 0){
|
||||
tam[tyx].state = SPRIXCELL_TRANSPARENT;
|
||||
}else if(tam[tyx].state == SPRIXCELL_OPAQUE_SIXEL){
|
||||
tam[tyx].state = SPRIXCELL_MIXED_SIXEL;
|
||||
n->tam[tyx].state = SPRIXCELL_TRANSPARENT;
|
||||
}else if(n->tam[tyx].state == SPRIXCELL_OPAQUE_SIXEL){
|
||||
n->tam[tyx].state = SPRIXCELL_MIXED_SIXEL;
|
||||
}
|
||||
dst[3] = 0;
|
||||
}else{
|
||||
if(c % cdimx == 0 && l % cdimy == 0){
|
||||
tam[tyx].state = SPRIXCELL_OPAQUE_SIXEL;
|
||||
}else if(tam[tyx].state == SPRIXCELL_TRANSPARENT){
|
||||
tam[tyx].state = SPRIXCELL_MIXED_SIXEL;
|
||||
n->tam[tyx].state = SPRIXCELL_OPAQUE_SIXEL;
|
||||
}else if(n->tam[tyx].state == SPRIXCELL_TRANSPARENT){
|
||||
n->tam[tyx].state = SPRIXCELL_MIXED_SIXEL;
|
||||
}
|
||||
memcpy(dst + 3, src + 3, 1);
|
||||
}
|
||||
@ -103,16 +86,13 @@ int fbcon_blit(struct ncplane* n, int linesize, const void* data,
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
scrub_tam_boundaries(tam, leny, lenx, cdimy, cdimx);
|
||||
if(plane_blit_sixel(s, &s->glyph, leny, lenx, 0, tam, SPRIXEL_INVALIDATED) < 0){
|
||||
scrub_tam_boundaries(n->tam, leny, lenx, cdimy, cdimx);
|
||||
if(plane_blit_sixel(s, &s->glyph, leny, lenx, 0, n->tam, SPRIXEL_INVALIDATED) < 0){
|
||||
goto error;
|
||||
}
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if(!reuse){
|
||||
free(tam);
|
||||
}
|
||||
fbuf_free(&s->glyph);
|
||||
s->glyph.size = 0;
|
||||
return -1;
|
||||
|
@ -911,38 +911,16 @@ int sixel_blit(ncplane* n, int linesize, const void* data, int leny, int lenx,
|
||||
memset(stable.deets, 0, sizeof(*stable.deets) * colorregs);
|
||||
int cols = bargs->u.pixel.spx->dimx;
|
||||
int rows = bargs->u.pixel.spx->dimy;
|
||||
tament* tam = 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.
|
||||
if(n->tam){
|
||||
if(n->leny == rows && n->lenx == cols){
|
||||
tam = n->tam;
|
||||
reuse = true;
|
||||
}
|
||||
typeof(bargs->u.pixel.spx->needs_refresh) rmatrix;
|
||||
rmatrix = malloc(sizeof(*rmatrix) * rows * cols);
|
||||
if(rmatrix == NULL){
|
||||
sixelmap_free(stable.map);
|
||||
free(stable.deets);
|
||||
return -1;
|
||||
}
|
||||
if(!reuse){
|
||||
tam = malloc(sizeof(*tam) * rows * cols);
|
||||
if(tam == NULL){
|
||||
sixelmap_free(stable.map);
|
||||
free(stable.deets);
|
||||
return -1;
|
||||
}
|
||||
memset(tam, 0, sizeof(*tam) * rows * cols);
|
||||
}else{
|
||||
typeof(bargs->u.pixel.spx->needs_refresh) rmatrix;
|
||||
rmatrix = malloc(sizeof(*rmatrix) * rows * cols);
|
||||
if(rmatrix == NULL){
|
||||
sixelmap_free(stable.map);
|
||||
free(stable.deets);
|
||||
return -1;
|
||||
}
|
||||
bargs->u.pixel.spx->needs_refresh = rmatrix;
|
||||
}
|
||||
if(extract_color_table(data, linesize, cols, leny, lenx, &stable, tam, bargs)){
|
||||
if(!reuse){
|
||||
free(tam);
|
||||
}
|
||||
bargs->u.pixel.spx->needs_refresh = rmatrix;
|
||||
assert(n->tam);
|
||||
if(extract_color_table(data, linesize, cols, leny, lenx, &stable, n->tam, bargs)){
|
||||
free(bargs->u.pixel.spx->needs_refresh);
|
||||
sixelmap_free(stable.map);
|
||||
free(stable.deets);
|
||||
@ -950,7 +928,7 @@ int sixel_blit(ncplane* n, int linesize, const void* data, int leny, int lenx,
|
||||
}
|
||||
refine_color_table(data, linesize, bargs->begy, bargs->begx, leny, lenx, &stable);
|
||||
// takes ownership of sixelmap on success
|
||||
int r = sixel_blit_inner(leny, lenx, &stable, bargs->u.pixel.spx, tam);
|
||||
int r = sixel_blit_inner(leny, lenx, &stable, bargs->u.pixel.spx, n->tam);
|
||||
if(r < 0){
|
||||
sixelmap_free(stable.map);
|
||||
}
|
||||
|
@ -930,6 +930,15 @@ make_sprixel_plane(notcurses* nc, ncplane* parent, ncvisual* ncv,
|
||||
return n;
|
||||
}
|
||||
|
||||
static tament*
|
||||
create_tam(int rows, int cols){
|
||||
tament* tam = malloc(sizeof(*tam) * rows * cols);
|
||||
if(tam){
|
||||
memset(tam, 0, sizeof(*tam) * rows * cols);
|
||||
}
|
||||
return tam;
|
||||
}
|
||||
|
||||
// when a sprixel is blitted to a plane, that plane becomes a sprixel plane. it
|
||||
// must not be used with other output mechanisms unless erased. the plane will
|
||||
// be shrunk to fit the output, and the output is always placed at the origin.
|
||||
@ -1010,15 +1019,28 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits
|
||||
bargs.lenx = lenx;
|
||||
bargs.flags = flags;
|
||||
bargs.u.pixel.colorregs = nc->tcache.color_registers;
|
||||
int cols = disppixx / nc->tcache.cellpixx + !!(disppixx % nc->tcache.cellpixx);
|
||||
int rows = outy / nc->tcache.cellpixy + !!(outy % nc->tcache.cellpixy);
|
||||
if(n->sprite == NULL){
|
||||
int cols = disppixx / nc->tcache.cellpixx + !!(disppixx % nc->tcache.cellpixx);
|
||||
int rows = outy / nc->tcache.cellpixy + !!(outy % nc->tcache.cellpixy);
|
||||
if((n->sprite = sprixel_alloc(&nc->tcache, n, rows, cols)) == NULL){
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;
|
||||
}
|
||||
if((n->tam = create_tam(rows, cols)) == NULL){
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;;
|
||||
}
|
||||
}else{
|
||||
n->sprite = sprixel_recycle(n);
|
||||
if(n->sprite->dimy != rows || n->sprite->dimx != cols){
|
||||
free(n->tam);
|
||||
if((n->tam = create_tam(rows, cols)) == NULL){
|
||||
ncplane_destroy(createdn);
|
||||
return NULL;;
|
||||
}
|
||||
}
|
||||
n->sprite->dimx = cols;
|
||||
n->sprite->dimy = rows;
|
||||
}
|
||||
bargs.u.pixel.spx = n->sprite;
|
||||
// FIXME need to pull off the ncpile's sprixellist if anything below fails!
|
||||
|
Loading…
Reference in New Issue
Block a user