Skip to content

Commit

Permalink
Use much better Burkes dithering
Browse files Browse the repository at this point in the history
  • Loading branch information
colinleroy committed Jul 29, 2023
1 parent 41e4e5b commit 5e495ed
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/debian/changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
a2tools (1.2.4) bionic; urgency=medium
a2tools (1.2.4.1) bionic; urgency=medium

* Rework HGR convert for better B&W dithering
* Optimize (a lot)
Expand Down
51 changes: 49 additions & 2 deletions src/surl-server/hgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ char *hgr_to_png(char *hgr_buf, size_t hgr_len, char monochrome, size_t *len)
return out_buf;
}

static void mono_dither(SDL_Surface* s) {
#if 0
static void mono_dither_bayer(SDL_Surface* s) {
Uint32 x, y;

// Ordered dither kernel
Expand Down Expand Up @@ -666,6 +667,52 @@ static void mono_dither(SDL_Surface* s) {
}
}
}
#endif

static void mono_dither_burkes(SDL_Surface* s) {
Uint32 x, y;
float **error_table;
int threshold = 180;
#define ERR_X_OFF 2
error_table = malloc(sizeof(float *) * (s->h + 5));
for (y = 0; y < s->h + 5; y++) {
error_table[y] = malloc(sizeof(float) * (s->w + 5));
memset(error_table[y], 0x00, sizeof(float) * (s->w + 5));
}

for(y = 0; y < s->h; ++y) {
for(x = 0; x < s->w; ++x) {
Uint8 r, g, b;
float in;
float current_error;
sdl_get_pixel(s, x, y, &r, &g, &b);

// Convert the pixel value to grayscale i.e. intensity
in = .299 * r + .587 * g + .114 * b;

if (threshold > in + error_table[y][x + ERR_X_OFF]) {
sdl_set_pixel(s, x, y, 0, 0, 0);
current_error = in + error_table[y][x + ERR_X_OFF];
} else {
sdl_set_pixel(s, x, y, 255, 255, 255);
current_error = in + error_table[y][x + ERR_X_OFF] - 255;
}
error_table[y][x + 1 + ERR_X_OFF] += (int)(8.0L / 32.0L * current_error);
error_table[y][x + 2 + ERR_X_OFF] += (int)(4.0L / 32.0L * current_error);
error_table[y + 1][x + ERR_X_OFF] += (int)(8.0L / 32.0L * current_error);
error_table[y + 1][x + 1 + ERR_X_OFF] += (int)(4.0L / 32.0L * current_error);
error_table[y + 1][x + 2 + ERR_X_OFF] += (int)(2.0L / 32.0L * current_error);
error_table[y + 1][x - 1 + ERR_X_OFF] += (int)(4.0L / 32.0L * current_error);
error_table[y + 1][x - 2 + ERR_X_OFF] += (int)(2.0L / 32.0L * current_error);

}
}

for (y = 0; y < s->h + 4; y++) {
free(error_table[y]);
}
free(error_table);
}

static int sdl_color_hgr(SDL_Surface *src, unsigned char *hgr) {
int x, y;
Expand Down Expand Up @@ -728,7 +775,7 @@ unsigned char *sdl_to_hgr(const char *filename, char monochrome, int *len) {

sdl_image_scale(image, resized, monochrome ? 0.952381 : 1.904762);
if (monochrome) {
mono_dither(resized);
mono_dither_burkes(resized);
*len = sdl_mono_hgr(resized, grbuf);
} else {
color_dither(resized);
Expand Down

0 comments on commit 5e495ed

Please sign in to comment.