[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 y = 0; // position within source image (pixels)
int x = 0;
int tyx = 0; // postition within tamatrix (cells)
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);
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){
if(x == lenx){
x = 0;
if(x % cdimx){
++tyx;
}
if(++y % cdimy){
tyx -= cols;
}
++y;
}
const uint32_t* line = data + (linesize / sizeof(*data)) * y;
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]);
if(++x % cdimx == 0){
++tyx;
}
++x;
int tyx = (x / cdimx) + (y / cdimy) * cols;
wipe[e] = (tacache[tyx] == SPRIXCELL_ANNIHILATED);
}
totalout += encodeable;
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);
ncfputs(out, fp);
}

@ -926,23 +926,7 @@ int sprite_sixel_annihilate(const notcurses* nc, const ncpile* p, FILE* out, spr
(void)p;
(void)out;
(void)s;
/*
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;
return 0;
}
// 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
// count, and a sum of all three channels. in addition, we track whether we've
// seen at least two colors in the chunk.
static int
extract_color_table(const uint32_t* data, int linesize, int begy, int begx,
int leny, int lenx, sixeltable* stab){
static inline int
extract_color_table(const uint32_t* data, int linesize, int begy, int begx, int cols,
int leny, int lenx, int cdimy, int cdimx, sixeltable* stab,
sprixcell_e* tacache){
unsigned char mask = 0xc0;
int pos = 0;
for(int visy = begy ; visy < (begy + leny) ; visy += 6){
for(int visx = begx ; visx < (begx + lenx) ; visx += 1){
for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){
const uint32_t* rgb = (const uint32_t*)(data + (linesize / 4 * sy) + visx);
for(int visy = begy ; visy < (begy + leny) ; visy += 6){ // pixel row
for(int visx = begx ; visx < (begx + lenx) ; visx += 1){ // pixel column
for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){ // offset within sprixel
const uint32_t* rgb = (data + (linesize / 4 * sy) + visx);
if(rgba_trans_p(ncpixel_a(*rgb))){
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];
break_sixel_comps(comps, *rgb, mask);
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.
// Closes |fp| on all paths.
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");
// 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
@ -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));
}
int p = 0;
(void)tacache; // FIXME fill in tacache when we hit transparencies
while(p < stab->sixelcount){
for(int i = 0 ; i < stab->colors ; ++i){
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
// stacks. There is also a RLE component, handled in rasterization.
// A pixel block is indicated by setting cell_pixels_p().
int sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab,
const blitterargs* bargs){
static inline int
sixel_blit_inner(ncplane* n, int leny, int lenx, sixeltable* stab,
const blitterargs* bargs, unsigned reuse,
sprixcell_e* tacache){
char* buf = NULL;
size_t size = 0;
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 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){
fclose(fp);
free(buf);
return -1;
}
memset(tacache, 0, sizeof(*tacache) * rows * cols);
}
// calls fclose() on success
if(write_sixel_data(fp, lenx, stab, &parse_start, tacache)){
if(!reuse){
free(tacache);
}
if(write_sixel_data(fp, lenx, stab, &parse_start)){
free(buf);
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,
rows, cols, bargs->u.pixel.sprixelid, leny, lenx,
parse_start, tacache) < 0){
free(tacache);
free(buf);
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
memset(stable.data, 0, sixelcount * 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.data);
free(stable.deets);
return -1;
}
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.deets);
free(stable.table);

Loading…
Cancel
Save