|
| 1 | +#include <cstdlib> |
| 2 | +#include <fstream> |
| 3 | +#include <iostream> |
| 4 | +#include <string> |
| 5 | + |
| 6 | +#include <image_upscaler/image_upscaler.hpp> |
| 7 | + |
| 8 | +/* Implementation of Rgba */ |
| 9 | +Rgba::Rgba(uint32_t hex) : r((hex & 0xFF'00'00'00) >> 24), g((hex & 0x00'FF'00'00) >> 16), b((hex & 0x00'00'FF'00) >> 8), a(hex & 0x00'00'00'FF) {} |
| 10 | + |
| 11 | +Rgba::Rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {} |
| 12 | + |
| 13 | +constexpr uint32_t Rgba::to_hex(Rgba const& rgba) { return ((rgba.r << 24) | (rgba.g << 16) | (rgba.b << 8) | (rgba.a)); } |
| 14 | + |
| 15 | +/* --- End --- */ |
| 16 | + |
| 17 | +/* Implementation of Image */ |
| 18 | +Image::Image(uint32_t width, uint32_t height) : extent{width, height}, pixels(width * height, Rgba(0)) {} |
| 19 | + |
| 20 | +void Image::export_to_ppm(Image const& input, std::string const& path) { |
| 21 | + std::ofstream output(path); |
| 22 | + output << "P3\n"; |
| 23 | + output << "# " << path << '\n'; |
| 24 | + output << input.extent.width << " " << input.extent.height << '\n'; |
| 25 | + output << "255\n"; |
| 26 | + |
| 27 | + for (uint32_t y = 0; y < input.extent.height; ++y) { |
| 28 | + for (uint32_t x = 0; x < input.extent.width; ++x) { |
| 29 | + Rgba current = input.pixels.at(y * input.extent.width + x); |
| 30 | + output << static_cast<uint32_t>(current.r) << '\n' << static_cast<uint32_t>(current.g) << '\n' << static_cast<uint32_t>(current.b) << '\n'; |
| 31 | + } |
| 32 | + } |
| 33 | + |
| 34 | + output.close(); |
| 35 | +} |
| 36 | + |
| 37 | +Rgba& Image::operator[](Index2D index) { return this->pixels.at(index.y * this->extent.width + index.x); } |
| 38 | + |
| 39 | +Rgba const& Image::operator[](Index2D index) const { return this->pixels.at(index.y * this->extent.width + index.x); } |
| 40 | + |
| 41 | +/* --- End --- */ |
| 42 | + |
| 43 | +Image upscale(Image const& input, uint32_t scale) { |
| 44 | + uint32_t target_width_v = input.extent.width * scale; |
| 45 | + uint32_t target_height_v = input.extent.height * scale; |
| 46 | + uint32_t x_index{0}, y_index{0}; |
| 47 | + Image target_image(target_width_v, target_height_v); |
| 48 | + |
| 49 | + for (y_index = 0; y_index < input.extent.height; ++y_index) { |
| 50 | + for (x_index = 0; x_index < input.extent.width; ++x_index) { |
| 51 | + Rgba current = input[Index2D{x_index, y_index}]; |
| 52 | + if (Rgba::to_hex(current)) { |
| 53 | + for (uint32_t i = y_index * scale; i < ((y_index + 1) * scale); ++i) { |
| 54 | + for (uint32_t j = x_index * scale; j < ((x_index + 1) * scale); ++j) { target_image[Index2D{j, i}] = current; } |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + return target_image; |
| 61 | +} |
0 commit comments