blind-invert-luma.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-invert-luma.c (3065B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include "common.h"
            3 
            4 USAGE("[-iw] mask-stream")
            5 
            6 #define PROCESS(TYPE, INV)\
            7         do {\
            8                 size_t i;\
            9                 TYPE w, y, yo;\
           10                 for (i = 0; i < n; i += colour->pixel_size) {\
           11                         w = INV ((TYPE *)(mask->buf + i))[1];\
           12                         w *= ((TYPE *)(mask->buf + i))[3];\
           13                         yo = ((TYPE *)(colour->buf + i))[1];\
           14                         y = (1 - yo) * w + yo * (1 - w);\
           15                         ((TYPE *)(colour->buf + i))[0] += (y - yo) * (TYPE)D65_XYZ_X;\
           16                         ((TYPE *)(colour->buf + i))[1] = y;\
           17                         ((TYPE *)(colour->buf + i))[2] += (y - yo) * (TYPE)D65_XYZ_Z;\
           18                         /*
           19                          * Explaination:
           20                          *   Y is the luma and ((X / Xn - Y / Yn), (Z / Zn - Y / Yn))
           21                          *   is the chroma (according to CIELAB), where (Xn, Yn, Zn)
           22                          *   is the white point.
           23                          */\
           24                 }\
           25         } while (0)
           26 
           27 #define PROCESS_W(TYPE, INV)\
           28         do {\
           29                 size_t i;\
           30                 TYPE w, y, yo, X, Z;\
           31                 for (i = 0; i < n; i += colour->pixel_size) {\
           32                         X = ((TYPE *)(mask->buf + i))[0];\
           33                         Z = ((TYPE *)(mask->buf + i))[2];\
           34                         w = INV ((TYPE *)(mask->buf + i))[1];\
           35                         w *= ((TYPE *)(mask->buf + i))[3];\
           36                         yo = ((TYPE *)(colour->buf + i))[1];\
           37                         y = (1 - yo) * w + yo * (1 - w);\
           38                         ((TYPE *)(colour->buf + i))[0] += (y - yo) * X;\
           39                         ((TYPE *)(colour->buf + i))[1] = y;\
           40                         ((TYPE *)(colour->buf + i))[2] += (y - yo) * Z;\
           41                 }\
           42         } while (0)
           43 
           44 static void process_lf   (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double,);}
           45 static void process_lf_i (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double, 1 -);}
           46 static void process_lf_w (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double,);}
           47 static void process_lf_iw(struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double, 1 -);}
           48 static void process_f    (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float,);}
           49 static void process_f_i  (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float, 1 -);}
           50 static void process_f_w  (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float,);}
           51 static void process_f_iw (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float, 1 -);}
           52 
           53 int
           54 main(int argc, char *argv[])
           55 {
           56         int invert = 0, whitepoint = 0;
           57         struct stream colour, mask;
           58         void (*process)(struct stream *colour, struct stream *mask, size_t n);
           59 
           60         ARGBEGIN {
           61         case 'i':
           62                 invert = 1;
           63                 break;
           64         case 'w':
           65                 whitepoint = 1;
           66                 break;
           67         default:
           68                 usage();
           69         } ARGEND;
           70 
           71         if (argc != 1)
           72                 usage();
           73 
           74         eopen_stream(&colour, NULL);
           75         eopen_stream(&mask, argv[0]);
           76 
           77         CHECK_ALPHA(&colour);
           78         CHECK_COLOUR_SPACE(&colour, CIEXYZ);
           79         if (colour.encoding == DOUBLE)
           80                 process = invert ? whitepoint ? process_lf_iw : process_lf_i
           81                                  : whitepoint ? process_lf_w  : process_lf;
           82         else if (colour.encoding == FLOAT)
           83                 process = invert ? whitepoint ? process_f_iw : process_f_i
           84                                  : whitepoint ? process_f_w  : process_f;
           85         else
           86                 eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
           87 
           88         fprint_stream_head(stdout, &colour);
           89         efflush(stdout, "<stdout>");
           90         process_two_streams(&colour, &mask, STDOUT_FILENO, "<stdout>", process);
           91         return 0;
           92 }