mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
[sixel] reproduce surgery map #1457
This commit is contained in:
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…
x
Reference in New Issue
Block a user