1<?php
2
3namespace Mpdf\Color;
4
5class ColorModeConverter
6{
7
8	/**
9	 * @param float[] $c
10	 *
11	 * @return float[]
12	 */
13	public function rgb2gray($c)
14	{
15		if (isset($c[4])) {
16			return [1, ($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07), ord(1), $c[4]];
17		}
18
19		return [1, ($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07)];
20	}
21
22	/**
23	 * @param float[] $c
24	 *
25	 * @return float[]
26	 */
27	public function cmyk2gray($c)
28	{
29		$rgb = $this->cmyk2rgb($c);
30		return $this->rgb2gray($rgb);
31	}
32
33	/**
34	 * @param float[] $c
35	 *
36	 * @return float[]
37	 */
38	public function rgb2cmyk($c)
39	{
40		$cyan = 1 - ($c[1] / 255);
41		$magenta = 1 - ($c[2] / 255);
42		$yellow = 1 - ($c[3] / 255);
43		$min = min($cyan, $magenta, $yellow);
44
45		if ($min == 1) {
46			if ($c[0] == 5) {
47				return [6, 100, 100, 100, 100, $c[4]];
48			}
49
50			return [4, 100, 100, 100, 100];
51			// For K-Black
52			//if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
53			//else { return array (4,0,0,0,100); }
54		}
55
56		$K = $min;
57		$black = 1 - $K;
58		if ($c[0] == 5) {
59			return [6, ($cyan - $K) * 100 / $black, ($magenta - $K) * 100 / $black, ($yellow - $K) * 100 / $black, $K * 100, $c[4]];
60		}
61
62		return [4, ($cyan - $K) * 100 / $black, ($magenta - $K) * 100 / $black, ($yellow - $K) * 100 / $black, $K * 100];
63	}
64
65	/**
66	 * @param float[] $c
67	 *
68	 * @return float[]
69	 */
70	public function cmyk2rgb($c)
71	{
72		$rgb = [];
73		$colors = 255 - ($c[4] * 2.55);
74		$rgb[0] = (int) ($colors * (255 - ($c[1] * 2.55)) / 255);
75		$rgb[1] = (int) ($colors * (255 - ($c[2] * 2.55)) / 255);
76		$rgb[2] = (int) ($colors * (255 - ($c[3] * 2.55)) / 255);
77		if ($c[0] == 6) {
78			return [5, $rgb[0], $rgb[1], $rgb[2], $c[5]];
79		}
80
81		return [3, $rgb[0], $rgb[1], $rgb[2]];
82	}
83
84	/**
85	 * @param float $r
86	 * @param float $g
87	 * @param float $b
88	 *
89	 * @return float[]
90	 */
91	public function rgb2hsl($r, $g, $b)
92	{
93		$h = 0;
94
95		$min = min($r, $g, $b);
96		$max = max($r, $g, $b);
97
98		$diff = $max - $min;
99		$l = ($max + $min) / 2;
100
101		if ($diff == 0) {
102			$h = 0;
103			$s = 0;
104		} else {
105
106			if ($l < 0.5) {
107				$s = $diff / ($max + $min);
108			} else {
109				$s = $diff / (2 - $max - $min);
110			}
111
112			$rDiff = ((($max - $r) / 6) + ($diff / 2)) / $diff;
113			$gDiff = ((($max - $g) / 6) + ($diff / 2)) / $diff;
114			$bDiff = ((($max - $b) / 6) + ($diff / 2)) / $diff;
115
116			if ($r == $max) {
117				$h = $bDiff - $gDiff;
118			} elseif ($g == $max) {
119				$h = (1 / 3) + $rDiff - $bDiff;
120			} elseif ($b == $max) {
121				$h = (2 / 3) + $gDiff - $rDiff;
122			}
123
124			if ($h < 0) {
125				++$h;
126			}
127
128			if ($h > 1) {
129				--$h;
130			}
131		}
132
133		return [$h, $s, $l];
134	}
135
136	/**
137	 * Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
138	 * Output is RGB in normal 255 255 255 format, held in $r, $g, $b
139	 *
140	 * @param float $h
141	 * @param float $s
142	 * @param float $l
143	 *
144	 * @return float[]
145	 */
146	public function hsl2rgb($h, $s, $l)
147	{
148		if ($s == 0) {
149			$r = $l * 255;
150			$g = $l * 255;
151			$b = $l * 255;
152		} else {
153			if ($l < 0.5) {
154				$tmp = $l * (1 + $s);
155			} else {
156				$tmp = ($l + $s) - ($s * $l);
157			}
158			$tmp2 = 2 * $l - $tmp;
159			$r = round(255 * $this->hue2rgb($tmp2, $tmp, $h + (1 / 3)));
160			$g = round(255 * $this->hue2rgb($tmp2, $tmp, $h));
161			$b = round(255 * $this->hue2rgb($tmp2, $tmp, $h - (1 / 3)));
162		}
163
164		return [$r, $g, $b];
165	}
166
167	/**
168	 * @param float $v1
169	 * @param float $v2
170	 * @param float $vh
171	 *
172	 * @return float
173	 */
174	public function hue2rgb($v1, $v2, $vh)
175	{
176		if ($vh < 0) {
177			++$vh;
178		}
179
180		if ($vh > 1) {
181			--$vh;
182		}
183
184		if ((6 * $vh) < 1) {
185			return ($v1 + ($v2 - $v1) * 6 * $vh);
186		}
187
188		if ((2 * $vh) < 1) {
189			return $v2;
190		}
191
192		if ((3 * $vh) < 2) {
193			return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6));
194		}
195
196		return $v1;
197	}
198
199}
200