blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | 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 }