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