Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

colour_manager.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 9.56 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\captcha;
015   
016  class colour_manager
017  {
018      var $img;
019      var $mode;
020      var $colours;
021      var $named_colours;
022   
023      /**
024      * Create the colour manager, link it to the image resource
025      */
026      function __construct($img, $background = false, $mode = 'ahsv')
027      {
028          $this->img = $img;
029          $this->mode = $mode;
030          $this->colours = array();
031          $this->named_colours = array();
032   
033          if ($background !== false)
034          {
035              $bg = $this->allocate_named('background', $background);
036              imagefill($this->img, 0, 0, $bg);
037          }
038      }
039   
040      /**
041      * Lookup a named colour resource
042      */
043      function get_resource($named_colour)
044      {
045          if (isset($this->named_colours[$named_colour]))
046          {
047              return $this->named_colours[$named_colour];
048          }
049   
050          if (isset($this->named_rgb[$named_colour]))
051          {
052              return $this->allocate_named($named_colour, $this->named_rgb[$named_colour], 'rgb');
053          }
054   
055          return false;
056      }
057   
058      /**
059      * Assign a name to a colour resource
060      */
061      function name_colour($name, $resource)
062      {
063          $this->named_colours[$name] = $resource;
064      }
065   
066      /**
067      * names and allocates a colour resource
068      */
069      function allocate_named($name, $colour, $mode = false)
070      {
071          $resource = $this->allocate($colour, $mode);
072   
073          if ($resource !== false)
074          {
075              $this->name_colour($name, $resource);
076          }
077          return $resource;
078      }
079   
080      /**
081      * allocates a specified colour into the image
082      */
083      function allocate($colour, $mode = false)
084      {
085          if ($mode === false)
086          {
087              $mode = $this->mode;
088          }
089   
090          if (!is_array($colour))
091          {
092              if (isset($this->named_rgb[$colour]))
093              {
094                  return $this->allocate_named($colour, $this->named_rgb[$colour], 'rgb');
095              }
096   
097              if (!is_int($colour))
098              {
099                  return false;
100              }
101   
102              $mode = 'rgb';
103              $colour = array(255 & ($colour >> 16), 255 & ($colour >>  8), 255 & $colour);
104          }
105   
106          if (isset($colour['mode']))
107          {
108              $mode = $colour['mode'];
109              unset($colour['mode']);
110          }
111   
112          if (isset($colour['random']))
113          {
114              unset($colour['random']);
115              // everything else is params
116              return $this->random_colour($colour, $mode);
117          }
118   
119          $rgb        = $this->model_convert($colour, $mode, 'rgb');
120          $store        = ($this->mode == 'rgb') ? $rgb : $this->model_convert($colour, $mode, $this->mode);
121          $resource    = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]);
122          $this->colours[$resource] = $store;
123   
124          return $resource;
125      }
126   
127      /**
128      * randomly generates a colour, with optional params
129      */
130      function random_colour($params = array(), $mode = false)
131      {
132          if ($mode === false)
133          {
134              $mode = $this->mode;
135          }
136   
137          switch ($mode)
138          {
139              case 'rgb':
140                  // @TODO random rgb generation. do we intend to do this, or is it just too tedious?
141                  break;
142   
143              case 'ahsv':
144              case 'hsv':
145              default:
146   
147                  $default_params = array(
148                      'hue_bias'            => false,    // degree / 'r'/'g'/'b'/'c'/'m'/'y'   /'o'
149                      'hue_range'            => false,    // if hue bias, then difference range +/- from bias
150                      'min_saturation'    => 30,        // 0 - 100
151                      'max_saturation'    => 80,        // 0 - 100
152                      'min_value'            => 30,        // 0 - 100
153                      'max_value'            => 80,        // 0 - 100
154                  );
155   
156                  $alt = ($mode == 'ahsv') ? true : false;
157                  $params = array_merge($default_params, $params);
158   
159                  $min_hue        = 0;
160                  $max_hue        = 359;
161                  $min_saturation    = max(0, $params['min_saturation']);
162                  $max_saturation    = min(100, $params['max_saturation']);
163                  $min_value        = max(0, $params['min_value']);
164                  $max_value        = min(100, $params['max_value']);
165   
166                  if ($params['hue_bias'] !== false)
167                  {
168                      if (is_numeric($params['hue_bias']))
169                      {
170                          $h = intval($params['hue_bias']) % 360;
171                      }
172                      else
173                      {
174                          switch ($params['hue_bias'])
175                          {
176                              case 'o':
177                                  $h = $alt ?  60 :  30;
178                                  break;
179   
180                              case 'y':
181                                  $h = $alt ? 120 :  60;
182                                  break;
183   
184                              case 'g':
185                                  $h = $alt ? 180 : 120;
186                                  break;
187   
188                              case 'c':
189                                  $h = $alt ? 210 : 180;
190                                  break;
191   
192                              case 'b':
193                                  $h = 240;
194                                  break;
195   
196                              case 'm':
197                                  $h = 300;
198                                  break;
199   
200                              case 'r':
201                              default:
202                                  $h = 0;
203                                  break;
204                          }
205                      }
206   
207                      $min_hue = $h + 360;
208                      $max_hue = $h + 360;
209   
210                      if ($params['hue_range'])
211                      {
212                          $min_hue -= min(180, $params['hue_range']);
213                          $max_hue += min(180, $params['hue_range']);
214                      }
215                  }
216   
217                  $h = mt_rand($min_hue, $max_hue);
218                  $s = mt_rand($min_saturation, $max_saturation);
219                  $v = mt_rand($min_value, $max_value);
220   
221                  return $this->allocate(array($h, $s, $v), $mode);
222   
223                  break;
224          }
225      }
226   
227      /**
228      */
229      function colour_scheme($resource, $include_original = true)
230      {
231          $mode = 'hsv';
232   
233          if (($pre = $this->get_resource($resource)) !== false)
234          {
235              $resource = $pre;
236          }
237   
238          $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode);
239          $results = ($include_original) ? array($resource) : array();
240          $colour2 = $colour3 = $colour4 = $colour;
241          $colour2[0] += 150;
242          $colour3[0] += 180;
243          $colour4[0] += 210;
244   
245          $results[] = $this->allocate($colour2, $mode);
246          $results[] = $this->allocate($colour3, $mode);
247          $results[] = $this->allocate($colour4, $mode);
248   
249          return $results;
250      }
251   
252      /**
253      */
254      function mono_range($resource, $count = 5, $include_original = true)
255      {
256          if (is_array($resource))
257          {
258              $results = array();
259              for ($i = 0, $size = count($resource); $i < $size; ++$i)
260              {
261                  $results = array_merge($results, $this->mono_range($resource[$i], $count, $include_original));
262              }
263              return $results;
264          }
265   
266          $mode = (in_array($this->mode, array('hsv', 'ahsv'), true) ? $this->mode : 'ahsv');
267          if (($pre = $this->get_resource($resource)) !== false)
268          {
269              $resource = $pre;
270          }
271   
272          $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode);
273   
274          $results = array();
275          if ($include_original)
276          {
277              $results[] = $resource;
278              $count--;
279          }
280   
281          // This is a hard problem. I chicken out and try to maintain readability at the cost of less randomness.
282   
283          while ($count > 0)
284          {
285              $colour[1] = ($colour[1] + mt_rand(40,60)) % 99;
286              $colour[2] = ($colour[2] + mt_rand(40,60));
287              $results[] = $this->allocate($colour, $mode);
288              $count--;
289          }
290          return $results;
291      }
292   
293      /**
294      * Convert from one colour model to another
295      */
296      function model_convert($colour, $from_model, $to_model)
297      {
298          if ($from_model == $to_model)
299          {
300              return $colour;
301          }
302   
303          switch ($to_model)
304          {
305              case 'hsv':
306   
307                  switch ($from_model)
308                  {
309                      case 'ahsv':
310                          return $this->ah2h($colour);
311                          break;
312   
313                      case 'rgb':
314                          return $this->rgb2hsv($colour);
315                          break;
316                  }
317                  break;
318   
319              case 'ahsv':
320   
321                  switch ($from_model)
322                  {
323                      case 'hsv':
324                          return $this->h2ah($colour);
325                          break;
326   
327                      case 'rgb':
328                          return $this->h2ah($this->rgb2hsv($colour));
329                          break;
330                  }
331                  break;
332   
333              case 'rgb':
334                  switch ($from_model)
335                  {
336                      case 'hsv':
337                          return $this->hsv2rgb($colour);
338                          break;
339   
340                      case 'ahsv':
341                          return $this->hsv2rgb($this->ah2h($colour));
342                          break;
343                  }
344                  break;
345          }
346          return false;
347      }
348   
349      /**
350      * Slightly altered from wikipedia's algorithm
351      */
352      function hsv2rgb($hsv)
353      {
354          $this->normalize_hue($hsv[0]);
355   
356          $h = $hsv[0];
357          $s = min(1, max(0, $hsv[1] / 100));
358          $v = min(1, max(0, $hsv[2] / 100));
359   
360          // calculate hue sector
361          $hi = floor($hsv[0] / 60);
362   
363          // calculate opposite colour
364          $p = $v * (1 - $s);
365   
366          // calculate distance between hex vertices
367          $f = ($h / 60) - $hi;
368   
369          // coming in or going out?
370          if (!($hi & 1))
371          {
372              $f = 1 - $f;
373          }
374   
375          // calculate adjacent colour
376          $q = $v * (1 - ($f * $s));
377   
378          switch ($hi)
379          {
380              case 0:
381                  $rgb = array($v, $q, $p);
382                  break;
383   
384              case 1:
385                  $rgb = array($q, $v, $p);
386                  break;
387   
388              case 2:
389                  $rgb = array($p, $v, $q);
390                  break;
391   
392              case 3:
393                  $rgb = array($p, $q, $v);
394                  break;
395   
396              case 4:
397                  $rgb = array($q, $p, $v);
398                  break;
399   
400              case 5:
401                  $rgb = array($v, $p, $q);
402                  break;
403   
404              default:
405                  return array(0, 0, 0);
406                  break;
407          }
408   
409          return array(255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
410      }
411   
412      /**
413      * (more than) Slightly altered from wikipedia's algorithm
414      */
415      function rgb2hsv($rgb)
416      {
417          $r = min(255, max(0, $rgb[0]));
418          $g = min(255, max(0, $rgb[1]));
419          $b = min(255, max(0, $rgb[2]));
420          $max = max($r, $g, $b);
421          $min = min($r, $g, $b);
422   
423          $v = $max / 255;
424          $s = (!$max) ? 0 : 1 - ($min / $max);
425   
426          // if max - min is 0, we want hue to be 0 anyway.
427          $h = $max - $min;
428   
429          if ($h)
430          {
431              switch ($max)
432              {
433                  case $g:
434                      $h = 120 + (60 * ($b - $r) / $h);
435                      break;
436   
437                  case $b:
438                      $h = 240 + (60 * ($r - $g) / $h);
439                      break;
440   
441                  case $r:
442                      $h = 360 + (60 * ($g - $b) / $h);
443                      break;
444              }
445          }
446          $this->normalize_hue($h);
447   
448          return array($h, $s * 100, $v * 100);
449      }
450   
451      /**
452      */
453      function normalize_hue(&$hue)
454      {
455          $hue %= 360;
456   
457          if ($hue < 0)
458          {
459              $hue += 360;
460          }
461      }
462   
463      /**
464      * Alternate hue to hue
465      */
466      function ah2h($ahue)
467      {
468          if (is_array($ahue))
469          {
470              $ahue[0] = $this->ah2h($ahue[0]);
471              return $ahue;
472          }
473          $this->normalize_hue($ahue);
474   
475          // blue through red is already ok
476          if ($ahue >= 240)
477          {
478              return $ahue;
479          }
480   
481          // ahue green is at 180
482          if ($ahue >= 180)
483          {
484              // return (240 - (2 * (240 - $ahue)));
485              return (2 * $ahue) - 240; // equivalent
486          }
487   
488          // ahue yellow is at 120   (RYB rather than RGB)
489          if ($ahue >= 120)
490          {
491              return $ahue - 60;
492          }
493   
494          return $ahue / 2;
495      }
496   
497      /**
498      * hue to Alternate hue
499      */
500      function h2ah($hue)
501      {
502          if (is_array($hue))
503          {
504              $hue[0] = $this->h2ah($hue[0]);
505              return $hue;
506          }
507          $this->normalize_hue($hue);
508   
509          // blue through red is already ok
510          if ($hue >= 240)
511          {
512              return $hue;
513          }
514          else if ($hue <= 60)
515          {
516              return $hue * 2;
517          }
518          else if ($hue <= 120)
519          {
520              return $hue + 60;
521          }
522          else
523          {
524              return ($hue + 240) / 2;
525          }
526      }
527  }
528