pipe rgbas throughout sexblitter

This commit is contained in:
nick black 2020-10-28 08:06:11 -04:00 committed by Nick Black
parent 9328bdce43
commit f089f1e833

View File

@ -490,35 +490,73 @@ collect_diffs(unsigned* diff, unsigned bitstring, const uint32_t* rgba1,
return false;
}
// if the candidate diff is less than the minimum diff, update mindiffidx.
// if the candidate diff is equal to the minimum diff, add bits to
// *mindiffbits. FIXME need compare actual values for equality, not just
// diffs, on equal diff. if diffs are equal, but not values, need to track 2
// (since we can find 3 with diff of D0, val of V1 after finding 2 with diff
// of D0, val of V0).
// if the candidate diff is less than the minimum diff, update |mindiffidx|,
// and reset |*mindiffbits|. if the candidate diff is equal to the minimum
// diff, add bits to |*mindiffbits|.
static inline void
collect_mindiff(unsigned* mindiffidx, const unsigned diffs[15],
unsigned candidate, unsigned *mindiffbits){
unsigned candidate, unsigned *mindiffbits,
const uint32_t* rgbas[6]){
static unsigned mindiffkeys[15] = {
0x3, 0x5, 0x9, 0x11, 0x21,
0x6, 0xa, 0x12, 0x22, 0xc,
0x14, 0x24, 0x18, 0x28, 0x30,
};
if(diffs[candidate] <= diffs[*mindiffidx]){
*mindiffbits |= mindiffkeys[candidate];
if(diffs[candidate] < diffs[*mindiffidx]){
*mindiffidx = candidate;
*mindiffbits = mindiffkeys[candidate];
}else{
uint32_t lowestkey;
for(size_t i = 0 ; i < 6 ; ++i){
if(mindiffkeys[candidate] & (0x1 << i)){
lowestkey = *rgbas[i];
break;
}
}
uint32_t lowestcur;
for(size_t i = 0 ; i < 6 ; ++i){
if((i != lowestkey) && (*mindiffbits & (0x1 << i))){
lowestcur = *rgbas[i];
break;
}
}
if(memcmp(&lowestcur, &lowestkey, 3) == 0){
*mindiffbits |= mindiffkeys[candidate];
}
// FIXME if diff was equal, but values are different, need to track 2
// (since we can find 3 with diff of D0, val of V1 after finding 2 with
// diff of D0, val of V0).
}
}
}
// pick the foreground color based off lerping mindiffbits,
static void
get_sex_colors(uint32_t* fg, uint32_t* bg, unsigned mindiffbits,
unsigned r, unsigned g, unsigned b, unsigned div){
// FIXME need ingest actual rgbas to drop from sums
*fg = ((r / div) << 16) + ((g / div) << 8) + (b / div);
*bg = *fg;
get_sex_colors(uint32_t* fg, uint32_t* bg, bool bgr, unsigned mindiffbits,
unsigned r, unsigned g, unsigned b, unsigned div,
const uint32_t* rgbas[6]){
// FIXME fg lerps mindiffbits
uint32_t fgcs[2];
size_t i = 0;
//fprintf(stderr, "start r: %u g: %u b: %u div: %u midbs: %02x\n", r, g, b, div, mindiffbits);
for(unsigned shift = 0 ; shift < 6 ; ++shift){
if(mindiffbits & (1u << shift)){
// FIXME verify this
if(i < sizeof(fgcs) / sizeof(*fgcs)){
fgcs[i++] = *rgbas[shift];
}
const int rpos = bgr ? 2 : 0;
const int bpos = bgr ? 0 : 2;
r -= ((const uint8_t*)rgbas[shift])[rpos];
g -= ((const uint8_t*)rgbas[shift])[1];
b -= ((const uint8_t*)rgbas[shift])[bpos];
--div;
}
}
*fg = lerp(fgcs[0], fgcs[1]);
//fprintf(stderr, "r: %u g: %u b: %u div: %u\n", r, g, b, div);
*bg = ((r / div) << 16) + ((g / div) << 8) + (b / div);
}
static const char* sex[64] = {
@ -565,43 +603,43 @@ strans_check(uint64_t* channels, bool bgr, bool blendcolors, unsigned diffs[15],
unsigned mindiffidx = 0;
strans_fold(&transtring, 4u, rgbas[2], bgr, &r, &g, &b, &div);
allzerodiffs &= collect_diffs(&diffs[1], transtring, rgbas[2], 4u, rgbas[0], 1u);
collect_mindiff(&mindiffidx, diffs, 1, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 1, &mindiffbits, rgbas);
allzerodiffs &= collect_diffs(&diffs[5], transtring, rgbas[2], 4u, rgbas[1], 2u);
collect_mindiff(&mindiffidx, diffs, 5, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 5, &mindiffbits, rgbas);
strans_fold(&transtring, 8u, rgbas[3], bgr, &r, &g, &b, &div);
allzerodiffs &= collect_diffs(&diffs[2], transtring, rgbas[3], 8u, rgbas[0], 1u);
allzerodiffs &= collect_diffs(&diffs[6], transtring, rgbas[3], 8u, rgbas[1], 2u);
allzerodiffs &= collect_diffs(&diffs[9], transtring, rgbas[3], 8u, rgbas[2], 4u);
collect_mindiff(&mindiffidx, diffs, 2, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 6, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 9, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 2, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 6, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 9, &mindiffbits, rgbas);
strans_fold(&transtring, 16u, rgbas[4], bgr, &r, &g, &b, &div);
allzerodiffs &= collect_diffs(&diffs[3], transtring, rgbas[4], 16u, rgbas[0], 1u);
allzerodiffs &= collect_diffs(&diffs[7], transtring, rgbas[4], 16u, rgbas[1], 2u);
allzerodiffs &= collect_diffs(&diffs[10], transtring, rgbas[4], 16u, rgbas[2], 4u);
allzerodiffs &= collect_diffs(&diffs[12], transtring, rgbas[4], 16u, rgbas[3], 8u);
collect_mindiff(&mindiffidx, diffs, 3, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 7, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 10, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 12, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 3, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 7, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 10, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 12, &mindiffbits, rgbas);
strans_fold(&transtring, 32u, rgbas[5], bgr, &r, &g, &b, &div);
allzerodiffs &= collect_diffs(&diffs[4], transtring, rgbas[5], 32u, rgbas[0], 1u);
allzerodiffs &= collect_diffs(&diffs[8], transtring, rgbas[5], 32u, rgbas[1], 2u);
allzerodiffs &= collect_diffs(&diffs[11], transtring, rgbas[5], 32u, rgbas[2], 4u);
allzerodiffs &= collect_diffs(&diffs[13], transtring, rgbas[5], 32u, rgbas[3], 8u);
allzerodiffs &= collect_diffs(&diffs[14], transtring, rgbas[5], 32u, rgbas[4], 16u);
collect_mindiff(&mindiffidx, diffs, 4, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 8, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 11, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 13, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 14, &mindiffbits);
collect_mindiff(&mindiffidx, diffs, 4, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 8, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 11, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 13, &mindiffbits, rgbas);
collect_mindiff(&mindiffidx, diffs, 14, &mindiffbits, rgbas);
if(!transtring){ // no transparency. use complex solver unless all are equal.
if(allzerodiffs){ // every diff was 0, so all must be the same rgb value.
channels_set_bg_rgb8(channels, r / div, g / div, b / div);
return " ";
}
uint32_t fg, bg;
get_sex_colors(&fg, &bg, mindiffbits, r, g, b, div);
get_sex_colors(&fg, &bg, bgr, mindiffbits, r, g, b, div, rgbas);
channels_set_fg_rgb(channels, fg);
channels_set_bg_rgb(channels, bg);
return sex[mindiffbits];
@ -631,8 +669,6 @@ sextant_blit(ncplane* nc, int placey, int placex, int linesize,
const void* data, int begy, int begx,
int leny, int lenx, bool bgr, bool blendcolors){
const int bpp = 32;
const int rpos = bgr ? 2 : 0;
const int bpos = bgr ? 0 : 2;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);