summaryrefslogtreecommitdiff
path: root/examples/triage/entropy.cpp
blob: b43350cd9ef3d10f5450eb7d405b97bcdf99b85e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <QtCore/QTimer>
#include <QtGui/QPainter>
#include "entropy.h"
#include "view.h"
#include "theme.h"


EntropyThread::EntropyThread(BinaryViewRef data, size_t blockSize, QImage* image)
{
	m_data = data;
	m_image = image;
	m_blockSize = blockSize;
	m_updated = false;
	m_running = true;
	m_thread = std::thread([=]() { Run(); });
}


EntropyThread::~EntropyThread()
{
	m_running = false;
	m_thread.join();
}


void EntropyThread::Run()
{
	int width = m_image->width();
	for (int i = 0; i < width; i++)
	{
		if (!m_running)
			break;
		std::vector<float> entropy =
		    m_data->GetEntropy(m_data->GetStart() + ((uint64_t)i * m_blockSize), m_blockSize, m_blockSize);
		int v;
		if (entropy.size() == 0)
			v = 0;
		else
			v = (int)(entropy[0] * 255);
		if (v >= 240)
		{
			QColor color = getThemeColor(YellowStandardHighlightColor);
			m_image->setPixelColor(i, 0, color);
		}
		else
		{
			QColor baseColor = getThemeColor(FeatureMapBaseColor);
			QColor entropyColor = getThemeColor(BlueStandardHighlightColor);
			QColor color = mixColor(baseColor, entropyColor, (uint8_t)v);
			m_image->setPixelColor(i, 0, color);
		}
		m_updated = true;
	}
}


EntropyWidget::EntropyWidget(QWidget* parent, TriageView* view, BinaryViewRef data) : QWidget(parent)
{
	m_view = view;
	m_data = data;
	m_rawData = data->GetFile()->GetViewOfType("Raw");

	m_blockSize = (size_t)((m_rawData->GetLength() / 4096) + 1);
	if (m_blockSize < 1024)
		m_blockSize = 1024;
	m_width = (int)(m_rawData->GetLength() / (uint64_t)m_blockSize);
	m_image = QImage(m_width, 1, QImage::Format_ARGB32);
	m_image.fill(QColor(0, 0, 0, 0));
	m_thread = new EntropyThread(m_rawData, m_blockSize, &m_image);

	QTimer* timer = new QTimer();
	connect(timer, &QTimer::timeout, this, &EntropyWidget::timerExpired);
	timer->setInterval(100);
	timer->setSingleShot(false);
	timer->start();

	setMinimumHeight(UIContext::getScaledWindowSize(32, 32).height());
}


EntropyWidget::~EntropyWidget()
{
	delete m_thread;
}


void EntropyWidget::paintEvent(QPaintEvent*)
{
	QPainter p(this);
	p.drawImage(rect(), m_image);
	p.drawRect(rect());
}


QSize EntropyWidget::sizeHint() const
{
	return QSize(640, 32);
}


void EntropyWidget::timerExpired()
{
	if (m_thread->IsUpdated())
	{
		m_thread->ResetUpdated();
		update();
	}
}


void EntropyWidget::mousePressEvent(QMouseEvent* event)
{
	if (event->button() != Qt::LeftButton)
		return;
	float frac = (float)event->pos().x() / (float)rect().width();
	uint64_t offset = (uint64_t)(frac * m_width * m_blockSize);
	m_view->navigateToFileOffset(offset);
}