Added ff2braille - ff2txt - farbfeld image to plain text visualization
HTML git clone git://bitreich.org/ff2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ff2txt
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
---
DIR commit dc898f91b9f862707348f36a08628a9b08f3525b
HTML Author: Josuah Demangeon <mail@josuah.net>
Date: Mon, 22 Jan 2018 05:41:32 +0100
Added ff2braille
Diffstat:
A .gitignore | 3 +++
A Makefile | 8 ++++++++
A ff2braille.c | 111 ++++++++++++++++++++++++++++++
3 files changed, 122 insertions(+), 0 deletions(-)
---
DIR diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.core
+ff2braille
DIR diff --git a/Makefile b/Makefile
@@ -0,0 +1,8 @@
+CFLAGS = -std=c89 -pedantic -Wall -Wextra -Werror
+all: ff2braille
+
+ff2braille: ff2braille.o
+ cc -o $@ ff2braille.o $(LDFLAGS)
+
+clean:
+ rm -f *.o ff2braille
DIR diff --git a/ff2braille.c b/ff2braille.c
@@ -0,0 +1,111 @@
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "util.h"
+
+#define MAX_WIDTH (1 << 12)
+#define BRAILLE_START 10240
+#define COLORS 4
+
+#define LEN(X) (sizeof(X) / sizeof(*X))
+
+struct col {
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+ uint16_t alpha;
+};
+
+void
+err(char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+void
+read_header(uint32_t *width, uint32_t *h)
+{
+ uint32_t header[4];
+
+ if (fread(header, sizeof(*header), LEN(header), stdin) != LEN(header))
+ err("fread");
+
+ if (memcmp("farbfeld", header, sizeof("farbfeld") - 1))
+ err("invalid magic value\n");
+
+ *width = ntohl(header[2]);
+ *h = ntohl(header[3]);
+}
+
+void
+print_utf8_3byte(long rune)
+{
+ printf("%c%c%c",
+ (char)(0xe0 | (0x0f & (rune >> 12))), /* 1110xxxx */
+ (char)(0x80 | (0x3f & (rune >> 6))), /* 10xxxxxx */
+ (char)(0x80 | (0x3f & (rune)))); /* 10xxxxxx */
+}
+
+int
+is_on(struct col *rows[4], uint32_t width, uint32_t height, uint32_t w,
+ uint32_t h)
+{
+ uint16_t sum;
+
+ if (w >= width || h >= height)
+ return 0;
+
+ /* divide first to avoid overflow */
+ sum = rows[h][w].red / 4;
+ sum += rows[h][w].green / 4;
+ sum += rows[h][w].blue / 4;
+ sum += rows[h][w].alpha / 4;
+ return sum >= UINT16_MAX / 2;
+}
+
+void
+print_4_rows(struct col *rows[4], uint32_t width, uint32_t height)
+{
+ uint32_t w;
+
+ for (w = 0; w < width; w += 2)
+ print_utf8_3byte(BRAILLE_START +
+ 1 * is_on(rows, width, height, w + 0, 0) +
+ 8 * is_on(rows, width, height, w + 1, 0) +
+ 2 * is_on(rows, width, height, w + 0, 1) +
+ 16 * is_on(rows, width, height, w + 1, 1) +
+ 4 * is_on(rows, width, height, w + 0, 2) +
+ 32 * is_on(rows, width, height, w + 1, 2) +
+ 64 * is_on(rows, width, height, w + 0, 3) +
+ 128 * is_on(rows, width, height, w + 1, 3));
+ putchar('\n');
+}
+
+int
+main(void)
+{
+ struct col buf[MAX_WIDTH * 4], *rows[4];
+ uint32_t width, height, r, i;
+
+ read_header(&width, &height);
+ if (width == 0 || height == 0)
+ err("empty image");
+
+ for (i = 0; i < 4; i++)
+ rows[i] = buf + width * i;
+
+ for (; height > 0; height -= 4) {
+ r = fread(buf, sizeof(*buf), width * 4, stdin);
+ if (r % width != 0)
+ err("invalid line width");
+ print_4_rows(rows, width, r / width);
+ }
+ if (ferror(stdin))
+ err("fread stdin");
+ return 0;
+}