rgb.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "lib9.h"
  2. #include "draw.h"
  3. /*
  4. * This original version, although fast and a true inverse of
  5. * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c))
  6. * returned the original color, does a terrible job for RGB
  7. * triples that do not appear in the color map, so it has been
  8. * replaced by the much slower version below, that loops
  9. * over the color map looking for the nearest point in RGB
  10. * space. There is no visual psychology reason for that
  11. * criterion, but it's easy to implement and the results are
  12. * far more pleasing.
  13. *
  14. int
  15. rgb2cmap(int cr, int cg, int cb)
  16. {
  17. int r, g, b, v, cv;
  18. if(cr < 0)
  19. cr = 0;
  20. else if(cr > 255)
  21. cr = 255;
  22. if(cg < 0)
  23. cg = 0;
  24. else if(cg > 255)
  25. cg = 255;
  26. if(cb < 0)
  27. cb = 0;
  28. else if(cb > 255)
  29. cb = 255;
  30. r = cr>>6;
  31. g = cg>>6;
  32. b = cb>>6;
  33. cv = cr;
  34. if(cg > cv)
  35. cv = cg;
  36. if(cb > cv)
  37. cv = cb;
  38. v = (cv>>4)&3;
  39. return ((((r<<2)+v)<<4)+(((g<<2)+b+v-r)&15));
  40. }
  41. */
  42. int
  43. rgb2cmap(int cr, int cg, int cb)
  44. {
  45. int i, r, g, b, sq;
  46. ulong rgb;
  47. int best, bestsq;
  48. best = 0;
  49. bestsq = 0x7FFFFFFF;
  50. for(i=0; i<256; i++){
  51. rgb = cmap2rgb(i);
  52. r = (rgb>>16) & 0xFF;
  53. g = (rgb>>8) & 0xFF;
  54. b = (rgb>>0) & 0xFF;
  55. sq = (r-cr)*(r-cr)+(g-cg)*(g-cg)+(b-cb)*(b-cb);
  56. if(sq < bestsq){
  57. bestsq = sq;
  58. best = i;
  59. }
  60. }
  61. return best;
  62. }
  63. int
  64. cmap2rgb(int c)
  65. {
  66. int j, num, den, r, g, b, v, rgb;
  67. r = c>>6;
  68. v = (c>>4)&3;
  69. j = (c-v+r)&15;
  70. g = j>>2;
  71. b = j&3;
  72. den=r;
  73. if(g>den)
  74. den=g;
  75. if(b>den)
  76. den=b;
  77. if(den==0) {
  78. v *= 17;
  79. rgb = (v<<16)|(v<<8)|v;
  80. }
  81. else{
  82. num=17*(4*den+v);
  83. rgb = ((r*num/den)<<16)|((g*num/den)<<8)|(b*num/den);
  84. }
  85. return rgb;
  86. }
  87. int
  88. cmap2rgba(int c)
  89. {
  90. return (cmap2rgb(c)<<8)|0xFF;
  91. }