blind-set-saturation.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-set-saturation.c (2474B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include "common.h"
            3 
            4 USAGE("[-w] saturation-stream")
            5 
            6 #define PROCESS(TYPE)\
            7         do {\
            8                 size_t i;\
            9                 TYPE s, *x, y, *z;\
           10                 for (i = 0; i < n; i += colour->pixel_size) {\
           11                         s = ((TYPE *)(satur->buf + i))[1];\
           12                         s *= ((TYPE *)(satur->buf + i))[3];\
           13                         x = ((TYPE *)(colour->buf + i)) + 0;\
           14                         y = ((TYPE *)(colour->buf + i))[1];\
           15                         z = ((TYPE *)(colour->buf + i)) + 2;\
           16                         *x = ((*x / (TYPE)D65_XYZ_X - y) * s + y) * (TYPE)D65_XYZ_X;\
           17                         *z = ((*z / (TYPE)D65_XYZ_Z - y) * s + y) * (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)\
           28         do {\
           29                 size_t i;\
           30                 TYPE s, *x, y, *z, X, Z;\
           31                 for (i = 0; i < n; i += colour->pixel_size) {\
           32                         X = ((TYPE *)(satur->buf + i))[0];\
           33                         Z = ((TYPE *)(satur->buf + i))[2];\
           34                         s = ((TYPE *)(satur->buf + i))[1];\
           35                         s *= ((TYPE *)(satur->buf + i))[3];\
           36                         x = ((TYPE *)(colour->buf + i)) + 0;\
           37                         y = ((TYPE *)(colour->buf + i))[1];\
           38                         z = ((TYPE *)(colour->buf + i)) + 2;\
           39                         *x = ((*x / X - y) * s + y) * X;\
           40                         *z = ((*z / Z - y) * s + y) * Z;\
           41                 }\
           42         } while (0)
           43 
           44 static void process_lf  (struct stream *colour, struct stream *satur, size_t n) {PROCESS(double);}
           45 static void process_lf_w(struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(double);}
           46 static void process_f   (struct stream *colour, struct stream *satur, size_t n) {PROCESS(float);}
           47 static void process_f_w (struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(float);}
           48 
           49 int
           50 main(int argc, char *argv[])
           51 {
           52         struct stream colour, satur;
           53         int whitepoint = 0;
           54         void (*process)(struct stream *colour, struct stream *satur, size_t n);
           55 
           56         ARGBEGIN {
           57         case 'w':
           58                 whitepoint = 1;
           59                 break;
           60         default:
           61                 usage();
           62         } ARGEND;
           63 
           64         if (argc != 1)
           65                 usage();
           66 
           67         eopen_stream(&colour, NULL);
           68         eopen_stream(&satur, argv[0]);
           69 
           70         CHECK_COLOUR_SPACE(&colour, CIEXYZ);
           71         CHECK_CHANS(&colour, == 3, == 1);
           72         if (colour.encoding == DOUBLE)
           73                 process = whitepoint ? process_lf_w : process_lf;
           74         else if (colour.encoding == FLOAT)
           75                 process = whitepoint ? process_f_w : process_f;
           76         else
           77                 eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
           78 
           79         fprint_stream_head(stdout, &colour);
           80         efflush(stdout, "<stdout>");
           81         process_two_streams(&colour, &satur, STDOUT_FILENO, "<stdout>", process);
           82         return 0;
           83 }