Skip to content

Commit 422ba14

Browse files
committed
Better implementation for low-level bit-fiddling in tracer code
1 parent b45e2c4 commit 422ba14

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/gen/tracer.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,33 @@ void tracer_t::reset()
4141
m_num_points = 0;
4242
}
4343

44+
static potrace_word bit_squeeze(potrace_word w, unsigned char const *d) noexcept
45+
{
46+
return (0x80U & d[0]) | (0x40U & d[1]) | (0x20U & d[2]) | (0x10U & d[3]) |
47+
(0x08U & d[4]) | (0x04U & d[5]) | (0x02U & d[6]) | (0x01U & d[7]) |
48+
w;
49+
}
50+
51+
static_assert(sizeof(potrace_word) == 8);
52+
4453
void tracer_t::prepare(canvas_t const &canvas) noexcept
4554
{
4655
std::size_t const size = canvas.size();
4756
assert(size % bits_per_word == 0);
4857

4958
m_bits.reserve((size * size) / bits_per_word);
5059

51-
unsigned char const *d = canvas.begin();
52-
while (d != canvas.end()) {
53-
potrace_word w = 0x1U & *d++;
54-
for (std::size_t n = 1; n < bits_per_word; ++n) {
55-
w <<= 1U;
56-
assert(d != canvas.end());
57-
w |= 0x1U & *d++;
58-
}
60+
for (unsigned char const *d = canvas.begin(); d != canvas.end(); d += 8) {
61+
auto w = bit_squeeze(0, d);
62+
63+
w = bit_squeeze(w << 8U, d += 8);
64+
w = bit_squeeze(w << 8U, d += 8);
65+
w = bit_squeeze(w << 8U, d += 8);
66+
w = bit_squeeze(w << 8U, d += 8);
67+
w = bit_squeeze(w << 8U, d += 8);
68+
w = bit_squeeze(w << 8U, d += 8);
69+
w = bit_squeeze(w << 8U, d += 8);
70+
5971
m_bits.push_back(w);
6072
}
6173

0 commit comments

Comments
 (0)