summaryrefslogtreecommitdiff
path: root/plugins/python/cglimpse/distro.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/python/cglimpse/distro.py')
-rw-r--r--plugins/python/cglimpse/distro.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/plugins/python/cglimpse/distro.py b/plugins/python/cglimpse/distro.py
new file mode 100644
index 0000000..5ffc523
--- /dev/null
+++ b/plugins/python/cglimpse/distro.py
@@ -0,0 +1,101 @@
+
+from .method import GlimpseMethod
+
+
+class ByteDistribution(GlimpseMethod):
+
+ def __init__(self, builder):
+ """Prepare a Shannon entropy display."""
+
+ super(ByteDistribution, self).__init__(builder)
+
+ button = builder.get_object('shannon_color')
+ button.connect('color-set', self._on_color_set)
+
+ self._on_color_set(button)
+
+ self._step = 0x80
+
+ self._v_legend = 'Quantity'
+ self._h_legend = 'Byte values'
+
+ self._x_range = [ 0, 0x20, 0x100 ]
+ self._y_range = [ 0, 25, 100 ]
+
+ self._values = {}
+
+
+ def _on_color_set(self, button):
+ """React on color chosen for the rendering."""
+
+ color = button.get_rgba()
+ self._color = [ color.red, color.green, color.blue, color.alpha ]
+ self._shadow_color = [ color.red * 0.5, color.green * 0.5, color.blue * 0.5, color.alpha ]
+
+
+ def format_legend(self, value, vert):
+ """Build the label used for a rule."""
+
+ if vert:
+ text = str(value)
+
+ else:
+
+ scale = [ ' kb', ' Mb', ' Gb', ' Tb' ]
+ suffix = ''
+
+ for i in range(len(scale)):
+
+ if value < 1024:
+ break
+
+ value /= 1024
+ suffix = scale[i]
+
+ text = '%u%s' % (value, suffix)
+
+ return text
+
+
+ def update(self, data):
+ """Provide a description for the method."""
+
+ max_count = 0
+
+ self._values = {}
+
+ for i in range(256):
+ self._values[i] = 0
+
+ for b in data:
+
+ if b in self._values.keys():
+ self._values[b] += 1
+
+ for c in self._values.values():
+ if c > max_count:
+ max_count = c
+
+ self._y_range = [ 0, max_count / 4, max_count ]
+
+
+ def render(self, cr, area):
+ """Draw the bytes distribution for the current binary, if any."""
+
+ max_count = self._y_range[-1]
+
+ last_x = area[0]
+
+ cr.set_source_rgba(*self._shadow_color)
+ cr.set_source_rgba(*self._color)
+ cr.set_line_width(1)
+
+ for i in range(256):
+
+ x = area[0] + ((i + 1) * area[2]) / 256
+ h = (area[3] * self._values[i]) / max_count
+
+ cr.rectangle(last_x, area[1] + area[3] - h, x - last_x, h)
+ cr.fill()
+
+ last_x = x