Luanti 5.17.0-dev
Loading...
Searching...
No Matches
bitmap.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2021-2025 sfan5
4
5#include "irrlichttypes.h"
6#include <vector>
7#include <algorithm>
8#include <cassert>
9
14class Bitmap {
16 std::vector<u8> data;
17
18 // NOTE: do not rely on the value of unused padding bits in `data`
19
20 static inline u32 bytepos(u32 index) { return index >> 3; }
21 static inline u8 bitpos(u32 index) { return index & 7; }
22
23 template<bool set, bool toggle, bool clear>
24 bool modify_(u32 x, u32 y)
25 {
26 u32 index = y * linesize + x;
27 u8 mask = 1 << bitpos(index);
28 u8 byte = data[bytepos(index)];
29 if constexpr (set)
30 byte |= mask;
31 else if constexpr (toggle)
32 byte ^= mask;
33 else if constexpr (clear)
34 byte &= ~mask;
35 data[bytepos(index)] = byte;
36 return byte & mask;
37 }
38
39public:
41 Bitmap() : linesize(0), lines(0) {}
42
45 {
47 }
48
49 inline u32 width() const { return linesize; }
50 inline u32 height() const { return lines; }
51
52 inline void resize(u32 width, u32 height, bool initial_value=false)
53 {
54 assert(width <= 65534 && height <= 65534); // index would overflow
56 lines = height;
57 data.clear(); // make sure to discard all data
58 if (width && height)
59 data.resize(bytepos(width * height) + 1, static_cast<u8>(initial_value ? 0xff : 0));
60 }
61
62 inline void reset(bool value)
63 {
64 std::fill(data.begin(), data.end(), value ? 0xff : 0);
65 }
66
67 inline bool get(u32 x, u32 y) const
68 {
69 u32 index = y * linesize + x;
70 return data[bytepos(index)] & (1 << bitpos(index));
71 }
72
73 inline void set(u32 x, u32 y) { modify_<1, 0, 0>(x, y); }
74 inline void unset(u32 x, u32 y) { modify_<0, 0, 1>(x, y); }
75 inline bool toggle(u32 x, u32 y) { return modify_<0, 1, 0>(x, y); }
76
78 inline bool all() const
79 {
80 if (!linesize || !lines)
81 return (assert(0), true);
82 for (u32 i = 0; i < data.size() - 1; i++) {
83 if (data[i] != 0xff)
84 return false;
85 }
86 u8 last_byte = data.back(); // contains padding
87 u8 leftover_bits = bitpos(linesize * lines); // [0, 7]
88 u8 leftover_mask = (1 << leftover_bits) - 1; // 0, 1, 3, 7, ... or 127
89 return (last_byte & leftover_mask) == leftover_mask;
90 }
91
93 inline bool none() const
94 {
95 if (!linesize || !lines)
96 return (assert(0), true);
97 for (u32 i = 0; i < data.size() - 1; i++) {
98 if (data[i] != 0)
99 return false;
100 }
101 u8 last_byte = data.back();
102 u8 leftover_bits = bitpos(linesize * lines);
103 u8 leftover_mask = (1 << leftover_bits) - 1;
104 return (last_byte & leftover_mask) == 0;
105 }
106};
107
108// Note: a 3D class could be written based on the 2D one. Or maybe the other way?
void set(u32 x, u32 y)
Definition bitmap.h:73
void reset(bool value)
Definition bitmap.h:62
u32 lines
Definition bitmap.h:15
void unset(u32 x, u32 y)
Definition bitmap.h:74
static u8 bitpos(u32 index)
Definition bitmap.h:21
bool all() const
Returns true if all bits in the bitmap are set.
Definition bitmap.h:78
bool none() const
Returns true if no bits in the bitmap are set.
Definition bitmap.h:93
u32 width() const
Definition bitmap.h:49
bool get(u32 x, u32 y) const
Definition bitmap.h:67
u32 linesize
Definition bitmap.h:15
u32 height() const
Definition bitmap.h:50
bool toggle(u32 x, u32 y)
Definition bitmap.h:75
Bitmap(u32 width, u32 height)
Create a new zero-filled bitmap.
Definition bitmap.h:44
Bitmap()
Create an empty bitmap.
Definition bitmap.h:41
static u32 bytepos(u32 index)
Definition bitmap.h:20
bool modify_(u32 x, u32 y)
Definition bitmap.h:24
void resize(u32 width, u32 height, bool initial_value=false)
Definition bitmap.h:52
std::vector< u8 > data
Definition bitmap.h:16
constexpr v3f x
Definition test_irr_matrix4.cpp:18
constexpr v3f y
Definition test_irr_matrix4.cpp:19