crt/img.hpp
#pragma once
#include "common.hpp"
#include "vertex.hpp"
class Img {
public:
typedef unsigned char val_t;
typedef struct __attribute__((packed)) rgb_s {
#ifdef USE_X
// suitable for X11 TrueColor image
val_t b, g, r;
val_t x; // unused
rgb_s(): b(0), g(0), r(0), x(0) {}
rgb_s(val_t rr, val_t gg, val_t bb): b(bb), g(gg), r(rr), x(0) {}
#else
// can be optimized for PPM bitmap files
val_t r, g, b;
rgb_s(): r(0), g(0), b(0) {}
rgb_s(val_t rr, val_t gg, val_t bb): r(rr), g(gg), b(bb) {}
#endif
INLINE rgb_s& operator*=(coord_t o) {
r *= o;
g *= o;
b *= o;
return *this;
}
void debug(const char* prefix) {
LOG("%s0x%02x%02x%02x", prefix?:"", r, g, b);
}
} rgb_t;
private:
rgb_t* const buf;
void* const freebuf;
bool to_ppm(int) const;
public:
const unsigned w, h;
Img(unsigned, unsigned);
Img(unsigned, unsigned, rgb_t*, void*);
~Img();
INLINE rgb_t& at(unsigned x, unsigned y) {
assert(x < w && y < h);
return buf[(y*w)+x];
}
INLINE const rgb_t& at(unsigned x, unsigned y) const {
assert(x < w && y < h);
return buf[(y*w)+x];
}
rgb_t avg(unsigned, unsigned, unsigned, unsigned) const;
rgb_t interpolate(coord_t, coord_t) const;
static Img* from_ppm(const char*);
bool to_ppm(const char*) const;
bool supersample(unsigned, Img*) const;
Img* rotate() const;
void mirror_x();
void mirror_y();
};