[sixel] reproduce surgery map #1457

pull/1480/head
nick black 3 years ago committed by Nick Black
parent 6907562c9c
commit 51182e3315

@ -238,7 +238,6 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
int totalout = 0; // total pixels of payload out int totalout = 0; // total pixels of payload out
int y = 0; // position within source image (pixels) int y = 0; // position within source image (pixels)
int x = 0; int x = 0;
int tyx = 0; // postition within tamatrix (cells)
int targetout = 0; // number of pixels expected out after this chunk int targetout = 0; // number of pixels expected out after this chunk
//fprintf(stderr, "total: %d chunks = %d, s=%d,v=%d\n", total, chunks, lenx, leny); //fprintf(stderr, "total: %d chunks = %d, s=%d,v=%d\n", total, chunks, lenx, leny);
while(chunks--){ while(chunks--){
@ -261,26 +260,17 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx, int cols,
for(int e = 0 ; e < encodeable ; ++e){ for(int e = 0 ; e < encodeable ; ++e){
if(x == lenx){ if(x == lenx){
x = 0; x = 0;
if(x % cdimx){ ++y;
++tyx;
}
if(++y % cdimy){
tyx -= cols;
}
} }
const uint32_t* line = data + (linesize / sizeof(*data)) * y; const uint32_t* line = data + (linesize / sizeof(*data)) * y;
source[e] = line[x]; source[e] = line[x];
//fprintf(stderr, "%u/%u/%u -> %c%c%c%c %u %u %u %u\n", r, g, b, b64[0], b64[1], b64[2], b64[3], b64[0], b64[1], b64[2], b64[3]); //fprintf(stderr, "%u/%u/%u -> %c%c%c%c %u %u %u %u\n", r, g, b, b64[0], b64[1], b64[2], b64[3], b64[0], b64[1], b64[2], b64[3]);
if(++x % cdimx == 0){ ++x;
++tyx; int tyx = (x / cdimx) + (y / cdimy) * cols;
}
wipe[e] = (tacache[tyx] == SPRIXCELL_ANNIHILATED); wipe[e] = (tacache[tyx] == SPRIXCELL_ANNIHILATED);
} }
totalout += encodeable; totalout += encodeable;
char out[17]; char out[17];
if(wipe[0] || wipe[1] || wipe[2]){
fprintf(stderr, "TYX: %d lenx: %d y: %d x: %d %d %d %d\n", tyx, lenx, y, x, wipe[0], wipe[1], wipe[2]);
}
base64_rgba3(source, encodeable, out, wipe); base64_rgba3(source, encodeable, out, wipe);
ncfputs(out, fp); ncfputs(out, fp);
} }

@ -926,23 +926,7 @@ int sprite_sixel_annihilate(const notcurses* nc, const ncpile* p, FILE* out, spr
(void)p; (void)p;
(void)out; (void)out;
(void)s; (void)s;
/* return 0;
struct crender* rvec = p->crender;
// FIXME need to cap by ends minus bottom, right margins also
const int ycap = nc->stdplane->leny + nc->margin_t;
const int xcap = nc->stdplane->lenx + nc->margin_l;
//fprintf(stderr, "yCAP: %d xCAP: %d\n", ycap, xcap);
for(int y = s->y + nc->stdplane->absy ; y < s->y + nc->stdplane->absy + s->dimy && y < ycap ; ++y){
const int innery = y - nc->stdplane->absy;
for(int x = s->x + nc->stdplane->absx ; x < s->x + nc->stdplane->absx + s->dimx && x < xcap ; ++x){
const int innerx = x - nc->stdplane->absx;
const size_t damageidx = innery * nc->lfdimx + innerx;
//fprintf(stderr, "DAMAGING %zu %d * %d + %d (max %d/%d)\n", damageidx, innery, nc->lfdimx, innerx, ycap, xcap);
rvec[damageidx].s.damaged = 1;
}
}
*/
return 1;
} }
// returns -1 on error, 0 on success, 1 on success + invalidations requiring // returns -1 on error, 0 on success, 1 on success + invalidations requiring

