commit 0a034f2bd5a44c3cc0c033eacc940bb3bf73662c
Author:     Mattias Andrée <maand...@kth.se>
AuthorDate: Tue Jul 18 19:42:27 2017 +0200
Commit:     Mattias Andrée <maand...@kth.se>
CommitDate: Tue Jul 18 19:42:27 2017 +0200

    Add blind-mosaic-corners and fix enset_pixel_format
    
    Signed-off-by: Mattias Andrée <maand...@kth.se>

diff --git a/Makefile b/Makefile
index fb876e1..0b5e73f 100644
--- 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
index 3b9aacd..76c9593 100644
--- 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
index 8062ace..092b6e6 100644
--- 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
new file mode 100644
index 0000000..47ad936
--- /dev/null
+++ 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 < maand...@kth.se >
diff --git a/man/blind-mosaic-edges.1 b/man/blind-mosaic-edges.1
index 92b7edc..265a857 100644
--- 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
index ce93b15..a6cf673 100644
--- 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
index f497977..6bcd4c0 100644
--- 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
index a6c18fc..5f1ca55 100644
--- 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
index 93a0468..ed0b9a9 100644
--- 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
index 98a0a23..e0ec8c5 100644
--- 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
new file mode 100644
index 0000000..ecb9692
--- /dev/null
+++ 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
index 11dabd5..46fed64 100644
--- 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

Reply via email to