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 }