kitty animation: everything up through rebuild works #1895

dankamongmen/linuxfbdumb
nick black 3 years ago committed by Nick Black
parent af305f56c4
commit b9b26603ad

@ -355,14 +355,28 @@ int kitty_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec){
// an animation auxvec requires storing all the pixel data for the cell,
// instead of just the alpha channel. pass the start of the RGBA to be
// copied, and the rowstride.
// copied, and the rowstride. dimy and dimx are the source image's total
// size in pixels. posy and posx are the origin of the cell to be copied,
// again in pixels. data is the image source. around the edges, we might
// get truncated regions.
static inline uint8_t*
kitty_transanim_auxvec(int cellpxy, int cellpxx, const uint32_t* data, int rowstride){
kitty_transanim_auxvec(int dimy, int dimx, int posy, int posx,
int cellpxy, int cellpxx,
const uint32_t* data, int rowstride){
const size_t slen = 4 * cellpxy * cellpxx;
uint8_t* a = malloc(slen);
if(a){
for(int y = 0 ; y < cellpxy ; ++y){
memcpy(a + y * (cellpxx * 4), data + y * (rowstride / 4), cellpxx * 4);
for(int y = posy ; y < posy + cellpxy && y < dimy ; ++y){
int pixels = cellpxx;
if(pixels + posx > dimx){
pixels = dimx - posx;
}
logtrace("Copying %d (%d) from %p to %p\n", pixels * 4, y,
data + posy * (rowstride / 4) + posx,
a + (y - posy) * (pixels * 4));
memcpy(a + (y - posy) * (pixels * 4),
data + posy * (rowstride / 4) + posx,
pixels * 4);
}
}
return a;
@ -518,7 +532,6 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
//fprintf(stderr, "drawing kitty %p\n", tam);
if(linesize % sizeof(*data)){
logerror("Stride (%d) badly aligned\n", linesize);
fclose(fp);
return -1;
}
bool translucent = bargs->flags & NCVISUAL_OPTION_BLEND;
@ -566,8 +579,9 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
int ycell = y / cdimy;
int tyx = xcell + ycell * cols;
if(tam[tyx].auxvector == NULL){
if((tam[tyx].auxvector = kitty_transanim_auxvec(cdimy, cdimx, line + x, linesize)) == NULL){
fclose(fp);
if((tam[tyx].auxvector = kitty_transanim_auxvec(leny, lenx, y, x,
cdimy, cdimx,
data, linesize)) == NULL){
goto err;
}
}
@ -604,9 +618,6 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
}
fprintf(fp, "\e\\");
}
if(fclose(fp) == EOF){
goto err;
}
scrub_tam_boundaries(tam, leny, lenx, cdimy, cdimx);
return 0;
@ -620,12 +631,11 @@ err:
// deflate-compressed) 24bit RGB. Returns -1 on error, 1 on success.
int kitty_blit_core(ncplane* n, int linesize, const void* data, int leny, int lenx,
const blitterargs* bargs, int bpp __attribute__ ((unused))){
//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;
char* buf = NULL;
size_t size = 0;
FILE* fp = open_memstream(&buf, &size);
if(fp == NULL){
sprixel* s = bargs->u.pixel.spx;
if(init_sprixel_animation(s)){
return -1;
}
tament* tam = NULL;
@ -642,30 +652,33 @@ int kitty_blit_core(ncplane* n, int linesize, const void* data, int leny, int le
if(!reuse){
tam = malloc(sizeof(*tam) * rows * cols);
if(tam == NULL){
fclose(fp);
free(buf);
fclose(s->mstreamfp);
free(s->glyph);
return -1;
}
memset(tam, 0, sizeof(*tam) * rows * cols);
}
// closes fp on all paths
if(write_kitty_data(fp, linesize, leny, lenx, cols, data, bargs, tam, &parse_start)){
if(!reuse){
free(tam);
}
free(buf);
return -1;
if(write_kitty_data(s->mstreamfp, linesize, leny, lenx, cols, data,
bargs, tam, &parse_start)){
goto error;
}
// take ownership of |buf| and |tam| on success
if(plane_blit_sixel(bargs->u.pixel.spx, buf, size,
leny, lenx, parse_start, tam) < 0){
if(!reuse){
free(tam);
}
free(buf);
return -1;
/*if(ncflush(s->mstreamfp)){
goto error;
}*/
// take ownership of |buf| and |tam| on success.
if(plane_blit_sixel(s, s->glyph, s->glyphlen, leny, lenx, parse_start, tam) < 0){
goto error;
}
return 1;
error:
fclose(s->mstreamfp);
if(!reuse){
free(tam);
}
free(s->glyph);
return -1;
}
int kitty_blit(ncplane* n, int linesize, const void* data, int leny, int lenx,
@ -731,6 +744,7 @@ int kitty_draw(const ncpile* p, sprixel* s, FILE* out){
animated = true;
}
int ret = s->glyphlen;
logdebug("Writing out %zub for %u\n", s->glyphlen, s->id);
if(ret){
if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){
ret = -1;
@ -740,7 +754,8 @@ int kitty_draw(const ncpile* p, sprixel* s, FILE* out){
free(s->glyph);
s->glyph = NULL;
s->glyphlen = 0;
s->invalidated = SPRIXEL_QUIESCENT;
//s->invalidated = SPRIXEL_QUIESCENT;
s->invalidated = SPRIXEL_LOADED;
}else{
s->invalidated = SPRIXEL_LOADED;
}

@ -178,9 +178,11 @@ int sprite_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell){
if(s->n->tam[idx].state == SPRIXCELL_TRANSPARENT){
// need to make a transparent auxvec, because a reload will force us to
// update said auxvec.
s->n->tam[idx].auxvector = nc->tcache.pixel_trans_auxvec(&nc->tcache);
if(s->n->tam[idx].auxvector == NULL){
return -1;
s->n->tam[idx].auxvector = nc->tcache.pixel_trans_auxvec(&nc->tcache);
if(s->n->tam[idx].auxvector == NULL){
return -1;
}
}
s->n->tam[idx].state = SPRIXCELL_ANNIHILATED_TRANS;
return 1;

Loading…
Cancel
Save