| blind-set-luma.c - blind - suckless command-line video editing utility | |
| git clone git://git.suckless.org/blind | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| blind-set-luma.c (3592B) | |
| --- | |
| 1 /* See LICENSE file for copyright and license details. */ | |
| 2 #ifndef TYPE | |
| 3 #include "common.h" | |
| 4 | |
| 5 USAGE("luma-stream") | |
| 6 | |
| 7 #define FILE "blind-set-luma.c" | |
| 8 #include "define-functions.h" | |
| 9 | |
| 10 int | |
| 11 main(int argc, char *argv[]) | |
| 12 { | |
| 13 struct stream colour, luma; | |
| 14 void (*process)(struct stream *colour, struct stream *luma, size… | |
| 15 | |
| 16 UNOFLAGS(argc != 1); | |
| 17 | |
| 18 eopen_stream(&colour, NULL); | |
| 19 eopen_stream(&luma, argv[0]); | |
| 20 | |
| 21 SELECT_PROCESS_FUNCTION(&colour); | |
| 22 CHECK_CHANS(&colour, == 3, == 1); | |
| 23 CHECK_COLOUR_SPACE(&colour, CIEXYZ); | |
| 24 | |
| 25 fprint_stream_head(stdout, &colour); | |
| 26 efflush(stdout, "<stdout>"); | |
| 27 process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", p… | |
| 28 return 0; | |
| 29 } | |
| 30 | |
| 31 #else | |
| 32 | |
| 33 static void | |
| 34 PROCESS(struct stream *colour, struct stream *luma, size_t n) | |
| 35 {\ | |
| 36 size_t i; | |
| 37 TYPE a, y; | |
| 38 for (i = 0; i < n; i += colour->pixel_size) { | |
| 39 a = ((TYPE *)(luma->buf + i))[1]; | |
| 40 a *= ((TYPE *)(luma->buf + i))[3]; | |
| 41 y = ((TYPE *)(colour->buf + i))[1]; | |
| 42 ((TYPE *)(colour->buf + i))[0] += y * a - y; | |
| 43 ((TYPE *)(colour->buf + i))[1] = y * a; | |
| 44 ((TYPE *)(colour->buf + i))[2] += y * a - y; | |
| 45 /* | |
| 46 * Note, this changes the luma only, not the saturation, | |
| 47 * so the result may look a bit weird. To change both | |
| 48 * you can use `blind-arithm mul`. | |
| 49 * | |
| 50 * Explaination of algorithm: | |
| 51 * | |
| 52 * Y is the luma, but (X, Z) is not the chroma, | |
| 53 * but in CIELAB, L* is the luma and (a*, *b) is | |
| 54 * the chroma. Multiplying | |
| 55 * | |
| 56 * ⎛0 1 0⎞ | |
| 57 * ⎜1 −1 0⎟ | |
| 58 * ⎝0 1 −1⎠ | |
| 59 * | |
| 60 * (X Y Z)' gives a colour model similar to | |
| 61 * CIE L*a*b*: a model where each parameter is | |
| 62 * a linear transformation of the corresponding | |
| 63 * parameter in CIE L*a*b*. The inverse of that | |
| 64 * matrix is | |
| 65 * | |
| 66 * ⎛1 1 0⎞ | |
| 67 * ⎜1 0 0⎟ | |
| 68 * ⎝0 0 −1⎠ | |
| 69 * | |
| 70 * and | |
| 71 * | |
| 72 * ⎛1 1 0⎞⎛a 0 0⎞⎛0 1 0⎞ ⎛1 a−… | |
| 73 * ⎜1 0 0⎟⎜0 1 0⎟⎜1 −1 0⎟ = ⎜0 a… | |
| 74 * ⎝0 0 −1⎠⎝0 0 1⎠⎝0 1 −1⎠ ⎝0 … | |
| 75 * | |
| 76 * Explanation of why changing only the luma looks weird: | |
| 77 * | |
| 78 * Consider when you are workings with colours, | |
| 79 * when you want to change the brightness of a | |
| 80 * colour, you multiply all parameters: red, green, | |
| 81 * and blue, with the same value (this is however | |
| 82 * only an approximation in most cases, since you | |
| 83 * are usually usally working with colours that | |
| 84 * have the sRGB transfer function applied to their | |
| 85 * parameters). This action is the same in all | |
| 86 * colour models and colour spaces that are a | |
| 87 * linear transformation of the sRGB colour spaces | |
| 88 * (sans transfer function); this is simply because | |
| 89 * of the properties of linear transformations. | |
| 90 * | |
| 91 * The reason you change brightness this way can | |
| 92 * be explained by how objects reflect colour. | |
| 93 * Objects can only reject colours that are present | |
| 94 * in the light source. A ideal white object will look | |
| 95 * pure red if the light sources is ideal red, and a | |
| 96 * a ideal blue object will pure black in the same | |
| 97 * light source. An object can also not reflect | |
| 98 * colours brighter than the source. When the brightne… | |
| 99 * of a light source is changed, the intensity of all | |
| 100 * colours (by wavelength) it emits is multiplied by | |
| 101 * one value. Therefore, when changing the brightness | |
| 102 * it looks most natural when all primaries (red, gree… | |
| 103 * and blue) are multiplied by one value, or all | |
| 104 * parameters of the used colour spaces is a linear | |
| 105 * transformation of sRGB, such as CIE XYZ. | |
| 106 */ | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 #endif |