functions.php ➔ C256toRGB()   C
last analyzed

Complexity

Conditions 11
Paths 9

Size

Total Lines 42
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 11.0086

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 24
c 2
b 0
f 0
nc 9
nop 1
dl 0
loc 42
ccs 23
cts 24
cp 0.9583
crap 11.0086
rs 5.2653

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Scriptura\Color\Helpers;
4
5
/**
6
 * Converts a color from hex to rgb.
7
 *
8
 * eg.
9
 * 'FF5F47' => [255, 95, 71]
10
 *
11
 * @param string $code Hex code without #
12
 *
13
 * @return int[] [red(0-255), green(0-255), blue(0-255)]
14
 */
15
function HEXtoRGB($code)
16
{
17 33
    return array_map('hexdec', str_split($code, 2));
18
}
19
20
/**
21
 * Converts a color from rgb to hex.
22
 *
23
 * eg.
24
 * [255, 95, 71] => 'FF5F47'
25
 *
26
 * @param int $red Decimal in range 0-255
27
 * @param int $green Decimal in range 0-255
28
 * @param int $blue Decimal in range 0-255
29
 *
30
 * @return string
31
 */
32
function RGBtoHEX($red, $green, $blue)
33
{
34 33
    return implode('', [
35 33
        sprintf('%02x', $red),
36 33
        sprintf('%02x', $green),
37 33
        sprintf('%02x', $blue),
38 33
    ]);
39
}
40
41
/**
42
 * Converts a color from rgb to hsl.
43
 *
44
 * eg.
45
 * [255, 95, 71] => [8, 100, 64]
46
 *
47
 * http://www.rapidtables.com/convert/color/rgb-to-hsl.htm
48
 *
49
 * $min = Smallest part of the color
50
 * $max = Largest part of the color
51
 * $c = Chroma
52
 *
53
 * @param int $red Decimal in range 0-255
54
 * @param int $green Decimal in range 0-255
55
 * @param int $blue Decimal in range 0-255
56
 *
57
 * @return int[] [hue(0-360°), saturation(0-100%), lightness(0-100%)]
58
 */
59
function RGBtoHSL($red, $green, $blue)
60
{
61 33
    $red /= 255;
62 33
    $green /= 255;
63 33
    $blue /= 255;
64
65 33
    $min = min($red, $green, $blue);
66 33
    $max = max($red, $green, $blue);
67 33
    $c = $max - $min;
68
69 33
    $hue = 0;
70 33
    $saturation = 0;
71 33
    $lightness = ($max + $min) / 2;
72
73 33
    if ($c != 0) {
74
        switch ($max) {
75 22
            case $red:
76 12
                $hue = fmod(($green - $blue) / $c, 6);
77 12
                break;
78 10
            case $green:
79 5
                $hue = (($blue - $red) / $c) + 2;
80 5
                break;
81 5
            case $blue:
82 5
                $hue = (($red - $green) / $c) + 4;
83 5
                break;
84
        }
85
86 22
        $hue *= 60;
87
88 22
        if ($hue < 0) {
89 2
            $hue += 360;
90 2
        }
91
92 22
        $saturation = $c / (1 - abs(2 * $lightness - 1));
93 22
    }
94
95
    return [
96 33
        (int) round($hue, 0),
97 33
        (int) round($saturation * 100, 0),
98 33
        (int) round($lightness * 100, 0),
99 33
    ];
100
}
101
102
/**
103
 * Converts a color from hsl to rgb.
104
 *
105
 * eg.
106
 * [8, 100, 64] => [255, 95, 71]
107
 *
108
 * http://www.rapidtables.com/convert/color/hsl-to-rgb.htm
109
 *
110
 * $c = Chroma
111
 * $x = Second largest component of this color
112
 * $m = Amount to add to match lightness
113
 *
114
 * @param int $hue Degree in range 0-360
115
 * @param int $saturation Percent in range 0-100
116
 * @param int $lightness Percent in range 0-100
117
 *
118
 * @return int[] [red(0-255), green(0-255), blue(0-255)]
119
 */
120
function HSLtoRGB($hue, $saturation, $lightness)
121
{
122 34
    $saturation /= 100;
123 34
    $lightness /= 100;
124
125 34
    $c = (1 - abs(2 * $lightness - 1)) * $saturation;
126 34
    $x = $c * (1 - abs(fmod(($hue / 60), 2) - 1));
127 34
    $m = $lightness - ($c / 2);
128
129 34
    switch (true) {
130 34
        case ($hue < 60 || $hue === 360):
131 19
            $rgb = [$c, $x, 0];
132 19
            break;
133 16
        case ($hue < 120):
134 4
            $rgb = [$x, $c, 0];
135 4
            break;
136 13
        case ($hue < 180):
137 4
            $rgb = [0, $c, $x];
138 4
            break;
139 10
        case ($hue < 240):
140 4
            $rgb = [0, $x, $c];
141 4
            break;
142 7
        case ($hue < 300):
143 4
            $rgb = [$x, 0, $c];
144 4
            break;
145 4
        case ($hue < 360):
146 4
            $rgb = [$c, 0, $x];
147 4
            break;
148
    }
149
150
    return [
151 34
        (int) round(($rgb[0] + $m) * 255),
0 ignored issues
show
Bug introduced by
The variable $rgb does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
152 34
        (int) round(($rgb[1] + $m) * 255),
153 34
        (int) round(($rgb[2] + $m) * 255),
154 34
    ];
155
}
156
157
/**
158
 * Get the mix between two hsl colors.
159
 *
160
 * http://go.pastie.org/1976031#79-96
161
 *
162
 * @param int $hue1 Degree in range 0-360
163
 * @param int $saturation1 Percent in range 0-100
164
 * @param int $lightness1 Percent in range 0-100
165
 * @param int $hue2 Degree in range 0-360
166
 * @param int $saturation2 Percent in range 0-100
167
 * @param int $lightness2 Percent in range 0-100
168
 *
169
 * @return int[] [hue(0-360°), saturation(0-100%), lightness(0-100%)]
170
 */
