Added ff2braille - ff2txt - farbfeld image to plain text visualization
 (HTM) git clone git://bitreich.org/ff2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ff2txt
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
       ---
 (DIR) commit dc898f91b9f862707348f36a08628a9b08f3525b
 (HTM) 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;
       +}