diff --git a/img2cpi.c b/img2cpi.c index cfde98c..ac448d5 100644 --- a/img2cpi.c +++ b/img2cpi.c @@ -84,7 +84,8 @@ struct image *image_load(const char *fp); struct image *image_new(int w, int h); struct image *image_resize(struct image *original, int new_w, int new_h); struct image_pal *image_quantize(struct image *original, const union color *colors, size_t n_colors); -int get_color_difference(union color a, union color b); +float get_color_difference(union color a, union color b); +float get_color_brightness(union color clr); void image_unload(struct image *img); void get_size_keep_aspect(int w, int h, int dw, int dh, int *ow, int *oh); @@ -251,6 +252,53 @@ int main(int argc, char **argv) { // use old 2x3 for (int y = 0; y < args.height; y++) { for (int x = 0; x < args.width; x++) { + unsigned char darkest_i = 0, brightest_i = 0; + float darkest_diff = 0xffffff, brightest_diff = 0; + + for (int oy = 0; oy < 3; oy++) { + for (int ox = 0; ox < 2; ox++) { + unsigned char pix = quantized_image->pixels[ox + (x + (y * 3 + oy)) * 2]; + float brightness = get_color_brightness(palette[pix]); + if (brightness >= brightest_diff) { + brightest_i = pix; + brightest_diff = brightness; + } + if (brightness <= darkest_diff) { + darkest_i = pix; + darkest_diff = brightness; + } + } + } + + unsigned char bitmap = 0; + const static unsigned char pixel_bits[3][2] = { { 1, 2}, { 4, 8 }, { 16, 0 } }; + for (int oy = 0; oy < 3; oy++) { + for (int ox = 0; ox < 2; ox++) { + if (ox == 1 && oy == 2) continue; + unsigned char pix = quantized_image->pixels[ox + (x + (y * 3 + oy)) * 2]; + float diff_bg = get_color_difference(palette[darkest_i], palette[pix]); + float diff_fg = get_color_difference(palette[brightest_i], palette[pix]); + if (diff_fg < diff_bg) { + bitmap |= pixel_bits[oy][ox]; + } + } + } + + { + unsigned char pix = quantized_image->pixels[1 + (x + (y * 3 + 2)) * 2]; + float diff_bg = get_color_difference(palette[darkest_i], palette[pix]); + float diff_fg = get_color_difference(palette[brightest_i], palette[pix]); + if (diff_fg > diff_bg) { + bitmap ^= 31; + unsigned char tmp = darkest_i; + darkest_i = brightest_i; + brightest_i = tmp; + } + } + + characters[x + y * args.width].character = 0x80 + bitmap; + characters[x + y * args.width].bg = darkest_i; + characters[x + y * args.width].fg = brightest_i; } } } else { @@ -258,7 +306,7 @@ int main(int argc, char **argv) { for (int y = 0; y < args.height; y++) { for (int x = 0; x < args.width; x++) { // Oh boy... - int min_diff = 0xffffff; + float min_diff = 0xffffff; char closest_sym = 0x00, closest_color = 0xae; for (int sym = 0x01; sym <= 0xFF; sym++) { if (sym == '\t' || sym == '\n' || sym == '\r' || sym == '\x0e') { @@ -267,7 +315,7 @@ int main(int argc, char **argv) { for (int color = 0x00; color <= 0xff; color++) { union color cell_bg = palette[color & 0xF], cell_fg = palette[color >> 4]; - int difference = 0; + float difference = 0; for (int oy = 0; oy < 11; oy++) { unsigned char sym_line = font_atlas[sym][oy]; for (int ox = 0; ox < 8; ox++) { @@ -590,13 +638,17 @@ struct image_pal *image_quantize(struct image *original, const union color *colo return out; } -int get_color_difference(union color a, union color b) { +float get_color_difference(union color a, union color b) { int dr = a.rgba.r - b.rgba.r, dg = a.rgba.g - b.rgba.g, db = a.rgba.b - b.rgba.b; return dr * dr + dg * dg + db * db; } +float get_color_brightness(union color clr) { + return get_color_difference(clr, (union color){ .v = 0 }); +} + const union color DEFAULT_PALETTE[16] = { { 0xf0, 0xf0, 0xf0, 0xff }, { 0xf2, 0xb2, 0x33, 0xff },