diff options
author | Keuin <[email protected]> | 2022-04-11 12:07:58 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-11 12:08:11 +0800 |
commit | a15c8f6b3658095eb50da4bd75da697e37dbe033 (patch) | |
tree | ef4ec60e5c80b3c9031d60fe7caff52b331eb3e8 /bitmap.h | |
parent | cdb0bdfc60481708ab1a9707c0e1e4458e6396bf (diff) |
Implement bitmap and PPM serialization (with a demo program).
Diffstat (limited to 'bitmap.h')
-rw-r--r-- | bitmap.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/bitmap.h b/bitmap.h new file mode 100644 index 0000000..b94bb25 --- /dev/null +++ b/bitmap.h @@ -0,0 +1,74 @@ +// +// Created by Keuin on 2022/4/11. +// + +#ifndef RT_BITMAP_H +#define RT_BITMAP_H + +#include <vector> +#include <cstdint> +#include <ostream> +#include <cassert> + + +// T is some unsigned integer, do not use float point types! +template<typename T> +struct pixel { + T r, g, b; +}; + +// 8 bit pixel +using pixel8b = pixel<uint8_t>; + +template<typename T> +class bitmap { + const unsigned width, height; + std::vector<pixel<T>> content; // pixels scanned by rows, from top to bottom + + pixel<T> &image(unsigned x, unsigned y) { + assert(x < width); + assert(y < height); + return content[x * width + y]; + } + + pixel<T> &image(unsigned x, unsigned y) const { + assert(x < width); + assert(y < height); + return content[x * width + y]; + } + +public: + bitmap(unsigned int width, unsigned int height) : width(width), height(height) { + content.resize(width * height, pixel<T>{}); + } + + void set(unsigned x, unsigned y, const pixel<T> &pixel) { + image(x, y) = pixel; + } + + pixel<T> get(unsigned x, unsigned y) const { + return image(x, y); + } + + // Do not use float-point pixels, or this routine will break. + void write_plain_ppm(std::ostream &out) const; +}; + +template<typename T> +void bitmap<T>::write_plain_ppm(std::ostream &out) const { + const auto depth = (1ULL << (sizeof(T) * 8)) - 1ULL; // color depth of pixels + out << "P3\n" // file header + << width << ' ' << height << '\n' // image width and height + << depth << '\n'; // normalized max color depth (e.g. 255 for 8bit image) + + for (const auto &pixel: content) { + out << (unsigned long long) pixel.r << ' ' + << (unsigned long long) pixel.g << ' ' + << (unsigned long long) pixel.b << '\n'; + } +} + +using bitmap8b = bitmap<uint8_t>; + + +#endif //RT_BITMAP_H |