From 8cc3d2a592d28d1976054aacb89979de1266e6bf Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 9 Nov 2024 15:50:33 -0800 Subject: [PATCH] fix raw writes to BitmapImage --- src/Image.cc | 30 ++++++++++++++++++------------ src/Image.hh | 1 + src/ImageTest.cc | 4 ++-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Image.cc b/src/Image.cc index 00f641e..fb8f283 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -1721,7 +1721,7 @@ void Image::resize_blit(const Image& source, ssize_t x, ssize_t y, ssize_t w, } static inline constexpr size_t byte_count_for_bit_count(size_t bit_count) { - return (bit_count + 7) & (~7); + return (bit_count + 7) >> 3; } BitmapImage::BitmapImage() : width(0), height(0), row_bytes(0), data(nullptr) {} @@ -1729,7 +1729,7 @@ BitmapImage::BitmapImage() : width(0), height(0), row_bytes(0), data(nullptr) {} BitmapImage::BitmapImage(size_t w, size_t h) : width(w), height(h), - row_bytes(byte_count_for_bit_count(this->height)), + row_bytes(byte_count_for_bit_count(this->width)), data(new uint8_t[this->get_data_size()]) { memset(this->data, 0, this->get_data_size()); } @@ -1737,7 +1737,7 @@ BitmapImage::BitmapImage(size_t w, size_t h) BitmapImage::BitmapImage(const BitmapImage& im) : width(im.width), height(im.height), - row_bytes(byte_count_for_bit_count(this->height)), + row_bytes(byte_count_for_bit_count(this->width)), data(new uint8_t[this->get_data_size()]) { memcpy(this->data, im.data, this->get_data_size()); } @@ -1820,7 +1820,7 @@ bool BitmapImage::read_pixel(size_t x, size_t y) const { if (x >= this->width || y >= this->height) { throw runtime_error("out of bounds"); } - return !!(this->data[y * byte_count_for_bit_count(this->width) + (x >> 3)] & (0x80 >> (x & 7))); + return !!(this->data[y * this->row_bytes + (x >> 3)] & (0x80 >> (x & 7))); } void BitmapImage::write_pixel(size_t x, size_t y, bool v) { @@ -1828,12 +1828,19 @@ void BitmapImage::write_pixel(size_t x, size_t y, bool v) { throw runtime_error("out of bounds"); } if (v) { - this->data[y * byte_count_for_bit_count(this->width) + (x >> 3)] |= (0x80 >> (x & 7)); + this->data[y * this->row_bytes + (x >> 3)] |= (0x80 >> (x & 7)); } else { - this->data[y * byte_count_for_bit_count(this->width) + (x >> 3)] &= (0x7F7F >> (x & 7)); + this->data[y * this->row_bytes + (x >> 3)] &= ~(0x80 >> (x & 7)); } } +void BitmapImage::write_row(size_t y, const void* in_data, size_t size_bits) { + if (y >= this->height) { + throw runtime_error("out of bounds"); + } + memcpy(&this->data[y * this->row_bytes], in_data, min(byte_count_for_bit_count(size_bits), row_bytes)); +} + void BitmapImage::invert() { size_t num_bytes = this->get_data_size(); for (size_t z = 0; z < num_bytes; z++) { @@ -1843,14 +1850,13 @@ void BitmapImage::invert() { Image BitmapImage::to_color(uint32_t false_color, uint32_t true_color, bool add_alpha) const { Image ret(this->width, this->height, add_alpha); - uint8_t pending_bits = 0; for (size_t y = 0; y < this->height; y++) { - for (size_t x = 0; x < this->width; x++) { - if (!(x & 7)) { - pending_bits = this->data[(y * this->row_bytes) + (x >> 3)]; + for (size_t x = 0; x < this->width; x += 8) { + uint8_t pending_bits = this->data[(y * this->row_bytes) + (x >> 3)]; + for (size_t z = 0; z < std::min(this->width - x, 8); z++) { + ret.write_pixel(x + z, y, (pending_bits & 0x80) ? true_color : false_color); + pending_bits <<= 1; } - ret.write_pixel(x, y, (pending_bits & 0x80) ? true_color : false_color); - pending_bits <<= 1; } } return ret; diff --git a/src/Image.hh b/src/Image.hh index e6ff7d5..b0539e3 100644 --- a/src/Image.hh +++ b/src/Image.hh @@ -235,6 +235,7 @@ public: void clear(bool v); bool read_pixel(size_t x, size_t y) const; void write_pixel(size_t x, size_t y, bool v); + void write_row(size_t y, const void* in_data, size_t size); void invert(); diff --git a/src/ImageTest.cc b/src/ImageTest.cc index 6766ee8..ca2a8a8 100644 --- a/src/ImageTest.cc +++ b/src/ImageTest.cc @@ -212,7 +212,7 @@ int main(int, char**) { } { - fprintf(stderr, "-- [BitmapImage] write pattern"); + fprintf(stderr, "-- [BitmapImage] write pattern\n"); for (size_t y = 0; y < bm.get_height(); y++) { for (size_t x = 0; x < bm.get_width(); x++) { bm.write_pixel(x, y, (x & y) & 1); @@ -271,7 +271,7 @@ int main(int, char**) { expect_eq(ref, img); } - // unlink(temp_filename); + unlink(temp_filename); } }