|
|
|
@ -1,10 +1,10 @@
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
break_sixel_comps(unsigned char comps[static 3], uint32_t rgba){
|
|
|
|
|
comps[0] = ncpixel_r(rgba) * 100 / 255;
|
|
|
|
|
comps[1] = ncpixel_g(rgba) * 100 / 255;
|
|
|
|
|
comps[2] = ncpixel_b(rgba) * 100 / 255;
|
|
|
|
|
break_sixel_comps(unsigned char comps[static 3], uint32_t rgba, unsigned char mask){
|
|
|
|
|
comps[0] = (ncpixel_r(rgba) & mask) * 100 / 255;
|
|
|
|
|
comps[1] = (ncpixel_g(rgba) & mask) * 100 / 255;
|
|
|
|
|
comps[2] = (ncpixel_b(rgba) & mask) * 100 / 255;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
// what do we do if every pixel is transparent (0 colors)? FIXME
|
|
|
|
|
static int
|
|
|
|
|
extract_color_table(const uint32_t* data, int linesize, int begy, int begx,
|
|
|
|
|
int leny, int lenx, colortable* ctab){
|
|
|
|
|
extract_ctable_inner(const uint32_t* data, int linesize, int begy, int begx,
|
|
|
|
|
int leny, int lenx, colortable* ctab, unsigned char mask){
|
|
|
|
|
for(int visy = begy ; visy < (begy + leny) ; visy += 6){
|
|
|
|
|
for(int visx = begx ; visx < (begx + lenx) ; visx += 1){
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
unsigned char comps[3];
|
|
|
|
|
break_sixel_comps(comps, *rgb);
|
|
|
|
|
break_sixel_comps(comps, *rgb, mask);
|
|
|
|
|
if(find_color(ctab, comps) < 0){
|
|
|
|
|
fprintf(stderr, "FUCK ME; THE COLOR TABLE'S FULL\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -78,9 +77,31 @@ fprintf(stderr, "FUCK ME; THE COLOR TABLE'S FULL\n");
|
|
|
|
|
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
|
|
|
|
|
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);
|
|
|
|
|
for(int c = 0 ; c < stab->ctab->colors ; ++c){
|
|
|
|
|
int pos = 0;
|
|
|
|
@ -96,7 +117,7 @@ extract_data_table(const uint32_t* data, int linesize, int begy, int begx,
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
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]);
|
|
|
|
|
if(memcmp(comps, stab->ctab->table + c * 3, 3) == 0){
|
|
|
|
|
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){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ctab->colors = 0;
|
|
|
|
|
ctab->sixelcount = 0;
|
|
|
|
|
memset(ctab->table, 0xff, 3);
|
|
|
|
|
if(extract_color_table(data, linesize, begy, begx, leny, lenx, ctab)){
|
|
|
|
|
unsigned char mask;
|
|
|
|
|
if(extract_color_table(data, linesize, begy, begx, leny, lenx, ctab, &mask)){
|
|
|
|
|
free(ctab);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
@ -227,7 +246,7 @@ int sixel_blit(ncplane* nc, int placey, int placex, int linesize,
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
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(ctab);
|
|
|
|
|
return -1;
|
|
|
|
|