forked from hkc/cc-stuff
Compare commits
2 Commits
6028bb419e
...
6ebe98e94c
Author | SHA1 | Date |
---|---|---|
Vftdan | 6ebe98e94c | |
Vftdan | 46f8ecd68e |
67
img2cpi.c
67
img2cpi.c
|
@ -30,8 +30,9 @@ struct palette {
|
|||
};
|
||||
#define LENGTHOF(...) (sizeof(__VA_ARGS__) / sizeof(*(__VA_ARGS__)))
|
||||
#define PALETTE(...) { .count = LENGTHOF((union color[]){__VA_ARGS__}), .colors = {__VA_ARGS__} }
|
||||
typedef char GlyphBitmap[11];
|
||||
|
||||
const extern char font_atlas[256][11];
|
||||
const extern GlyphBitmap font_atlas[256];
|
||||
const extern struct palette DEFAULT_PALETTE, DEFAULT_GRAY_PALETTE;
|
||||
|
||||
struct arguments {
|
||||
|
@ -124,6 +125,8 @@ bool k_means_iteration(struct k_means_state *state);
|
|||
void k_means_end(struct k_means_state *state);
|
||||
struct palette *palette_k_means(const struct image *image, const struct palette *prototype);
|
||||
|
||||
inline static uint8_t closest_chunk_color_symbol(const typeof(float[8][11][0x10]) *chunk_palette_diffs, uint8_t color_pair);
|
||||
|
||||
const char *known_file_extensions[] = {
|
||||
".png", ".jpg", ".jpeg", ".jfif", ".jpg", ".gif",
|
||||
".tga", ".bmp", ".hdr", ".pnm", 0
|
||||
|
@ -630,11 +633,9 @@ void convert_8x11(const struct image_pal *img, struct cc_char *characters) {
|
|||
|
||||
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') {
|
||||
continue;
|
||||
}
|
||||
for (int color = 0x00; color <= 0xff; color++) {
|
||||
for (int color = 0x00; color <= 0xff; color++) {
|
||||
{
|
||||
const int sym = closest_chunk_color_symbol(&chunk_palette_diffs, color);
|
||||
float difference = 0;
|
||||
for (int oy = 0; oy < 11; oy++) {
|
||||
unsigned char sym_line = font_atlas[sym][oy];
|
||||
|
@ -792,6 +793,60 @@ struct palette *palette_k_means(const struct image *image, const struct palette
|
|||
return palette;
|
||||
}
|
||||
|
||||
inline static float weighted_glyph_hamming_distance(const GlyphBitmap *lhs, const GlyphBitmap *rhs, typeof(float[11][8]) *weights) {
|
||||
float dist = 0;
|
||||
for (int oy = 0; oy < 11; oy++) {
|
||||
uint8_t sym_line = (*lhs)[oy] ^ (*rhs)[oy];
|
||||
for (int ox = 0; ox < 8; ox++) {
|
||||
bool lit = sym_line & (0x80 >> ox);
|
||||
if (lit) {
|
||||
dist += (*weights)[oy][ox];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
uint8_t closest_glyph_symbol(const GlyphBitmap *target, typeof(float[11][8]) *weights) {
|
||||
uint8_t best = 0x01;
|
||||
float best_dist = weighted_glyph_hamming_distance(target, &font_atlas[best], weights);
|
||||
for (int sym = 0x02; sym <= 0xFF; sym++) {
|
||||
if (sym == '\t' || sym == '\n' || sym == '\r' || sym == '\x0e') {
|
||||
continue;
|
||||
}
|
||||
float dist = weighted_glyph_hamming_distance(target, &font_atlas[best], weights);
|
||||
if (dist <= best_dist) {
|
||||
best_dist = dist;
|
||||
best = sym;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
void construct_chunk_color_glyph(GlyphBitmap *result, typeof(float[11][8]) *weights, const typeof(float[8][11][0x10]) *chunk_palette_diffs, uint8_t color_pair) {
|
||||
uint8_t fg = color_pair >> 4,
|
||||
bg = color_pair & 0xF;
|
||||
for (int oy = 0; oy < 11; oy++) {
|
||||
uint8_t sym_line = 0;
|
||||
for (int ox = 0; ox < 8; ox++) {
|
||||
float dist_diff = (*chunk_palette_diffs)[ox][oy][fg] - (*chunk_palette_diffs)[ox][oy][bg];
|
||||
uint8_t lit = dist_diff > 0;
|
||||
sym_line |= lit << (7 - ox);
|
||||
if (weights) {
|
||||
(*weights)[oy][ox] = lit ? dist_diff : -dist_diff;
|
||||
}
|
||||
}
|
||||
(*result)[oy] = sym_line;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t closest_chunk_color_symbol(const typeof(float[8][11][0x10]) *chunk_palette_diffs, uint8_t color_pair) {
|
||||
GlyphBitmap glyph;
|
||||
float weights[11][8];
|
||||
construct_chunk_color_glyph(&glyph, &weights, chunk_palette_diffs, color_pair);
|
||||
return closest_glyph_symbol(&glyph, &weights);
|
||||
}
|
||||
|
||||
const struct palette DEFAULT_PALETTE = PALETTE(
|
||||
{ { 0xf0, 0xf0, 0xf0, 0xff } },
|
||||
{ { 0xf2, 0xb2, 0x33, 0xff } },
|
||||
|
|
Loading…
Reference in New Issue