diff --git a/src/lib/kitty.c b/src/lib/kitty.c index 9d1fe1d3d..a3f016973 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -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; } diff --git a/src/lib/linux.c b/src/lib/linux.c index 17fecf4e1..76cc8278d 100644 --- a/src/lib/linux.c +++ b/src/lib/linux.c @@ -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; diff --git a/src/lib/sixel.c b/src/lib/sixel.c index f7ccc3b4d..5261bdfdd 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -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); } diff --git a/src/lib/visual.c b/src/lib/visual.c index f5ef6a506..b8bff6d37 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -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!