From ae6fba6e227f4d91cd069aef01290bb33cd6ea7e Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 4 Nov 2004 22:28:39 +0000 Subject: [PATCH] * src/caca.h: + Introduced CACA_DITHER_FSTEIN. * src/caca.c: + CACA_DITHER_FSTEIN is the default dithering method. * src/bitmap.c: + Fixed other dithering methods. Black background does not work yet. --- src/bitmap.c | 80 ++++++++++++++++++++++++++++++++++------------------ src/caca.c | 6 +++- src/caca.h | 3 +- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/bitmap.c b/src/bitmap.c index 3b3c5b7..8c7ffdf 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -103,6 +103,12 @@ static int rgb_palette[] = 0xfff, 0xfff, 0xfff, }; +static int rgb_weight[] = +{ + //2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + #if !defined(_DOXYGEN_SKIP_ME) #define HSV_XRATIO 6 #define HSV_YRATIO 3 @@ -541,6 +547,12 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, _increment_dither = increment_random_dither; break; + case CACA_DITHERING_FSTEIN: + _init_dither = init_no_dither; + _get_dither = get_no_dither; + _increment_dither = increment_no_dither; + break; + default: /* Something wicked happened! */ return; @@ -624,15 +636,24 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, continue; } - r += remain_r; - g += remain_g; - b += remain_b; - r += remain_r_next; - g += remain_g_next; - b += remain_b_next; - remain_r_next = fs_r[x+1]; - remain_g_next = fs_g[x+1]; - remain_b_next = fs_b[x+1]; + if(_caca_dithering == CACA_DITHERING_FSTEIN) + { + r += remain_r; + g += remain_g; + b += remain_b; + r += remain_r_next; + g += remain_g_next; + b += remain_b_next; + remain_r_next = fs_r[x+1]; + remain_g_next = fs_g[x+1]; + remain_b_next = fs_b[x+1]; + } + else + { + r += (_get_dither() - 0x80) * 4; + g += (_get_dither() - 0x80) * 4; + b += (_get_dither() - 0x80) * 4; + } distmin = INT_MAX; for(i = 0; i < 16; i++) @@ -640,6 +661,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, dist = sq(r - rgb_palette[i * 3]) + sq(g - rgb_palette[i * 3 + 1]) + sq(b - rgb_palette[i * 3 + 2]); + dist *= rgb_weight[i]; if(dist < distmin) { outbg = i; @@ -658,6 +680,7 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, dist = sq(r - rgb_palette[i * 3]) + sq(g - rgb_palette[i * 3 + 1]) + sq(b - rgb_palette[i * 3 + 2]); + dist *= rgb_weight[i]; if(dist < distmin) { outfg = i; @@ -686,24 +709,27 @@ void caca_draw_bitmap(int x1, int y1, int x2, int y2, } outch = density_chars[4 * ch]; - remain_r = r - (fg_r * ch + bg_r * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); - remain_g = g - (fg_g * ch + bg_g * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); - remain_b = b - (fg_b * ch + bg_b * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); - remain_r_next = fs_r[x+1]; - remain_g_next = fs_g[x+1]; - remain_b_next = fs_b[x+1]; - fs_r[x-1] += 3 * remain_r / 16; - fs_g[x-1] += 3 * remain_g / 16; - fs_b[x-1] += 3 * remain_b / 16; - fs_r[x] = 5 * remain_r / 16; - fs_g[x] = 5 * remain_g / 16; - fs_b[x] = 5 * remain_b / 16; - fs_r[x+1] = 1 * remain_r / 16; - fs_g[x+1] = 1 * remain_g / 16; - fs_b[x+1] = 1 * remain_b / 16; - remain_r = 7 * remain_r / 16; - remain_g = 7 * remain_g / 16; - remain_b = 7 * remain_b / 16; + if(_caca_dithering == CACA_DITHERING_FSTEIN) + { + remain_r = r - (fg_r * ch + bg_r * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); + remain_g = g - (fg_g * ch + bg_g * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); + remain_b = b - (fg_b * ch + bg_b * ((2*DCHMAX-1) - ch)) / (2*DCHMAX-1); + remain_r_next = fs_r[x+1]; + remain_g_next = fs_g[x+1]; + remain_b_next = fs_b[x+1]; + fs_r[x-1] += 3 * remain_r / 16; + fs_g[x-1] += 3 * remain_g / 16; + fs_b[x-1] += 3 * remain_b / 16; + fs_r[x] = 5 * remain_r / 16; + fs_g[x] = 5 * remain_g / 16; + fs_b[x] = 5 * remain_b / 16; + fs_r[x+1] = 1 * remain_r / 16; + fs_g[x+1] = 1 * remain_g / 16; + fs_b[x+1] = 1 * remain_b / 16; + remain_r = 7 * remain_r / 16; + remain_g = 7 * remain_g / 16; + remain_b = 7 * remain_b / 16; + } /* Now output the character */ caca_set_color(outfg, outbg); diff --git a/src/caca.c b/src/caca.c index 02ef4ec..613faa9 100644 --- a/src/caca.c +++ b/src/caca.c @@ -319,12 +319,13 @@ void caca_set_feature(enum caca_feature feature) break; case CACA_DITHERING: - feature = CACA_DITHERING_ORDERED4; + feature = CACA_DITHERING_FSTEIN; case CACA_DITHERING_NONE: case CACA_DITHERING_ORDERED2: case CACA_DITHERING_ORDERED4: case CACA_DITHERING_ORDERED8: case CACA_DITHERING_RANDOM: + case CACA_DITHERING_FSTEIN: _caca_dithering = feature; break; @@ -356,6 +357,7 @@ char const *caca_get_feature_name(enum caca_feature feature) case CACA_DITHERING_ORDERED4: return "4x4 ordered dithering"; case CACA_DITHERING_ORDERED8: return "8x8 ordered dithering"; case CACA_DITHERING_RANDOM: return "random dithering"; + case CACA_DITHERING_FSTEIN: return "Floyd-Steinberg dithering"; default: return "unknown"; } @@ -541,6 +543,8 @@ static void caca_init_features(void) caca_set_feature(CACA_DITHERING_ORDERED8); else if(!strcasecmp("random", var)) caca_set_feature(CACA_DITHERING_RANDOM); + else if(!strcasecmp("fstein", var)) + caca_set_feature(CACA_DITHERING_FSTEIN); } #endif } diff --git a/src/caca.h b/src/caca.h index 84d251d..6036514 100644 --- a/src/caca.h +++ b/src/caca.h @@ -151,8 +151,9 @@ enum caca_feature CACA_DITHERING_ORDERED4 = 0x33, /**< Ordered 4x4 Bayer dithering. */ CACA_DITHERING_ORDERED8 = 0x34, /**< Ordered 8x8 Bayer dithering. */ CACA_DITHERING_RANDOM = 0x35, /**< Random dithering. */ + CACA_DITHERING_FSTEIN = 0x36, /**< Floyd-Steinberg dithering. */ #define CACA_DITHERING_MIN 0x31 /**< First dithering feature. */ -#define CACA_DITHERING_MAX 0x35 /**< Last dithering feature. */ +#define CACA_DITHERING_MAX 0x36 /**< Last dithering feature. */ CACA_FEATURE_UNKNOWN = 0xffff /**< Unknown feature. */ };