sixel_blit: dumb quantization algorithm #1378

pull/1383/head
nick black 4 years ago
parent 3382de37e3
commit 49c7b6be3f
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -1,10 +1,10 @@
#include "internal.h" #include "internal.h"
static inline void static inline void
break_sixel_comps(unsigned char comps[static 3], uint32_t rgba){ break_sixel_comps(unsigned char comps[static 3], uint32_t rgba, unsigned char mask){
comps[0] = ncpixel_r(rgba) * 100 / 255; comps[0] = (ncpixel_r(rgba) & mask) * 100 / 255;
comps[1] = ncpixel_g(rgba) * 100 / 255; comps[1] = (ncpixel_g(rgba) & mask) * 100 / 255;
comps[2] = ncpixel_b(rgba) * 100 / 255; comps[2] = (ncpixel_b(rgba) & mask) * 100 / 255;
} }
// first pass: extract up to 256 sixelspace colors over arbitrarily many sixels // first pass: extract up to 256 sixelspace colors over arbitrarily many sixels
@ -56,8 +56,8 @@ find_color(colortable* ctab, unsigned char comps[static 3]){
// everything in a single pass FIXME. // everything in a single pass FIXME.
// what do we do if every pixel is transparent (0 colors)? FIXME // what do we do if every pixel is transparent (0 colors)? FIXME
static int static int
extract_color_table(const uint32_t* data, int linesize, int begy, int begx, extract_ctable_inner(const uint32_t* data, int linesize, int begy, int begx,
int leny, int lenx, colortable* ctab){ int leny, int lenx, colortable* ctab, unsigned char mask){
for(int visy = begy ; visy < (begy + leny) ; visy += 6){ for(int visy = begy ; visy < (begy + leny) ; visy += 6){
for(int visx = begx ; visx < (begx + lenx) ; visx += 1){ for(int visx = begx ; visx < (begx + lenx) ; visx += 1){
for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){ for(int sy = visy ; sy < (begy + leny) && sy < visy + 6 ; ++sy){
@ -66,9 +66,8 @@ extract_color_table(const uint32_t* data, int linesize, int begy, int begx,
continue; continue;
} }
unsigned char comps[3]; unsigned char comps[3];
break_sixel_comps(comps, *rgb); break_sixel_comps(comps, *rgb, mask);
if(find_color(ctab, comps) < 0){ if(find_color(ctab, comps) < 0){
fprintf(stderr, "FUCK ME; THE COLOR TABLE'S FULL\n");
return -1; return -1;
} }
} }
@ -78,9 +77,31 @@ fprintf(stderr, "FUCK ME; THE COLOR TABLE'S FULL\n");
return 0; return 0;
} }
static inline void
initialize_ctable(colortable* ctab){
ctab->colors = 0;
ctab->sixelcount = 0;
memset(ctab->table, 0xff, 3);
}
static int
extract_color_table(const uint32_t* data, int linesize, int begy, int begx,
int leny, int lenx, colortable* ctab, unsigned char* mask){
*mask = 0xff;
while(mask){
initialize_ctable(ctab);
if(extract_ctable_inner(data, linesize, begy, begx, leny, lenx, ctab, *mask) == 0){
return 0;
}
*mask <<= 1;
*mask &= 0xff;
}
return -1;
}
static int static int
extract_data_table(const uint32_t* data, int linesize, int begy, int begx, extract_data_table(const uint32_t* data, int linesize, int begy, int begx,
int leny, int lenx, sixeltable* stab){ int leny, int lenx, sixeltable* stab, unsigned char mask){
//fprintf(stderr, "colors: %d sixelcount: %d\n", stab->ctab->colors, stab->ctab->sixelcount); //fprintf(stderr, "colors: %d sixelcount: %d\n", stab->ctab->colors, stab->ctab->sixelcount);
for(int c = 0 ; c < stab->ctab->colors ; ++c){ for(int c = 0 ; c < stab->ctab->colors ; ++c){
int pos = 0; int pos = 0;
@ -96,7 +117,7 @@ extract_data_table(const uint32_t* data, int linesize, int begy, int begx,
continue; continue;
} }
unsigned char comps[3]; unsigned char comps[3];
break_sixel_comps(comps, *rgb); break_sixel_comps(comps, *rgb, mask);
//fprintf(stderr, "%d/%d/%d\n", comps[0], comps[1], comps[2]); //fprintf(stderr, "%d/%d/%d\n", comps[0], comps[1], comps[2]);
if(memcmp(comps, stab->ctab->table + c * 3, 3) == 0){ if(memcmp(comps, stab->ctab->table + c * 3, 3) == 0){
stab->data[c * stab->ctab->sixelcount + pos] |= (1u << (sy - visy)); stab->data[c * stab->ctab->sixelcount + pos] |= (1u << (sy - visy));
@ -211,10 +232,8 @@ int sixel_blit(ncplane* nc, int placey, int placex, int linesize,
if(ctab == NULL){ if(ctab == NULL){
return -1; return -1;
} }
ctab->colors = 0; unsigned char mask;
ctab->sixelcount = 0; if(extract_color_table(data, linesize, begy, begx, leny, lenx, ctab, &mask)){
memset(ctab->table, 0xff, 3);
if(extract_color_table(data, linesize, begy, begx, leny, lenx, ctab)){
free(ctab); free(ctab);
return -1; return -1;
} }
@ -227,7 +246,7 @@ int sixel_blit(ncplane* nc, int placey, int placex, int linesize,
return -1; return -1;
} }
memset(stable.data, 0, ctab->colors * ctab->sixelcount); memset(stable.data, 0, ctab->colors * ctab->sixelcount);
if(extract_data_table(data, linesize, begy, begx, leny, lenx, &stable)){ if(extract_data_table(data, linesize, begy, begx, leny, lenx, &stable, mask)){
free(stable.data); free(stable.data);
free(ctab); free(ctab);
return -1; return -1;

Loading…
Cancel
Save