Advertisement
wladimir

colorconv/xterm256.py

Apr 2nd, 2011
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.74 KB | None | 0 0
  1. """
  2. 256-color xterm conversion utilities.
  3. """
  4. # Wladimir van der Laan, 2011
  5.  
  6. # whole colortable, filled in later
  7. colortable = None
  8.  
  9. # the 6 value iterations in the xterm color cube
  10. valuerange = [ 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF ]
  11.  
  12. # 16 basic ANSI colors + lighter variants
  13. # these can be different depending on the terminal settings,
  14. # so do not use them when converting from RGB.
  15. basic16 = [
  16.         [ 0x00, 0x00, 0x00 ], # 0
  17.         [ 0xCD, 0x00, 0x00 ], # 1
  18.         [ 0x00, 0xCD, 0x00 ], # 2
  19.         [ 0xCD, 0xCD, 0x00 ], # 3
  20.         [ 0x00, 0x00, 0xEE ], # 4
  21.         [ 0xCD, 0x00, 0xCD ], # 5
  22.         [ 0x00, 0xCD, 0xCD ], # 6
  23.         [ 0xE5, 0xE5, 0xE5 ], # 7
  24.         [ 0x7F, 0x7F, 0x7F ], # 8
  25.         [ 0xFF, 0x00, 0x00 ], # 9
  26.         [ 0x00, 0xFF, 0x00 ], # 10
  27.         [ 0xFF, 0xFF, 0x00 ], # 11
  28.         [ 0x5C, 0x5C, 0xFF ], # 12
  29.         [ 0xFF, 0x00, 0xFF ], # 13
  30.         [ 0x00, 0xFF, 0xFF ], # 14
  31.         [ 0xFF, 0xFF, 0xFF ]  # 15
  32. ]
  33.  
  34. # Closest color on RGB color cube (from valuerange)
  35. closest6 = [
  36.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  37.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  38.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  39.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  40.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  41.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  42.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  43.     1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  44.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  45.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
  46.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  47.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  48.     3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  49.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  50.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
  51.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
  52.  
  53. def _color_dist(c, rgb):
  54.     """
  55.    Return squared Euclidian distance of rgb to color `c`
  56.    in the color table.
  57.    """
  58.     d0 = colortable[c][0] - rgb[0]
  59.     d1 = colortable[c][1] - rgb[1]
  60.     d2 = colortable[c][2] - rgb[2]
  61.     return d0*d0 + d1*d1 + d2*d2
  62.  
  63. def to_rgb(color):
  64.     """
  65.    Convert a xterm256 color value (0-255) to 3 unsigned chars RGB
  66.    tuple.
  67.    """
  68.     rgb = [0,0,0]
  69.     if color < 16:
  70.         # 16 basic colors
  71.         rgb[0] = basic16[color][0]
  72.         rgb[1] = basic16[color][1]
  73.         rgb[2] = basic16[color][2]
  74.     elif color >= 16 and color <= 231:
  75.         # color cube color
  76.         color -= 16
  77.         rgb[0] = valuerange[(color/36)%6]
  78.         rgb[1] = valuerange[(color/6)%6]
  79.         rgb[2] = valuerange[color%6]    
  80.     elif color >= 232 and color <= 255:
  81.         # gray tone
  82.         rgb[0] = rgb[1] = rgb[2] = 8+(color-232)*0x0a
  83.  
  84.     return rgb
  85.  
  86. def from_rgb(rgb):
  87.     """
  88.    Convert RGB tuple to xterm256 color value (0-255).
  89.    """
  90.     # Optimized algorithm to find the xterm256 color with Euclidian closest distance to a
  91.     # provided RGB value: as the palette consists of an independent 6x6x6 RGB cube
  92.     # and a 24 grey tone scale, determine the closest color in both palettes, then
  93.     # from these two return the on that's closest to the requested RGB color.
  94.    
  95.     # Compute closest color on 6x6x6 RGB cube
  96.     r = [closest6[x] for x in rgb]
  97.     b = 16 + r[0]*36 + r[1]*6 + r[2]
  98.    
  99.     # Compute closest point on greyscale line
  100.     greyscale = sum(rgb)
  101.     r = (greyscale-9) / 30
  102.     c = 232 + max(min(r,23),0)
  103.    
  104.     # Return RGB cube or greyscale color depending
  105.     # on which is closest.
  106.     distb = _color_dist(b, rgb)
  107.     distc = _color_dist(c, rgb)
  108.     if distb <= distc:
  109.         color = b
  110.     else:
  111.         color = c
  112.  
  113.     return color
  114.  
  115. colortable = [to_rgb(c) for c in xrange(0, 256)]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement