blind-temporal-arithm.c (2413B)
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, void *image); 8 9 #define LIST_OPERATORS(PIXFMT, TYPE)\ 10 X(add, *img + *buf, PIXFMT, TYPE)\ 11 X(mul, *img * *buf, PIXFMT, TYPE)\ 12 X(min, MIN(*img, *buf), PIXFMT, TYPE)\ 13 X(max, MAX(*img, *buf), PIXFMT, TYPE) 14 15 #define X(NAME, ALGO, PIXFMT, TYPE)\ 16 static void\ 17 process_##PIXFMT##_##NAME(struct stream *stream, void *image)\ 18 {\ 19 TYPE *buf, *img = image;\ 20 size_t i, n, j = 0, m = stream->frame_size / sizeof(TYPE);\ 21 do {\ 22 n = stream->ptr / sizeof(TYPE);\ 23 buf = (TYPE *)(stream->buf);\ 24 for (i = 0; i < n; i++, buf++) {\ 25 *img = ALGO;\ 26 if (++j == m) {\ 27 j = 0;\ 28 img = image;\ 29 } else {\ 30 img++;\ 31 }\ 32 }\ 33 n *= sizeof(TYPE);\ 34 memmove(stream->buf, stream->buf + n, stream->ptr -= n);\ 35 } while (eread_stream(stream, SIZE_MAX));\ 36 } 37 LIST_OPERATORS(lf, double) 38 LIST_OPERATORS(f, float) 39 #undef X 40 41 static process_func 42 get_process_lf(const char *operation) 43 { 44 #define X(NAME, _ALGO, PIXFMT, TYPE)\ 45 if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME; 46 LIST_OPERATORS(lf, double) 47 #undef X 48 eprintf("algorithm not recognised: %s\n", operation); 49 return NULL; 50 } 51 52 static process_func 53 get_process_f(const char *operation) 54 { 55 #define X(NAME, _ALGO, PIXFMT, TYPE)\ 56 if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME; 57 LIST_OPERATORS(f, float) 58 #undef X 59 eprintf("algorithm not recognised: %s\n", operation); 60 return NULL; 61 } 62 63 int 64 main(int argc, char *argv[]) 65 { 66 struct stream stream; 67 process_func process; 68 char *img; 69 70 UNOFLAGS(argc != 1); 71 72 eopen_stream(&stream, NULL); 73 74 if (stream.encoding == DOUBLE) 75 process = get_process_lf(argv[0]); 76 else if (stream.encoding == FLOAT) 77 process = get_process_f(argv[0]); 78 else 79 eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); 80 81 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL); 82 img = emalloc(stream.frame_size); 83 if (!eread_frame(&stream, img)) 84 eprintf("video has no frames\n"); 85 86 process(&stream, img); 87 if (stream.ptr) 88 eprintf("%s: incomplete frame\n", stream.file); 89 90 stream.frames = 1; 91 fprint_stream_head(stdout, &stream); 92 efflush(stdout, "<stdout>"); 93 ewriteall(STDOUT_FILENO, img, stream.frame_size, "<stdout>"); 94 free(img); 95 return 0; 96 }