all common routines to a same util.c - 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 a1eea6f23b8947751165e1909fd387803c7a803e
DIR parent 2f2583b40975087c6463403508706bcc5138e833
HTML Author: Josuah Demangeon <mail@josuah.net>
Date: Mon, 29 Jan 2018 08:26:30 +0100
all common routines to a same util.c
Diffstat:
M .gitignore | 1 +
M Makefile | 9 ++++++---
A ascii.txt | 49 +++++++++++++++++++++++++++++++
A ff2ascii.c | 101 +++++++++++++++++++++++++++++++
A ff2braille.1 | 29 +++++++++++++++++++++++++++++
M ff2braille.c | 98 +++++++++++++------------------
A ff2col.c | 40 +++++++++++++++++++++++++++++++
A util.c | 47 +++++++++++++++++++++++++++++++
A util.h | 16 ++++++++++++++++
9 files changed, 330 insertions(+), 60 deletions(-)
---
DIR diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
*.o
*.core
ff2braille
+ff2col
DIR diff --git a/Makefile b/Makefile
@@ -1,8 +1,11 @@
CFLAGS = -std=c89 -pedantic -Wall -Wextra -Werror
-all: ff2braille
+all: ff2braille ff2col
-ff2braille: ff2braille.o
- cc -o $@ ff2braille.o $(LDFLAGS)
+ff2braille: ff2braille.o util.o util.h
+ cc -o $@ ff2braille.o util.o $(LDFLAGS)
+
+ff2col: ff2col.o util.o util.h
+ cc -o $@ ff2col.o util.o $(LDFLAGS)
install:
mkdir -p ${PREFIX}/bin
DIR diff --git a/ascii.txt b/ascii.txt
@@ -0,0 +1,49 @@
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+
+
+
+! # $ % & ( ) / 0 1 2 3 4 5 6 7 8 9 : ; < > ?
+
+@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ]
+
+{ | }
+
+` ^ ~ " '
+* + - =
+b d f l k t
+a c e h i m n o r s u v w x z
+g j p q y
+,.
+_
DIR diff --git a/ff2ascii.c b/ff2ascii.c
@@ -0,0 +1,101 @@
+/*
+ * Transforming an image into a braille character text is transforming a
+ * matrice this way:
+ *
+ * farbfeld image braille characters
+ *
+ * [[a0 a1 a2 a3 a4 a5] [[[a0 a1 [a2 a3 [a4 a5 \
+ * [b0 b1 b2 b3 b4 b5] b0 b1 / b2 b3 / b4 b5 |<- One braille
+ * [c0 c1 c2 c3 c4 c5] c0 c1 / c2 c3 / c4 c5 | character
+ * [d0 d1 d2 d3 d4 d5] => d0 d1] d2 d3] d4 d5]] /
+ * [e0 e1 e2 e3 e4 e5] [[e0 e1 [e2 e3 [e4 e5
+ * [f0 f1 f2 f3 f4 f5] f0 f1 / f2 f3 / f4 f5
+ * [g0 g1 g2 g3 g4 g5] g0 g1 / g2 g3 / g4 g5
+ * [h0 h1 h2 h3 h4 h5]] h0 h1] h2 h3] h4 h5]]]
+ *
+ * braille characters written as a line:
+ *
+ * [[[a0 a1 b0 b1 c0 c1 d0 d1] <- One braille character
+ * [a2 a3 b2 b3 c2 c3 d2 d3]
+ * [a4 a5 b4 b5 c4 c5 d4 d5]] <- One row of braille characters
+ * [[e0 e1 f0 f1 g0 g1 h0 h1]
+ * [e2 e3 f2 f3 g2 g3 h2 h3]
+ * [e4 e5 f4 f5 g4 g5 h4 h5]]] <- Two row of braille characters
+ *
+ * Although the encoding of braille keeps 1 4
+ * the characters encoded with only six 2 5
+ * dots first, as only these are used for 3 6
+ * encoding letters: 7 8
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "util.h"
+
+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 +
+ 0x01 * is_on(rows, width, height, w + 0, 0) +
+ 0x08 * is_on(rows, width, height, w + 1, 0) +
+ 0x02 * is_on(rows, width, height, w + 0, 1) +
+ 0x10 * is_on(rows, width, height, w + 1, 1) +
+ 0x04 * is_on(rows, width, height, w + 0, 2) +
+ 0x20 * is_on(rows, width, height, w + 1, 2) +
+ 0x40 * is_on(rows, width, height, w + 0, 3) +
+ 0x80 * 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, h, r, i;
+
+ read_header(&width, &height);
+
+ for (i = 0; i < 4; i++)
+ rows[i] = buf + width * i;
+
+ for (h = 0; h < height; h += 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;
+}
DIR diff --git a/ff2braille.1 b/ff2braille.1
@@ -0,0 +1,29 @@
+.Dt FF2BRAILLE 1
+.Dd $Mdocdate: January 22 2018$
+.Os
+.
+.
+.Sh NAME
+.
+.Nm ff2braille
+.Nd farbfeld to text braille pattern image conversion
+.
+.
+.Sh SYNOPSIS
+.
+.Nm
+.
+.
+.Sh DESCRIPTION
+.
+.Nm
+reads a
+.Xr farbfeld 5
+image from stdin and write a text representation of the image using braille
+characters to stdout.
+.
+.
+.Sh EXIT STATUS
+.
+.Ex -std
+.
DIR diff --git a/ff2braille.c b/ff2braille.c
@@ -1,4 +1,32 @@
-#include <arpa/inet.h>
+/*
+ * Transforming an image into a braille character text is transforming a
+ * matrice this way:
+ *
+ * farbfeld image braille characters
+ *
+ * [[a0 a1 a2 a3 a4 a5] [[[a0 a1 [a2 a3 [a4 a5 \
+ * [b0 b1 b2 b3 b4 b5] b0 b1 / b2 b3 / b4 b5 |<- One braille
+ * [c0 c1 c2 c3 c4 c5] c0 c1 / c2 c3 / c4 c5 | character
+ * [d0 d1 d2 d3 d4 d5] => d0 d1] d2 d3] d4 d5]] /
+ * [e0 e1 e2 e3 e4 e5] [[e0 e1 [e2 e3 [e4 e5
+ * [f0 f1 f2 f3 f4 f5] f0 f1 / f2 f3 / f4 f5
+ * [g0 g1 g2 g3 g4 g5] g0 g1 / g2 g3 / g4 g5
+ * [h0 h1 h2 h3 h4 h5]] h0 h1] h2 h3] h4 h5]]]
+ *
+ * braille characters written as a line:
+ *
+ * [[[a0 a1 b0 b1 c0 c1 d0 d1] <- One braille character
+ * [a2 a3 b2 b3 c2 c3 d2 d3]
+ * [a4 a5 b4 b5 c4 c5 d4 d5]] <- One row of braille characters
+ * [[e0 e1 f0 f1 g0 g1 h0 h1]
+ * [e2 e3 f2 f3 g2 g3 h2 h3]
+ * [e4 e5 f4 f5 g4 g5 h4 h5]]] <- Two row of braille characters
+ *
+ * Although the encoding of braille keeps 1 4
+ * the characters encoded with only six 2 5
+ * dots first, as only these are used for 3 6
+ * encoding letters: 7 8
+ */
#include <stdio.h>
#include <string.h>
@@ -7,41 +35,6 @@
#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)
{
@@ -52,20 +45,13 @@ print_utf8_3byte(long rune)
}
int
-is_on(struct col *rows[4], uint32_t width, uint32_t height, uint32_t w,
- uint32_t h)
+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;
+ return is_bright(rows[h][w]);
}
void
@@ -75,14 +61,14 @@ print_4_rows(struct col *rows[4], uint32_t width, uint32_t height)
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));
+ 0x01 * is_on(rows, width, height, w + 0, 0) +
+ 0x08 * is_on(rows, width, height, w + 1, 0) +
+ 0x02 * is_on(rows, width, height, w + 0, 1) +
+ 0x10 * is_on(rows, width, height, w + 1, 1) +
+ 0x04 * is_on(rows, width, height, w + 0, 2) +
+ 0x20 * is_on(rows, width, height, w + 1, 2) +
+ 0x40 * is_on(rows, width, height, w + 0, 3) +
+ 0x80 * is_on(rows, width, height, w + 1, 3));
putchar('\n');
}
@@ -93,8 +79,6 @@ main(void)
uint32_t width, height, h, 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;
@@ -103,9 +87,9 @@ main(void)
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");
+ print_4_rows(rows, width, r / width);
}
return 0;
}
DIR diff --git a/ff2col.c b/ff2col.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "util.h"
+
+void
+print_2_rows(struct col *buf, uint32_t width, int height)
+{
+ size_t w;
+ int up, dn;
+ char *map = " '.:";
+
+ for (w = 0; w < width; w += 2) {
+ up = height > 0 && is_bright(buf[w]) ? 0x1 : 0x0;
+ dn = height > 1 && is_bright(buf[w + width]) ? 0x2 : 0x0;
+ putchar(map[up & dn]);
+ }
+ putchar('\n');
+}
+
+int
+main(void)
+{
+ struct col buf[MAX_WIDTH * 2];
+ uint32_t width, height, h, r;
+
+ read_header(&width, &height);
+
+ for (h = 0; h < height; h += 2) {
+ r = fread(buf, sizeof(*buf), width * 2, stdin);
+ if (r % width != 0)
+ err("invalid line width");
+ if (ferror(stdin))
+ err("fread stdin");
+ print_2_rows(buf, width, r / width);
+ }
+ return 0;
+}
DIR diff --git a/util.c b/util.c
@@ -0,0 +1,47 @@
+#include <arpa/inet.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "util.h"
+
+void
+err(char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+void
+read_header(uint32_t *width, uint32_t *height)
+{
+ 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]);
+ *height = ntohl(header[3]);
+
+ if (width == 0 || height == 0)
+ err("empty image");
+}
+
+int
+is_bright(struct col col)
+{
+ int32_t sum;
+
+ /* divide first to avoid overflow */
+ sum = htonl(col.red) / 4;
+ sum += htonl(col.green) / 4;
+ sum += htonl(col.blue) / 4;
+ sum += htonl(col.alpha) / 4;
+
+ return sum <= UINT16_MAX / 2;
+}
DIR diff --git a/util.h b/util.h
@@ -0,0 +1,16 @@
+#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 *);
+void read_header(uint32_t *, uint32_t *);
+int is_bright(struct col);