18921e4368313ea06c842e2d9bd1648b35b81db7
[xonotic/mediasource.git] / gfx / luma / tools / hsv-matrix.pl
1 #!/usr/bin/perl
2 # TASK
3 #   Calculate compound HSV feColorMatrix for svg filter:
4 #   http://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
5 #
6 # USAGE
7 #   $0 HUE(degrees) SATURATION VALUE
8
9
10 use strict;
11 use warnings;
12
13
14 my $hue = $ARGV[0]*3.14159/180.0;
15 my $sat = $ARGV[1];
16 my $val = $ARGV[2];
17
18
19 # Luminance vectors
20 my @lum = (0.2126, 0.7152, 0.0722);
21 my @inv = (1.0-$lum[0], 1.0-$lum[1], 1.0-$lum[2]);
22
23
24 # Hue transformation matrix
25 my @h = (
26         [$lum[0]+cos($hue)*$inv[0]-sin($hue)*$lum[0],
27          $lum[1]-cos($hue)*$lum[1]-sin($hue)*$lum[1],
28          $lum[2]-cos($hue)*$lum[2]+sin($hue)*$inv[2]],
29
30         [$lum[0]-cos($hue)*$lum[0]+sin($hue)*0.143,
31          $lum[1]+cos($hue)*$inv[1]+sin($hue)*0.140,
32          $lum[2]-cos($hue)*$lum[2]-sin($hue)*0.283],
33
34         [$lum[0]-cos($hue)*$lum[0]-sin($hue)*$inv[0],
35          $lum[1]-cos($hue)*$lum[1]+sin($hue)*$lum[1],
36          $lum[2]+cos($hue)*$inv[2]+sin($hue)*$lum[2]]
37 );
38
39
40 # Saturation transformation matrix
41 my @s = (
42         [$lum[0]+$inv[0]*$sat, $lum[1]-$lum[1]*$sat, $lum[2]-$lum[2]*$sat],
43         [$lum[0]-$lum[0]*$sat, $lum[1]+$inv[1]*$sat, $lum[2]-$lum[2]*$sat],
44         [$lum[0]-$lum[0]*$sat, $lum[1]-$lum[1]*$sat, $lum[2]+$inv[2]*$sat]
45 );
46
47
48 # Print feColorMatrix (HxSxV)
49 my $f = '%.2f';
50 printf("$f $f $f 0 0 $f $f $f 0 0 $f $f $f 0 0 0 0 0 1 0\n",
51         ($h[0][0]*$s[0][0]+$h[0][1]*$s[1][0]+$h[0][2]*$s[2][0])*$val,
52         ($h[0][0]*$s[0][1]+$h[0][1]*$s[1][1]+$h[0][2]*$s[2][1])*$val,
53         ($h[0][0]*$s[0][2]+$h[0][1]*$s[1][2]+$h[0][2]*$s[2][2])*$val,
54
55         ($h[1][0]*$s[0][0]+$h[1][1]*$s[1][0]+$h[1][2]*$s[2][0])*$val,
56         ($h[1][0]*$s[0][1]+$h[1][1]*$s[1][1]+$h[1][2]*$s[2][1])*$val,
57         ($h[1][0]*$s[0][2]+$h[1][1]*$s[1][2]+$h[1][2]*$s[2][2])*$val,
58
59         ($h[2][0]*$s[0][0]+$h[2][1]*$s[1][0]+$h[2][2]*$s[2][0])*$val,
60         ($h[2][0]*$s[0][1]+$h[2][1]*$s[1][1]+$h[2][2]*$s[2][1])*$val,
61         ($h[2][0]*$s[0][2]+$h[2][1]*$s[1][2]+$h[2][2]*$s[2][2])*$val);