blind-affine-colour.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-affine-colour.c (3345B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #ifndef TYPE
            3 #include "common.h"
            4 
            5 USAGE("[-alp] matrix-stream")
            6 
            7 static int skip_alpha = 0;
            8 static int linear = 0;
            9 static int per_pixel = 0;
           10 static size_t dim;
           11 
           12 #define FILE "blind-affine-colour.c"
           13 #include "define-functions.h"
           14 
           15 int
           16 main(int argc, char *argv[])
           17 {
           18         struct stream colour, matrix;
           19         void (*process)(struct stream *colour, struct stream *matrix);
           20         size_t h;
           21 
           22         ARGBEGIN {
           23         case 'a':
           24                 skip_alpha = 1;
           25                 break;
           26         case 'l':
           27                 linear = 1;
           28                 break;
           29         case 'p':
           30                 per_pixel = 1;
           31                 break;
           32         default:
           33                 usage();
           34         } ARGEND;
           35 
           36         if (argc != 1)
           37                 usage();
           38 
           39         eopen_stream(&colour, NULL);
           40         eopen_stream(&matrix, argv[0]);
           41 
           42         SELECT_PROCESS_FUNCTION(&colour);
           43         if (skip_alpha && colour.alpha_chan != -1)
           44                 CHECK_CHANS(&colour, == (short int)(colour.n_chan - 1), == colour.luma_chan);
           45         else
           46                 skip_alpha = 0;
           47 
           48         if (strcmp(colour.pixfmt, matrix.pixfmt))
           49                 eprintf("videos use incompatible pixel formats\n");
           50 
           51         dim = colour.n_chan - (size_t)skip_alpha + (size_t)!linear;
           52         h = matrix.height, matrix.height = dim;
           53         echeck_dimensions(&matrix, WIDTH | HEIGHT, "matrix");
           54         matrix.height = h;
           55 
           56         if (per_pixel) {
           57                 if (matrix.height != dim * colour.height || matrix.width != dim * colour.width)
           58                         eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
           59                                 dim * colour.height, dim * colour.width, matrix.height, matrix.width);
           60         } else {
           61                 if (matrix.height != dim || matrix.width != dim)
           62                         eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
           63                                 dim, dim, matrix.height, matrix.width);
           64         }
           65 
           66         fprint_stream_head(stdout, &colour);
           67         efflush(stdout, "<stdout>");
           68         process(&colour, &matrix);
           69         return 0;
           70 }
           71 
           72 #else
           73 
           74 static void
           75 PROCESS(struct stream *colour, struct stream *matrix)
           76 {
           77         char *mbuf;
           78         TYPE *mat, *pixel, V[5], M[ELEMENTSOF(V)][ELEMENTSOF(V)];
           79         size_t ptr, i, j, w, x = 0, y = 0, cn;
           80 
           81         mbuf = emalloc2(dim, matrix->row_size);
           82         mat = (TYPE *)mbuf;
           83         w = matrix->width * matrix->n_chan;
           84         cn = colour->n_chan - (size_t)skip_alpha;
           85 
           86         memset(M, 0, sizeof(M));
           87         for (i = 0; i < ELEMENTSOF(V); i++)
           88                 M[i][i] = V[i] = 1;
           89 
           90         do {
           91                 for (ptr = 0; ptr + colour->pixel_size <= colour->ptr; x = (x + 1) % colour->width, ptr += colour->pixel_size) {
           92                         if (!x) {
           93                                 if (!y && !eread_segment(matrix, mbuf, dim * matrix->row_size))
           94                                         break;
           95                                 if (!per_pixel) {
           96                                         if (!y) {
           97                                                 mat = (TYPE *)mbuf;
           98                                                 for (i = 0; i < dim; i++, mat += w)
           99                                                         for (j = 0; j < dim; j++)
          100                                                                 M[i][j] = mat[j * matrix->n_chan + 1]
          101                                                                         * mat[(j + 1) * matrix->n_chan - 1];
          102                                         }
          103                                         y = (y + 1) % colour->height;
          104                                 }
          105                         }
          106                         if (per_pixel) {
          107                                 mat = (TYPE *)(mbuf + x * dim * matrix->pixel_size);
          108                                 for (i = 0; i < dim; i++, mat += w)
          109                                         for (j = 0; j < dim; j++)
          110                                                 M[i][j] = mat[j * matrix->n_chan + 1]
          111                                                         * mat[(j + 1) * matrix->n_chan - 1];
          112                         }
          113                         pixel = (TYPE *)(colour->buf + ptr);
          114                         for (i = 0; i < dim; i++) {
          115                                 V[i] = 0;
          116                                 for (j = 0; j < cn; j++)
          117                                         V[i] += M[i][j] * pixel[j];
          118                                 for (; j < dim; j++)
          119                                         V[i] += M[i][j];
          120                         }
          121                         for (i = 0; i < cn; i++)
          122                                 pixel[i] = V[i] / V[cn];
          123                 }
          124                 ewriteall(STDOUT_FILENO, colour->buf, ptr, "<stdout>");
          125                 memmove(colour->buf, colour->buf + ptr, colour->ptr -= ptr);
          126         } while (eread_stream(colour, SIZE_MAX));
          127         if (colour->ptr)
          128                 eprintf("%s: incomplete frame\n", colour->file);
          129 
          130         free(mbuf);
          131 }
          132 
          133 #endif