Skip to content

Commit cac82d6

Browse files
committed
Precompute premultiplication table.
1 parent 9146a7d commit cac82d6

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

src/_mplcairo.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -912,15 +912,17 @@ void GraphicsContextRenderer::draw_image(
912912
for (auto i = 0; i < height; ++i) {
913913
auto ptr = reinterpret_cast<uint32_t*>(data + i * stride);
914914
for (auto j = 0; j < width; ++j) {
915-
auto const& r = im_raw(i, j, 0),
916-
& g = im_raw(i, j, 1),
917-
& b = im_raw(i, j, 2),
918-
& a = im_raw(i, j, 3);
919-
*ptr++ =
920-
(uint8_t(a) << 24)
921-
| (uint8_t(a / 255. * r) << 16)
922-
| (uint8_t(a / 255. * g) << 8)
923-
| (uint8_t(a / 255. * b) << 0);
915+
auto r = im_raw(i, j, 0),
916+
g = im_raw(i, j, 1),
917+
b = im_raw(i, j, 2),
918+
a = im_raw(i, j, 3);
919+
if (a != 0xff) {
920+
auto subtable = &detail::premultiplication_table[a << 8];
921+
r = subtable[r];
922+
g = subtable[g];
923+
b = subtable[b];
924+
}
925+
*ptr++ = (a << 24) + (r << 16) + (g << 8) + (b << 0);
924926
}
925927
}
926928
cairo_surface_mark_dirty(surface);

src/_util.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ std::unordered_map<FT_Error, std::string> const ft_errors
2828
;
2929
FT_Library ft_library{};
3030
bool has_pycairo{};
31+
std::array<uint8_t, 0x10000> premultiplication_table{[]() {
32+
auto table = decltype(premultiplication_table){};
33+
for (auto a = 1; a < 0x100; ++a) {
34+
for (auto c = 0; c < 0x100; ++c) {
35+
table[(a << 8) + c] = a / 255. * c;
36+
}
37+
}
38+
return table;
39+
} ()};
3140
std::array<uint8_t, 0x10000> unpremultiplication_table{[]() {
3241
auto table = decltype(unpremultiplication_table){};
3342
// As in cairo-png.c (unpremultiply 0 => 0).

src/_util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ namespace detail {
2121
extern std::unordered_map<FT_Error, std::string> const ft_errors;
2222
extern FT_Library ft_library;
2323
extern bool has_pycairo;
24-
extern std::array<uint8_t, 0x10000> unpremultiplication_table;
24+
extern std::array<uint8_t, 0x10000>
25+
premultiplication_table, unpremultiplication_table;
2526

2627
// Optional parts of cairo.
2728

0 commit comments

Comments
 (0)