@ -245,18 +245,24 @@ update_deets(uint32_t rgb, cdetails* deets){
// (assumed to have at least 256 registers). at each color, we store a pixel // (assumed to have at least 256 registers). at each color, we store a pixel
// count, and a sum of all three channels. in addition, we track whether we've // count, and a sum of all three channels. in addition, we track whether we've
// seen at least two colors in the chunk. // seen at least two colors in the chunk.
static int static inline int
extract_color_table(const uint32_t* data, int linesize, int begy, int begx, extract_color_table(const uint32_t* data, int linesize, int begy, int begx, int cols,
int leny, int lenx, sixeltable* stab){ int leny, int lenx, int cdimy, int cdimx, sixeltable* stab,
sprixcell_e* tacache){
unsigned char mask = 0xc0; unsigned char mask = 0xc0;
int pos = 0; int pos = 0;
for(int visy = begy ; visy < (begy + leny) ; visy += 6){ for(int visy = begy ; visy < (begy + leny) ; visy += 6){ // pixel row
for(int visx = begx ; visx < (begx + lenx) ; visx += 1){ for(int visx = begx ; visx < (begx + lenx) ; visx += 1){ // pixel column
for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){ for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){ // offset within sprixel
const uint32_t* rgb = (const uint32_t*)(data + (linesize / 4 * sy) + visx); const uint32_t* rgb = (data + (linesize / 4 * sy) + visx);
if(rgba_trans_p(ncpixel_a(*rgb))){ if(rgba_trans_p(ncpixel_a(*rgb))){
continue; continue;
} }
int txyidx = (sy / cdimy) * cols + (visx / cdimx);
if(tacache[txyidx] == SPRIXCELL_ANNIHILATED){
//fprintf(stderr, "TRANS SKIP %d %d %d %d\n", visy, visx, sy, txyidx);
continue;
}
unsigned char comps[RGBSIZE]; unsigned char comps[RGBSIZE];
break_sixel_comps(comps, *rgb, mask); break_sixel_comps(comps, *rgb, mask);
int c = find_color(stab, comps); int c = find_color(stab, comps);
@ -416,7 +422,7 @@ write_rle(int* printed, int color, FILE* fp, int seenrle, unsigned char crle){
// Emit the sprixel in its entirety, plus enable and disable pixel mode. // Emit the sprixel in its entirety, plus enable and disable pixel mode.
// Closes |fp| on all paths. // Closes |fp| on all paths.
static int static int
write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start, sprixcell_e* tacache){ write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start){
*parse_start = fprintf(fp, "\ePq"); *parse_start = fprintf(fp, "\ePq");
// Set Raster Attributes - pan/pad=1 (pixel aspect ratio), Ph=lenx, Pv=leny // Set Raster Attributes - pan/pad=1 (pixel aspect ratio), Ph=lenx, Pv=leny
// using Ph/Pv causes a background to be drawn using color register 0 for all // using Ph/Pv causes a background to be drawn using color register 0 for all
@ -435,7 +441,6 @@ write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start, sprixce
(intmax_t)(stab->deets[idx].sums[2] * 100 / count / 255)); (intmax_t)(stab->deets[idx].sums[2] * 100 / count / 255));
} }
int p = 0; int p = 0;
(void)tacache; // FIXME fill in tacache when we hit transparencies
while(p < stab->sixelcount){ while(p < stab->sixelcount){
for(int i = 0 ; i < stab->colors ; ++i){ for(int i = 0 ; i < stab->colors ; ++i){
int printed = 0; int printed = 0;
@ -486,8 +491,10 @@ write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start, sprixce
// are programmed as a set of registers, which are then referenced by the // are programmed as a set of registers, which are then referenced by the
// stacks. There is also a RLE component, handled in rasterization. // stacks. There is also a RLE component, handled in rasterization.
// A pixel block is indicated by setting cell_pixels_p(). // A pixel block is indicated by setting cell_pixels_p().
int sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab, static inline int
const blitterargs* bargs){ sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab,
const blitterargs* bargs, unsigned reuse,
sprixcell_e* tacache){
char* buf = NULL; char* buf = NULL;
size_t size = 0; size_t size = 0;
FILE* fp = open_memstream(&buf, &size); FILE* fp = open_memstream(&buf, &size);
@ -497,31 +504,8 @@ int sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab,
int parse_start = 0; int parse_start = 0;
int cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx); int cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx);
int rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy); int rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy);
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.
if(n->sprite){
sprixel* s = n->sprite;
if(s->dimy == rows && s->dimx == cols){
tacache = s->tacache;
reuse = true;
}
}
if(!reuse){
tacache = malloc(sizeof(*tacache) * rows * cols);
if(tacache == NULL){
fclose(fp);
free(buf);
return -1;
}
memset(tacache, 0, sizeof(*tacache) * rows * cols);
}
// calls fclose() on success // calls fclose() on success
if(write_sixel_data(fp, lenx, stab, &parse_start, tacache)){ if(write_sixel_data(fp, lenx, stab, &parse_start)){
if(!reuse){
free(tacache);
}
free(buf); free(buf);
return -1; return -1;
} }
@ -532,7 +516,6 @@ int sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab,
if(plane_blit_sixel(n, 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(buf); free(buf);
return -1; return -1;
} }
@ -567,14 +550,39 @@ int sixel_blit(ncplane* n, int linesize, const void* data,
// stable.table doesn't need initializing; we start from the bottom // stable.table doesn't need initializing; we start from the bottom
memset(stable.data, 0, sixelcount * colorregs); memset(stable.data, 0, sixelcount * colorregs);
memset(stable.deets, 0, sizeof(*stable.deets) * colorregs); memset(stable.deets, 0, sizeof(*stable.deets) * colorregs);
if(extract_color_table(data, linesize, bargs->begy, bargs->begx, leny, lenx, &stable)){ int cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx);
int rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy);
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.
if(n->sprite){
sprixel* s = n->sprite;
if(s->dimy == rows && s->dimx == cols){
tacache = s->tacache;
reuse = true;
}
}
if(!reuse){
tacache = malloc(sizeof(*tacache) * rows * cols);
if(tacache == NULL){
return -1;
}
memset(tacache, 0, sizeof(*tacache) * rows * cols);
}
if(extract_color_table(data, linesize, bargs->begy, bargs->begx, cols, leny, lenx,
bargs->u.pixel.celldimy, bargs->u.pixel.celldimx,
&stable, tacache)){
if(!reuse){
free(tacache);
}
free(stable.table); free(stable.table);
free(stable.data); free(stable.data);
free(stable.deets); free(stable.deets);
return -1; return -1;
} }
refine_color_table(data, linesize, bargs->begy, bargs->begx, leny, lenx, &stable); refine_color_table(data, linesize, bargs->begy, bargs->begx, leny, lenx, &stable);
int r = sixel_blit_inner(n, leny, lenx, &stable, bargs); int r = sixel_blit_inner(n, leny, lenx, &stable, bargs, reuse, tacache);
free(stable.data); free(stable.data);
free(stable.deets); free(stable.deets);
free(stable.table); free(stable.table);

Loading…
Cancel
Save