Skip to content

Commit

Permalink
[quantization] use clumpbyte for o(1) color lookup in first pass #2503
Browse files Browse the repository at this point in the history
  • Loading branch information
dankamongmen committed Dec 28, 2021
1 parent df1d815 commit 6ec660a
Showing 1 changed file with 16 additions and 60 deletions.
76 changes: 16 additions & 60 deletions src/lib/sixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,56 +319,12 @@ scrub_color_table(sprixel* s){
// color is not in the table and the table is full. returns the proper
// dtable index (*not* color index) otherwise.
static int
find_color(sixeltable* stab, unsigned char comps[static RGBSIZE]){
int i;
if(stab->map->colors){
int l, r;
// binary search over memcmp()-ordered color table
l = 0;
r = stab->map->colors - 1;
do{
i = l + (r - l) / 2;
const unsigned char* cmpie = stab->map->table + i * CENTSIZE;
//fprintf(stderr, " %u/%u/%u %u/%u/%u L %d R %d m %d\n", comps[0], comps[1], comps[2], cmpie[0], cmpie[1], cmpie[2], l, r, i);
int cmp = memcmp(cmpie, comps, RGBSIZE);
if(cmp == 0){
return ctable_to_dtable(cmpie);
}
if(cmp < 0){
l = i + 1;
}else{ // key is smaller
r = i - 1;
}
//fprintf(stderr, " BCMP: %d L %d R %d m: %d\n", cmp, l, r, i);
}while(l <= r);
if(r < 0){
i = 0;
}else if(l == stab->map->colors){
i = stab->map->colors;
}else{
i = l;
}
if(stab->map->colors == stab->colorregs){
return -1;
}
if(i < stab->map->colors){
//fprintf(stderr, "INSERTING COLOR %u %u %u AT %d\n", comps[0], comps[1], comps[2], i);
memmove(stab->map->table + (i + 1) * CENTSIZE,
stab->map->table + i * CENTSIZE,
(stab->map->colors - i) * CENTSIZE);
}
}else{
i = 0;
}
//fprintf(stderr, "NEW COLOR CONCAT %u %u %u AT %d\n", comps[0], comps[1], comps[2], i);
memcpy(stab->map->table + i * CENTSIZE, comps, RGBSIZE);
dtable_to_ctable(stab->map->colors, stab->map->table + i * CENTSIZE);
++stab->map->colors;
return stab->map->colors - 1;
//return ctable_to_dtable(stab->map->table + i * CENTSIZE);
find_color(sixeltable* stab, unsigned char key){
dtable_to_ctable(stab->map->colors, stab->map->table + key * CENTSIZE);
return ctable_to_dtable(stab->map->table + key * CENTSIZE);
}

static void
static int32_t
update_deets(uint32_t rgb, cdetails* deets){
unsigned char comps[RGBSIZE];
deets->sums[0] += ncpixel_r(rgb);
Expand Down Expand Up @@ -398,7 +354,7 @@ update_deets(uint32_t rgb, cdetails* deets){
deets->lo[2] = comps[2];
}
}
++deets->count;
return ++deets->count;
}

// goes through the needs_refresh matrix, and damages cells needing refreshing.
Expand Down Expand Up @@ -456,7 +412,6 @@ extract_color_table(const uint32_t* data, int linesize, int cols,
const int begy = bargs->begy;
const int cdimy = bargs->u.pixel.cellpxy;
const int cdimx = bargs->u.pixel.cellpxx;
const uint32_t mask = 0xe0c0e0;
int pos = 0; // pixel position
unsigned char* rmatrix = bargs->u.pixel.spx->needs_refresh;
for(int visy = begy ; visy < (begy + leny) ; visy += 6){ // pixel row
Expand Down Expand Up @@ -521,17 +476,18 @@ extract_color_table(const uint32_t* data, int linesize, int cols,
if(rgba_trans_p(*rgb, bargs->transcolor)){
continue;
}
unsigned char comps[RGBSIZE];
break_sixel_comps(comps, *rgb, mask);
int didx = find_color(stab, comps);
//fprintf(stderr, "DEETS %d %u %u %u (orig %u/%u/%u)\n", didx, comps[0], comps[1], comps[2], ncpixel_r(*rgb), ncpixel_g(*rgb), ncpixel_b(*rgb));
if(didx < 0){
//fprintf(stderr, "FAILED FINDING COLOR AUGH 0x%02x\n", mask);
return -1;
}
// we form an eight-bit index by taking the top 3 MSBs of the red and
// green channels, and the top 2 MSBs of the blue channel (of the
// three, the human eye is least sensitive to blue).
unsigned char clumpbyte =
(ncpixel_r(*rgb) & 0xe0) |
((ncpixel_g(*rgb) & 0xe0) >> 3) |
((ncpixel_b(*rgb) & 0xc0) >> 6);
int didx = find_color(stab, clumpbyte);
stab->map->data[didx * stab->map->sixelcount + pos] |= (1u << (sy - visy));
update_deets(*rgb, &stab->deets[didx]);
//debug_color_table(stab);
if(update_deets(*rgb, &stab->deets[didx]) == 1){
++stab->map->colors;
}
//fprintf(stderr, "color %d pos %d: 0x%x\n", c, pos, stab->data[c * stab->map->sixelcount + pos]);
//fprintf(stderr, " sums: %u %u %u count: %d r/g/b: %u %u %u\n", stab->deets[c].sums[0], stab->deets[c].sums[1], stab->deets[c].sums[2], stab->deets[c].count, ncpixel_r(*rgb), ncpixel_g(*rgb), ncpixel_b(*rgb));
}
Expand Down

0 comments on commit 6ec660a

Please sign in to comment.