libs/core/src/core/image.cc
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "core/image.h" | ||
| 2 | |||
| 3 | #include "assert/assert.h" | ||
| 4 | |||
| 5 | namespace eu::core | ||
| 6 | { | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | ✗ | Image::Image() = default; | |
| 11 | |||
| 12 | ✗ | bool Image::is_valid() const | |
| 13 | { | ||
| 14 | ✗ | return width > 0 && height > 0 && data.size() == static_cast<size_t>(width * height * 4); | |
| 15 | } | ||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | ✗ | void Image::setup_with_alpha_support(int w, int h) | |
| 20 | { | ||
| 21 | ✗ | width = w; | |
| 22 | ✗ | height = h; | |
| 23 | ✗ | data.resize(width * height * 4, 0); | |
| 24 | ✗ | } | |
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | ✗ | void Image::make_invalid() | |
| 29 | { | ||
| 30 | ✗ | width = 0; | |
| 31 | ✗ | height = 0; | |
| 32 | ✗ | data.clear(); | |
| 33 | ✗ | } | |
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | ✗ | void Image::set_pixel(int x, int y, int r, unsigned char g, unsigned char b, unsigned char a) | |
| 38 | { | ||
| 39 | ✗ | const int index = (y * width + x) * 4; | |
| 40 | ✗ | data[index + 0] = r; | |
| 41 | ✗ | data[index + 1] = g; | |
| 42 | ✗ | data[index + 2] = b; | |
| 43 | ✗ | data[index + 3] = a; | |
| 44 | ✗ | } | |
| 45 | |||
| 46 | ✗ | void Image::set_pixel(int x, int y, const PixelColor& color) | |
| 47 | { | ||
| 48 | ✗ | set_pixel(x, y, color.r, color.g, color.b, color.a); | |
| 49 | ✗ | } | |
| 50 | |||
| 51 | |||
| 52 | ✗ | PixelColor Image::get_pixel(int x, int y) const | |
| 53 | { | ||
| 54 | ✗ | ASSERTX(x >= 0 && x < width && y >= 0 && y < height, x, y, width, height); | |
| 55 | ✗ | const auto index = (y * width + x) * 4; | |
| 56 | return { | ||
| 57 | ✗ | .r = data[index + 0], | |
| 58 | ✗ | .g = data[index + 1], | |
| 59 | ✗ | .b = data[index + 2], | |
| 60 | ✗ | .a = data[index + 3] | |
| 61 | ✗ | }; | |
| 62 | ✗ | } | |
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | ✗ | void paste_image(Image* dst, int dst_x, int dst_y, const Image& src) | |
| 67 | { | ||
| 68 | // Assert valid images | ||
| 69 | ✗ | ASSERT(dst != nullptr); | |
| 70 | ✗ | ASSERT(dst->is_valid()); | |
| 71 | ✗ | ASSERT(src.is_valid()); | |
| 72 | |||
| 73 | ✗ | for (int local_y = 0; local_y < src.height; local_y += 1) | |
| 74 | { | ||
| 75 | ✗ | const auto y = dst_y + local_y; | |
| 76 | ✗ | if (y < 0 || y >= dst->height) | |
| 77 | { | ||
| 78 | // if y is outside the destination image, skip the entire horizontal row | ||
| 79 | ✗ | continue; | |
| 80 | } | ||
| 81 | |||
| 82 | ✗ | for (int local_x = 0; local_x < src.width; local_x += 1) | |
| 83 | { | ||
| 84 | ✗ | const auto x = dst_x + local_x; | |
| 85 | ✗ | if (x < 0 || x >= dst->width) | |
| 86 | { | ||
| 87 | // if x is outside the destination image, skip this pixel | ||
| 88 | ✗ | continue; | |
| 89 | } | ||
| 90 | |||
| 91 | ✗ | const auto src_color = src.get_pixel(local_x, local_y); | |
| 92 | ✗ | dst->set_pixel(x, y, src_color); | |
| 93 | } | ||
| 94 | } | ||
| 95 | ✗ | } | |
| 96 | |||
| 97 | |||
| 98 | } | ||
| 99 |