Package rekall :: Package ui :: Module colors
[frames] | no frames]

Source Code for Module rekall.ui.colors

  1  # Rekall Memory Forensics 
  2  # 
  3  # Copyright 2015 Google Inc. All Rights Reserved. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or (at 
  8  # your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  # General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the Free Software 
 17  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 18  # 
 19   
 20  """ 
 21  Various functions for handling colors. Used mainly for visualizing output 
 22  of plugins with heatmaps (for now). 
 23   
 24  Most of the code below is made to match this color chart: 
 25  http://en.wikipedia.org/wiki/File:Xterm_256color_chart.svg 
 26   
 27  The colorspace conversions are thin wrappers around colorsys, except for 
 28  the code to handle XTerm colors, which is my own work. 
 29  """ 
 30  __author__ = "Adam Sindelar <adamsh@google.com>" 
 31   
 32  import colorsys 
 33   
 34   
35 -def ArbitraryStepFunction(value, steps):
36 for step, ceiling in enumerate(steps): 37 if int(value) <= ceiling: 38 return step 39 40 raise ValueError("Maximum value of %d exceeded with %d." % (steps[-1], 41 value))
42 43 44 XTERM16 = ((0x00, 0x00, 0x00), (0x80, 0x00, 0x00), (0x00, 0x80, 0x00), 45 (0x80, 0x80, 0x00), (0x00, 0x00, 0x80), (0x80, 0x00, 0x80), 46 (0x00, 0x80, 0x80), (0xc0, 0xc0, 0xc0), (0x80, 0x80, 0x80), 47 (0xff, 0x00, 0x00), (0x00, 0xff, 0x00), (0xff, 0xff, 0x00), 48 (0x00, 0x00, 0xff), (0xff, 0x00, 0xff), (0x00, 0xff, 0xff), 49 (0xff, 0xff, 0xff)) 50 """XTerm has 16 special colors, as listed above.""" 51 52 53 XTERM_CHANNEL_STEPS = [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff] 54 """XTerm color space is sparse at low luminosity.""" 55 56
57 -def ChannelStepFunction(intensity):
58 return ArbitraryStepFunction(intensity, XTERM_CHANNEL_STEPS)
59 60
61 -def GreyscaleStepFunction(intensity):
62 return ArbitraryStepFunction(intensity, xrange(0x8, 0xef, 0xa))
63 64 65 # Color-space conversions: 66 67
68 -def RGBToXTerm(red, green, blue):
69 """Convert RGB values (0-255) to the closes XTerm color.""" 70 sred = ChannelStepFunction(red) 71 sgreen = ChannelStepFunction(green) 72 sblue = ChannelStepFunction(blue) 73 74 # Greyscale starts at xterm 232 and has 12 shades. Black and white are part 75 # of the 16-color range at the base of the spectrum. 76 if sred == sgreen == sblue: 77 avg = (red + green + blue) / 3 78 if avg < 0x8: 79 return 0 80 elif avg > 0xee: 81 return 15 82 else: 83 return 232 + GreyscaleStepFunction(avg) 84 85 return (16 # base offset 86 + ChannelStepFunction(blue) # Blue increases in the inner loop. 87 + ChannelStepFunction(green) * 6 # Green increases in the middle. 88 + ChannelStepFunction(red) * 6 ** 2) # Outer loop for red.
89 90
91 -def XTermToRGB(xterm):
92 """Convert the XTerm color (0-255) to an RGB equivalent.""" 93 if xterm < 16: 94 return XTERM16[xterm] 95 96 if xterm >= 232: 97 # Greyscale 98 value = (xterm - 231) * 0x08 99 return value, value, value 100 101 xterm -= 16 # Base of 256-color space. 102 red, r = divmod(xterm, 6 ** 2) 103 green, blue = divmod(r, 6) 104 105 return (XTERM_CHANNEL_STEPS[red], 106 XTERM_CHANNEL_STEPS[green], 107 XTERM_CHANNEL_STEPS[blue])
108 109
110 -def RGBToHSL(red, green, blue):
111 hue, luminosity, saturation = colorsys.rgb_to_hls( 112 float(red) / 0xff, float(green) / 0xff, float(blue) / 0xff) 113 114 return hue, saturation, luminosity
115 116
117 -def RGBToYIQ(red, green, blue):
118 return colorsys.rgb_to_yiq( 119 float(red) / 0xff, float(green) / 0xff, float(blue) / 0xff)
120 121
122 -def HSLToRGB(hue, saturation, luminosity):
123 red, green, blue = colorsys.hls_to_rgb(hue, luminosity, saturation) 124 return int(red * 0xff), int(green * 0xff), int(blue * 0xff)
125 126
127 -def YIQToRGB(y, i, q):
128 red, green, blue = colorsys.yiq_to_rgb(y, i, q) 129 return int(red * 0xff), int(green * 0xff), int(blue * 0xff)
130 131 132 # Text-color heuristics: 133 134
135 -def YIQTextForBackground(y, i, q):
136 """Compute the foreground color, given the background color.""" 137 # Y is luma, which is basically the sum of gamma-adjusted RGB channels. 138 # The Y channel is intentionally weighted towards the red end of the 139 # spectrum and high luminosities; I and Q are chromatic channels and carry 140 # no luminosity information. 141 # Perceptually, white text on red background of equivalent luminosity 142 # is more readable than white text on blue or green backgrounds, hence 143 # the formula below. (For greyscale this is basically identical to 144 # the HSL luminosity channel, using threshold of .5, because of the gamma 145 # compression's nonlinearity.) 146 return (0, 0, 0) if (y * 2 - i - q) > .8 else (1, 0, 0)
147 148
149 -def RGBTextForBackground(red, green, blue):
150 """Compute the foreground color, given the background color.""" 151 hsl = RGBToYIQ(red, green, blue) 152 text = YIQTextForBackground(*hsl) 153 r, g, b = YIQToRGB(*text) 154 return r, g, b
155 156
157 -def XTermTextForBackground(xterm):
158 """Compute the foreground color, given the background color.""" 159 rgb = XTermToRGB(xterm) 160 fg = RGBTextForBackground(*rgb) 161 return RGBToXTerm(*fg)
162 163 164 # Functions to color heatmaps: 165 166
167 -def BlendRGB(x, y, wx=1, wy=1):
168 """Blend RGB colors x and y, optionally using assigned weights wx and wy.""" 169 t = wx + wy 170 return ((x[0] * wx + y[0] * wy) / t, 171 (x[1] * wx + y[1] * wy) / t, 172 (x[2] * wx + y[2] * wy) / t)
173 174
175 -def HeatToHSL(heat, greyscale=False):
176 """Given heat (0-1.0), compute the color to represent it on a heatmap. 177 178 Arguments: 179 Greyscale: If True, use luminosity instead of hue. 180 """ 181 if greyscale: 182 saturation = 0 183 hue = 0 184 luminosity = heat 185 else: 186 saturation = 1.0 187 luminosity = .5 188 hue = .5 - (heat * .5) 189 190 return hue, saturation, luminosity
191 192
193 -def HeatToRGB(heat, greyscale=False):
194 return HSLToRGB(*HeatToHSL(heat, greyscale))
195 196
197 -def HeatToXTerm(heat, greyscale=False):
198 hsl = HeatToHSL(heat, greyscale) 199 rgb = HSLToRGB(*hsl) 200 xterm = RGBToXTerm(*rgb) 201 202 return xterm
203