From f089f1e83357c14250facc05692d9b0084e3e27c Mon Sep 17 00:00:00 2001 From: nick black Date: Wed, 28 Oct 2020 08:06:11 -0400 Subject: [PATCH] pipe rgbas throughout sexblitter --- src/lib/blit.c | 96 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/src/lib/blit.c b/src/lib/blit.c index 01774e6bb..163ed5fef 100644 --- a/src/lib/blit.c +++ b/src/lib/blit.c @@ -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);