171
function mixHSL($hue1, $saturation1, $lightness1, $hue2, $saturation2, $lightness2)
172
{
173 5
    $pi = pi();
174 5
    $h1 = $hue1 / 360;
175 5
    $s1 = $saturation1 / 100;
176 5
    $l1 = $lightness1 / 100;
177 5
    $h2 = $hue2 / 360;
178 5
    $s2 = $saturation2 / 100;
179 5
    $l2 = $lightness2 / 100;
180
181 5
    $h = 0.0;
182 5
    $s = 0.5 * ($s1 + $s2);
183 5
    $l = 0.5 * ($l1 + $l2);
184 5
    $x = cos(2.0 * $pi * $h1) + cos(2.0 * $pi * $h2);
185 5
    $y = sin(2.0 * $pi * $h1) + sin(2.0 * $pi * $h2);
186 5
    if ($x != 0.0 || $y != 0.0) {
187 5
        $h = atan2($y, $x) / (2.0 * $pi);
188 5
    } else {
189
        $s = 0.0;
190
    }
191
192 5
    $h *= 360;
193 5
    $s *= 100;
194 5
    $l *= 100;
195
196 5
    if ($h < 0) {
197 2
        $h += 360;
198 2
    }
199
200 5
    return [$h, $s, $l];
201
}
202
203
/**
204
 * Converts a color from rgb to 256.
205
 *
206
 * https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
207
 *
208
 * 0-7:     standard colors
209
 * 8-15:    high intensity colors
210
 * 16-231:  6 × 6 × 6 = 216 colors: 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
211
 * 232-255: grayscale from black to white in 24 steps
212
 *
213
 * @param int $red Decimal in range 0-255
214
 * @param int $green Decimal in range 0-255
215
 * @param int $blue Decimal in range 0-255
216
 *
217
 * @return int color(0-255)
218
 */
219
function RGBtoC256($red, $green, $blue)
220
{
221 34
    $steps = [0, 95, 135, 175, 215, 255];
222
223 34
    if ($red === $green && $green === $blue && !in_array($red, $steps)) {
224 3
        return round(232 + $red * 23 / 255);
225
    } else {
226
        $closest = function ($find, $values) {
227 31
            $distances = array();
228 31
            foreach ($values as $key => $num) {
229 31
                $distances[$key] = abs($find - $num);
230 31
            }
231
232 31
            return array_search(min($distances), $distances);
233 31
        };
234
235 31
        return (int) round(
236
            16
237 31
            + ($closest($red, $steps) * 36)
238 31
            + ($closest($green, $steps) * 6)
239 31
            + $closest($blue, $steps)
240 31
        );
241
    }
242
}
243
244
/**
245
 * Converts a color from 256 to rgb.
246
 *
247
 * https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
248
 *
249
 * 0-7:     standard colors
250
 * 8-15:    high intensity colors
251
 * 16-231:  6 × 6 × 6 = 216 colors: 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
252
 * 232-255: grayscale from black to white in 24 steps
253
 *
254
 * @param int $code Decimal in range 0-255
255
 *
256
 * @return int[] [red(0-255), green(0-255), blue(0-255)]
257
 */
258
function C256toRGB($code)
259
{
260
    // Primary and bright colors
261 37
    if ($code == 7) {
262 1
        return [192,192,192];
263
    }
264 37
    if ($code == 8) {
265 1
        return [128,128,128];
266
    }
267 37
    if ($code >= 0 && 15 >= $code) {
268 2
        $value = ($code <= 7) ? 128 : 255;
269 2
        $code = ($code <= 7) ? $code : $code - 8;
270
271 2
        $binary = str_pad(decbin($code), 3, '0', STR_PAD_LEFT);
272 2
        list($blue, $green, $red) = str_split($binary, 1);
273
274 2
        return [$red * $value, $green * $value, $blue * $value];
275
    }
276
277
    // Colors
278 35
    if ($code >= 16 && 231 >= $code) {
279 25
        $steps = [0, 95, 135, 175, 215, 255];
280 25
        $start = 16;
281 25
        $index = $code - $start;
282
283 25
        $red = (int) floor($index / 6 / 6);
284 25
        $green = (int) floor($index / 6 % 6);
285 25
        $blue = (int) floor($index % 6);
286
287 25
        return [$steps[$red], $steps[$green], $steps[$blue]];
288
    }
289
290
    // Grayscale
291 10
    if ($code >= 232 && 255 >= $code) {
292 10
        $start = 232;
293 10
        $index = $code - $start;
294
295 10
        $color = 8 + $index * 10;
296
297 10
        return [$color, $color, $color];
298
    }
299
}
300