blind-make-kernel.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-make-kernel.c (3372B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include "common.h"
            3 
            4 USAGE("[-d denominator] ... [-nxyza] [-- value ...] ...")
            5 
            6 static void
            7 new_row(double **kernel, size_t *col, size_t *rows, size_t *cols)
            8 {
            9         if (!*col)
           10                 return;
           11         if (*rows && *col != *cols)
           12                 eprintf("the rows in the matrix do not have the same number of columns\n");
           13         *kernel = erealloc3(*kernel, 1 + ++*rows, *cols = *col, sizeof(**kernel));
           14         *col = 0;
           15 }
           16 
           17 static void
           18 new_col(char *arg, double **kernel, size_t *col, size_t *rows, size_t *cols)
           19 {
           20         if (*rows && *col >= *cols)
           21                 eprintf("the rows in the matrix do not have the same number of columns\n");
           22         if (!*rows)
           23                 *kernel = erealloc2(*kernel, *col + 1, sizeof(**kernel));
           24         if (tolf(arg, &(*kernel)[*rows * *cols + (*col)++]))
           25                 eprintf("matrix cell values must be floating-point values\n");
           26 }
           27 
           28 static void
           29 finalise(double **kernel, size_t col, size_t *rows, size_t *cols)
           30 {
           31         if (col)
           32                 new_row(kernel, &col, rows, cols);
           33         if (!*rows)
           34                 eprintf("the matrix cannot be null-sized\n");
           35 }
           36 
           37 static double *
           38 read_matrix_cmdline(char *args[], size_t *rows, size_t *cols)
           39 {
           40         size_t col = 0;
           41         double *kernel = NULL;
           42         *rows = *cols = 0;
           43         for (; *args; args++) {
           44                 if (!strcmp(*args, "--"))
           45                         new_row(&kernel, &col, rows, cols);
           46                 else
           47                         new_col(*args, &kernel, &col, rows, cols);
           48         }
           49         finalise(&kernel, col, rows, cols);
           50         return kernel;
           51 }
           52 
           53 static double *
           54 read_matrix_stdin(size_t *rows, size_t *cols)
           55 {
           56         char *line = NULL, *p, *q;
           57         size_t size = 0, col = 0;
           58         double *kernel = NULL;
           59         ssize_t len;
           60         *rows = *cols = 0;
           61         while ((len = getline(&line, &size, stdin)) >= 0) {
           62                 col = 0;
           63                 for (p = line;; p = q) {
           64                         while (*p && isspace(*p)) p++;
           65                         if (!*(q = p))
           66                                 break;
           67                         while (*q && !isspace(*q)) q++;
           68                         *q++ = '\0';
           69                         new_col(p, &kernel, &col, rows, cols);
           70                 }
           71                 new_row(&kernel, &col, rows, cols);
           72         }
           73         free(line);
           74         if (ferror(stdout))
           75                 eprintf("getline:");
           76         finalise(&kernel, col, rows, cols);
           77         return kernel;
           78 }
           79 
           80 int
           81 main(int argc, char *argv[])
           82 {
           83         int normalise = 0;
           84         double denominator = 1;
           85         int id_x = 1, id_y = 1, id_z = 1, id_a = 1;
           86         size_t rows, cols, y, x, n;
           87         double *kernel, *kern, sum = 0, value;
           88         double *buffer, *buf, id_val;
           89 
           90         ARGBEGIN {
           91         case 'd':
           92                 denominator *= etolf_flag('d', UARGF());
           93                 break;
           94         case 'n':
           95                 normalise = 1;
           96                 break;
           97         case 'x':
           98                 id_x = 0;
           99                 break;
          100         case 'y':
          101                 id_y = 0;
          102                 break;
          103         case 'z':
          104                 id_z = 0;
          105                 break;
          106         case 'a':
          107                 id_a = 0;
          108                 break;
          109         default:
          110                 usage();
          111         } ARGEND;
          112 
          113         if (id_x && id_y && id_z && id_a)
          114                 id_x = id_y = id_z = id_a = 0;
          115 
          116         if (argc)
          117                 kernel = read_matrix_cmdline(argv, &rows, &cols);
          118         else
          119                 kernel = read_matrix_stdin(&rows, &cols);
          120 
          121         FPRINTF_HEAD(stdout, (size_t)1, cols, rows, "xyza");
          122         efflush(stdout, "<stdout>");
          123 
          124         buffer = emalloc2(cols, 4 * sizeof(double));
          125         n = cols * 4 * sizeof(double);
          126 
          127         if (normalise) {
          128                 kern = kernel;
          129                 for (y = 0; y < rows; y++)
          130                         for (x = 0; x < cols; x++)
          131                                 sum += *kern++;
          132                 denominator *= sum;
          133         }
          134 
          135         kern = kernel;
          136         for (y = 0; y < rows; y++) {
          137                 buf = buffer;
          138                 for (x = 0; x < cols; x++) {
          139                         id_val = (x == cols / 2 && y == rows / 2) ? 1. : 0.;
          140                         value = *kern++ / denominator;
          141                         buf[0] = id_x ? id_val : value;
          142                         buf[1] = id_y ? id_val : value;
          143                         buf[2] = id_z ? id_val : value;
          144                         buf[3] = id_a ? id_val : value;
          145                         buf += 4;
          146                 }
          147                 ewriteall(STDOUT_FILENO, buffer, n, "<stdout>");
          148         }
          149 
          150         free(kernel);
          151         free(buffer);
          152         return 0;
          153 }