commit 0a034f2bd5a44c3cc0c033eacc940bb3bf73662c
parent d05d162cb81664f292834fa5d48d623d2b6147a7
Author: Mattias Andrée <maandree@kth.se>
Date: Tue, 18 Jul 2017 19:42:27 +0200
Add blind-mosaic-corners and fix enset_pixel_format
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
12 files changed, 171 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -50,6 +50,7 @@ BIN =\
blind-matrix-translate\
blind-matrix-transpose\
blind-mosaic\
+ blind-mosaic-corners\
blind-mosaic-edges\
blind-multiply-matrices\
blind-next-frame\
diff --git a/README b/README
@@ -144,6 +144,9 @@ UTILITIES
blind-mosaic(1)
Redraw each frame in video as a mosaic
+ blind-mosaic-corners(1)
+ Find corners in a mosaic video
+
blind-mosaic-edges(1)
Find edges in a mosaic video
diff --git a/man/blind-hexagon-tessellation.1 b/man/blind-hexagon-tessellation.1
@@ -30,6 +30,7 @@ for more information.
.BR blind-get-colours (1),
.BR blind-apply-palette (1),
.BR blind-mosaic (1),
+.BR blind-mosaic-corners (1),
.BR blind-mosaic-edges (1)
.SH AUTHORS
Mattias Andrée
diff --git a/man/blind-mosaic-corners.1 b/man/blind-mosaic-corners.1
@@ -0,0 +1,41 @@
+.TH BLIND-MOSAIC-CORNERS 1 blind
+.SH NAME
+blind-mosaic-corners - Find corners in a mosaic video
+.SH SYNOPSIS
+[-xy]
+.B blind-mosaic-corners
+.SH DESCRIPTION
+.B blind-mosaic-corners
+reads a mosaic pattern from stdin and set the values
+of each change to 1 at corners and to 0 everywhere else.
+.IR mosaic-stream-corners .
+.SH OPTIONS
+.TP
+.B -x
+At the left and right edges of the video,
+wrap around to the opposite edges.
+.TP
+.B -y
+At the upper and lower edges of the video,
+wrap around to the opposite edges.
+.SH REQUIREMENTS
+.B blind-mosaic-corners
+requires enough free memory to load one full frame into
+memory and 1 bit per pixel on a frame. A frame requires
+32 bytes per pixel it contains.
+.B blind-mosaic-corners
+is optimised for simplicity rather the memory usage.
+.SH NOTES
+.B blind-mosaic-corners
+only works as intended if the tesserae are convex.
+.SH SEE ALSO
+.BR blind (7),
+.BR blind-mosaic-edges (1),
+.BR blind-hexagon-tessellation (1),
+.BR blind-rectangle-tessellation (1),
+.BR blind-triangle-tessellation (1),
+.BR blind-repeat-tessellation (1),
+.BR blind-mosaic (1)
+.SH AUTHORS
+Mattias Andrée
+.RI < maandree@kth.se >
diff --git a/man/blind-mosaic-edges.1 b/man/blind-mosaic-edges.1
@@ -27,6 +27,7 @@ memory and 1 bit per pixel on a frame. A frame requires
is optimised for simplicity rather the memory usage.
.SH SEE ALSO
.BR blind (7),
+.BR blind-mosaic-corners (1),
.BR blind-hexagon-tessellation (1),
.BR blind-rectangle-tessellation (1),
.BR blind-triangle-tessellation (1),
diff --git a/man/blind-mosaic.1 b/man/blind-mosaic.1
@@ -31,6 +31,7 @@ memory. A frame requires 32 bytes per pixel it contains.
.BR blind-rectangle-tessellation (1),
.BR blind-triangle-tessellation (1),
.BR blind-repeat-tessellation (1),
+.BR blind-mosaic-corners (1),
.BR blind-mosaic-edges (1)
.SH AUTHORS
Mattias Andrée
diff --git a/man/blind-rectangle-tessellation.1 b/man/blind-rectangle-tessellation.1
@@ -32,6 +32,7 @@ for more information.
.BR blind-get-colours (1),
.BR blind-apply-palette (1),
.BR blind-mosaic (1),
+.BR blind-mosaic-corners (1),
.BR blind-mosaic-edges (1)
.SH AUTHORS
Mattias Andrée
diff --git a/man/blind-repeat-tessellation.1 b/man/blind-repeat-tessellation.1
@@ -35,6 +35,7 @@ bytes per pixel it contains.
.BR blind-rectangle-tessellation (1),
.BR blind-triangle-tessellation (1),
.BR blind-mosaic (1),
+.BR blind-mosaic-corners (1),
.BR blind-mosaic-edges (1)
.SH AUTHORS
Mattias Andrée
diff --git a/man/blind-triangle-tessellation.1 b/man/blind-triangle-tessellation.1
@@ -35,6 +35,7 @@ for more information.
.BR blind-get-colours (1),
.BR blind-apply-palette (1),
.BR blind-mosaic (1),
+.BR blind-mosaic-corners (1),
.BR blind-mosaic-edges (1)
.SH AUTHORS
Mattias Andrée
diff --git a/man/blind.7 b/man/blind.7
@@ -160,6 +160,9 @@ Create an affine 2D-transformation matrix for transposition
.BR blind-mosaic (1)
Redraw each frame in video as a mosaic
.TP
+.BR blind-mosaic-corners (1)
+Find corners in a mosaic video
+.TP
.BR blind-mosaic-edges (1)
Find edges in a mosaic video
.TP
diff --git a/src/blind-mosaic-corners.c b/src/blind-mosaic-corners.c
@@ -0,0 +1,116 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("[-xy]")
+
+static size_t pixsize;
+
+static int
+pixcmp(const void *a, const void *b)
+{
+ return memcmp(a, b, pixsize);
+}
+
+static size_t
+count_unique(char *base, size_t n)
+{
+ size_t ret = 1, i;
+ qsort(base, n, pixsize, pixcmp);
+ for (i = 1; i < n; i++)
+ ret += !!memcmp(base + (i - 1) * pixsize, base + i * pixsize, pixsize);
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int tiled_x = 0;
+ int tiled_y = 0;
+ struct stream stream;
+ void *colours[2];
+ char *buf, *corners, *here, *found;
+ ssize_t dl, dr, du, dd;
+ size_t i, j, n, x, y;
+ int v;
+
+ ARGBEGIN {
+ case 'x':
+ tiled_x = 1;
+ break;
+ case 'y':
+ tiled_y = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc)
+ usage();
+
+ eopen_stream(&stream, NULL);
+ echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+
+ n = stream.width * stream.height;
+ buf = emalloc(stream.frame_size);
+ corners = emalloc((n + 7) / 8);
+
+ found = alloca(9 * stream.pixel_size);
+ colours[0] = alloca(stream.pixel_size);
+ colours[1] = alloca(stream.pixel_size);
+ memset(colours[0], 0, stream.pixel_size);
+
+ if (!strcmp(stream.pixfmt, "xyza")) {
+ ((double *)(colours[1]))[0] = (double)1;
+ ((double *)(colours[1]))[1] = (double)1;
+ ((double *)(colours[1]))[2] = (double)1;
+ ((double *)(colours[1]))[3] = (double)1;
+ } else if (!strcmp(stream.pixfmt, "xyza f")) {
+ ((float *)(colours[1]))[0] = (float)1;
+ ((float *)(colours[1]))[1] = (float)1;
+ ((float *)(colours[1]))[2] = (float)1;
+ ((float *)(colours[1]))[3] = (float)1;
+ } else {
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
+ }
+
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+
+ pixsize = stream.pixel_size;
+ while (eread_frame(&stream, buf)) {
+ memset(corners, 0, (n + 7) / 8);
+ for (i = 0; i < n; i++) {
+ here = buf + i * pixsize;
+ x = i % stream.width;
+ y = i / stream.width;
+ j = 1;
+ memcpy(found, here, pixsize);
+
+ dr = x != stream.width - 1 ? pixsize : tiled_x ? pixsize - stream.row_size : 0;
+ dl = x ? -pixsize : tiled_x ? stream.row_size - pixsize : 0;
+ dd = y != stream.height - 1 ? stream.row_size : tiled_y ? stream.row_size - stream.frame_size : 0;
+ du = y ? -stream.row_size : tiled_y ? stream.frame_size - stream.row_size : 0;
+
+ memcpy(found + j++ * pixsize, here + dr, pixsize);
+ memcpy(found + j++ * pixsize, here + dl, pixsize);
+ memcpy(found + j++ * pixsize, here + dd, pixsize);
+ memcpy(found + j++ * pixsize, here + du, pixsize);
+ memcpy(found + j++ * pixsize, here + dr + du, pixsize);
+ memcpy(found + j++ * pixsize, here + dl + du, pixsize);
+ memcpy(found + j++ * pixsize, here + dr + dd, pixsize);
+ memcpy(found + j++ * pixsize, here + dl + dd, pixsize);
+
+ if (j > 2 && count_unique(found, j) > 2)
+ corners[i >> 3] |= (char)(1 << (i & 7));
+ }
+ for (i = 0; i < n; i++) {
+ v = (corners[i >> 3] >> (i & 7)) & 1;
+ memcpy(buf + i * pixsize, colours[v], pixsize);
+ }
+ ewriteall(STDOUT_FILENO, buf, stream.frame_size, "<stdout>");
+ }
+
+ free(buf);
+ free(corners);
+ return 0;
+}
diff --git a/src/stream.c b/src/stream.c
@@ -128,7 +128,7 @@ set_pixel_format(struct stream *stream, const char *pixfmt)
void
enset_pixel_format(int status, struct stream *stream, const char *pixfmt)
{
- if (!set_pixel_format(stream, pixfmt)) {
+ if (set_pixel_format(stream, pixfmt)) {
if (pixfmt)
enprintf(status, "pixel format %s is not supported, try xyza\n", pixfmt);
else