blind-spatial-arithm.c - blind - suckless command-line video editing utility
 (HTM) git clone git://git.suckless.org/blind
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       blind-spatial-arithm.c (2546B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include "common.h"
            3 
            4 USAGE("operation")
            5 
            6 /* Because the syntax for a function returning a function pointer is disgusting. */
            7 typedef void (*process_func)(struct stream *stream);
            8 
            9 #define LIST_OPERATORS(PIXFMT, TYPE)\
           10         X(add, img[j & 3] + *buf,     PIXFMT, TYPE)\
           11         X(mul, img[j & 3] * *buf,     PIXFMT, TYPE)\
           12         X(min, MIN(img[j & 3], *buf), PIXFMT, TYPE)\
           13         X(max, MAX(img[j & 3], *buf), PIXFMT, TYPE)
           14 
           15 #define X(NAME, ALGO, PIXFMT, TYPE)\
           16         static void\
           17         process_##PIXFMT##_##NAME(struct stream *stream)\
           18         {\
           19                 TYPE img[4], *buf;\
           20                 size_t i, n, j = 0, m = stream->frame_size / sizeof(*img);\
           21                 int first = 1;\
           22                 do {\
           23                         n = stream->ptr / stream->pixel_size * stream->n_chan;\
           24                         buf = (TYPE *)(stream->buf);\
           25                         for (i = 0; i < n; i++, buf++, j++, j %= m) {\
           26                                 if (!j) {\
           27                                         if (!first)\
           28                                                 ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\
           29                                         first = 0;\
           30                                         img[0] = *buf++;\
           31                                         img[1] = *buf++;\
           32                                         img[2] = *buf++;\
           33                                         img[3] = *buf;\
           34                                         i += 3;\
           35                                         j = 3;\
           36                                 } else {\
           37                                         img[j & 3] = ALGO;\
           38                                 }\
           39                         }\
           40                         n *= sizeof(TYPE);\
           41                         memmove(stream->buf, stream->buf + n, stream->ptr -= n);\
           42                 } while (eread_stream(stream, SIZE_MAX));\
           43                 if (!first)\
           44                         ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\
           45         }
           46 LIST_OPERATORS(lf, double)
           47 LIST_OPERATORS(f, float)
           48 #undef X
           49 
           50 static process_func
           51 get_process_lf(const char *operation)
           52 {
           53 #define X(NAME, _ALGO, PIXFMT, TYPE)\
           54         if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME;
           55         LIST_OPERATORS(lf, double)
           56 #undef X
           57         eprintf("algorithm not recognised: %s\n", operation);
           58         return NULL;
           59 }
           60 
           61 static process_func
           62 get_process_f(const char *operation)
           63 {
           64 #define X(NAME, _ALGO, PIXFMT, TYPE)\
           65         if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME;
           66         LIST_OPERATORS(f, float)
           67 #undef X
           68         eprintf("algorithm not recognised: %s\n", operation);
           69         return NULL;
           70 }
           71 
           72 int
           73 main(int argc, char *argv[])
           74 {
           75         struct stream stream;
           76         process_func process;
           77 
           78         UNOFLAGS(argc != 1);
           79 
           80         eopen_stream(&stream, NULL);
           81         echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
           82 
           83         CHECK_N_CHAN(&stream, 4, 4);
           84         if (stream.encoding == DOUBLE)
           85                 process = get_process_lf(argv[0]);
           86         else if (stream.encoding == FLOAT)
           87                 process = get_process_f(argv[0]);
           88         else
           89                 eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
           90 
           91         if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixfmt) < 0)
           92                 eprintf("dprintf:");
           93         process(&stream);
           94         if (stream.ptr)
           95                 eprintf("%s: incomplete frame\n", stream.file);
           96         return 0;
           97 }