From 2731717beed624aa4b15b0abfe6fe8c8c1ed7fe2 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 30 Mar 2013 18:39:42 +0000 Subject: [PATCH] codec: add import code for .BIN binary ANSI files. --- caca/codec/codec.h | 1 + caca/codec/import.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/caca/codec/codec.h b/caca/codec/codec.h index 867253d..ae8acd5 100644 --- a/caca/codec/codec.h +++ b/caca/codec/codec.h @@ -13,6 +13,7 @@ ssize_t _import_text(caca_canvas_t *, void const *, size_t); ssize_t _import_ansi(caca_canvas_t *, void const *, size_t, int); +ssize_t _import_bin(caca_canvas_t *, void const *, size_t); void *_export_ansi(caca_canvas_t const *, size_t *); void *_export_utf8(caca_canvas_t const *, size_t *, int); diff --git a/caca/codec/import.c b/caca/codec/import.c index c1877ba..4607907 100644 --- a/caca/codec/import.c +++ b/caca/codec/import.c @@ -54,6 +54,7 @@ static ssize_t import_caca(caca_canvas_t *, void const *, size_t); * - \c "text": import ASCII text files. * - \c "ansi": import ANSI files. * - \c "utf8": import UTF-8 files with ANSI colour codes. + * - \c "bin": import BIN files. * * The number of bytes read is returned. If the file format is valid, but * not enough data was available, 0 is returned. @@ -80,12 +81,14 @@ ssize_t caca_import_canvas_from_memory(caca_canvas_t *cv, void const *data, return _import_text(cv, data, len); if(!strcasecmp("ansi", format)) return _import_ansi(cv, data, len, 0); + if(!strcasecmp("bin", format)) + return _import_bin(cv, data, len); /* Autodetection */ if(!strcasecmp("", format)) { unsigned char const *str = data; - unsigned int i; + unsigned int i, j, k; /* If 4 first bytes are 0xcaca + 'CV' */ if(len >= 4 && str[0] == 0xca && @@ -97,6 +100,17 @@ ssize_t caca_import_canvas_from_memory(caca_canvas_t *cv, void const *data, if((str[i] == '\033') && (str[i + 1] == '[')) return _import_ansi(cv, data, len, 0); + /* If we find a lot of spaces at even locations, + * we guess it's a BIN file. */ + for (i = j = k = 0; i < len; i += 2) + { + j += (str[i] == ' '); + k += (str[i + 1] == ' '); + } + + if (j > 10 && j > len / 40 && k < 10) + return _import_bin(cv, data, len); + /* Otherwise, import it as text */ return _import_text(cv, data, len); } @@ -117,6 +131,7 @@ ssize_t caca_import_canvas_from_memory(caca_canvas_t *cv, void const *data, * - \c "text": import ASCII text files. * - \c "ansi": import ANSI files. * - \c "utf8": import UTF-8 files with ANSI colour codes. + * - \c "bin": import BIN files. * * The number of bytes read is returned. If the file format is valid, but * not enough data was available, 0 is returned. @@ -267,6 +282,7 @@ char const * const * caca_get_import_list(void) "text", "plain text", "ansi", "ANSI coloured text", "utf8", "UTF-8 files with ANSI colour codes", + "bin", "BIN binary ANSI art", NULL, NULL }; @@ -394,6 +410,31 @@ invalid_caca: return -1; } +ssize_t _import_bin(caca_canvas_t *cv, void const *data, size_t len) +{ + uint8_t const *buf = (uint8_t const *)data; + size_t i; + int x = 0, y = 0; + + caca_set_canvas_size(cv, 0, 0); + caca_set_canvas_size(cv, 160, len / 160); + + for (i = 0; i < len; i += 2) + { + caca_set_color_ansi(cv, buf[i + 1] & 0xf, buf[i + 1] >> 4); + caca_put_char(cv, x, y, caca_cp437_to_utf32(buf[i])); + + ++x; + if (x >= 160) + { + ++y; + x = 0; + } + } + + return len & ~(size_t)1; +} + /* * XXX: The following functions are aliases. */