Browse Source

* 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.
tags/v0.99.beta14
Sam Hocevar sam 20 years ago
parent
commit
ae6fba6e22
3 changed files with 60 additions and 29 deletions
  1. +53
    -27
      src/bitmap.c
  2. +5
    -1
      src/caca.c
  3. +2
    -1
      src/caca.h

+ 53
- 27
src/bitmap.c View File

@@ -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);


+ 5
- 1
src/caca.c View File

@@ -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
}


+ 2
- 1
src/caca.h View File

@@ -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. */
};


Loading…
Cancel
Save