hsv2rgb.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* hsv2rgb.c
  2. * Integer only conversion functions between HSV and RGB
  3. */
  4. #include "hsv2rgb.h"
  5. // TODO fix these buggy macros
  6. #define max(x,y) ((x>y) ? x:y)
  7. #define min(x,y) ((x>y) ? y:x)
  8. #define min3(x,y,z) (min(min(x,y),z))
  9. #define max3(x,y,z) (max(max(x,y),z))
  10. rgb_color hsv2rgb(hsv_color hsv)
  11. {
  12. // From : http://qscribble.blogspot.fr/2008/06/integer-conversion-from-hsl-to-rgb.html
  13. int h = hsv.h;
  14. int s = hsv.s;
  15. int v = hsv.v;
  16. rgb_color rgb = {0, 0, 0};
  17. if (v == 0)
  18. return rgb;
  19. // sextant = 0 .. 5
  20. int sextant = (h*6)/256;
  21. // f = 0 .. 42
  22. int f = h - (sextant*256)/6;
  23. int p = (v * (256 - s))/256;
  24. int q = (v * (256*43 - s*f))/(256*43);
  25. int t = (v * (256*43 - s*(43-f)))/(256*43);
  26. // Corrige les erreurs dues aux arrondis
  27. p = max(min(p, 255), 0);
  28. q = max(min(q, 255), 0);
  29. t = max(min(t, 255), 0);
  30. switch(sextant){
  31. case 0: rgb.r = v; rgb.g = t; rgb.b = p; break;
  32. case 1: rgb.r = q; rgb.g = v; rgb.b = p; break;
  33. case 2: rgb.r = p; rgb.g = v; rgb.b = t; break;
  34. case 3: rgb.r = p; rgb.g = q; rgb.b = v; break;
  35. case 4: rgb.r = t; rgb.g = p; rgb.b = v; break;
  36. default:rgb.r = v; rgb.g = p; rgb.b = q; break;
  37. }
  38. return rgb;
  39. }
  40. hsv_color rgb2hsv(rgb_color rgb)
  41. {
  42. // From : http://www.ruinelli.ch/rgb-to-hsv
  43. hsv_color hsv = {0, 0, 0};
  44. int min, max, delta;
  45. min = min3(rgb.r, rgb.g, rgb.b);
  46. max = max3(rgb.r, rgb.g, rgb.b);
  47. if(max==0) {
  48. hsv.h = 0;
  49. hsv.s = 0;
  50. hsv.v = 0;
  51. return hsv;
  52. }
  53. hsv.v = max;
  54. delta = max - min;
  55. hsv.s = (delta)*255 / max;
  56. if(rgb.r == max)
  57. hsv.h = (rgb.g - rgb.b)*42/delta; // between yellow & magenta
  58. else if(rgb.g == max)
  59. hsv.h = 120 + (rgb.b - rgb.r)*42/delta; // between cyan & yellow
  60. else
  61. hsv.h = 240 + (rgb.r - rgb.g)*42/delta; // between magenta & cyan
  62. return hsv;
  63. }