bsnes/nall/image/base.hpp

127 lines
5.1 KiB
C++

#ifndef NALL_IMAGE_BASE_HPP
#define NALL_IMAGE_BASE_HPP
namespace nall {
struct image {
uint8_t* data = nullptr;
unsigned width = 0;
unsigned height = 0;
unsigned pitch = 0;
unsigned size = 0;
bool endian = 0; //0 = lsb, 1 = msb
unsigned depth = 32;
unsigned stride = 4;
struct channel {
uint64_t mask;
unsigned depth;
unsigned shift;
inline bool operator==(const channel& source) const {
return mask == source.mask && depth == source.depth && shift == source.shift;
}
inline bool operator!=(const channel& source) const {
return !operator==(source);
}
};
channel alpha = {255u << 24, 8u, 24u};
channel red = {255u << 16, 8u, 16u};
channel green = {255u << 8, 8u, 8u};
channel blue = {255u << 0, 8u, 0u};
enum class blend : unsigned {
add,
sourceAlpha, //color = sourceColor * sourceAlpha + targetColor * (1 - sourceAlpha)
sourceColor, //color = sourceColor
targetAlpha, //color = targetColor * targetAlpha + sourceColor * (1 - targetAlpha)
targetColor, //color = targetColor
};
//static.hpp
static inline unsigned bitDepth(uint64_t color);
static inline unsigned bitShift(uint64_t color);
static inline uint64_t normalize(uint64_t color, unsigned sourceDepth, unsigned targetDepth);
//core.hpp
inline explicit operator bool() const;
inline bool operator==(const image& source) const;
inline bool operator!=(const image& source) const;
inline image& operator=(const image& source);
inline image& operator=(image&& source);
inline image(const image& source);
inline image(image&& source);
inline image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
inline image(const string& filename);
inline image(const vector<uint8_t>& buffer);
inline image(const uint8_t* data, unsigned size);
inline image();
inline ~image();
inline uint64_t read(const uint8_t* data) const;
inline void write(uint8_t* data, uint64_t value) const;
inline void free();
inline bool empty() const;
inline bool load(const string& filename);
inline void allocate(unsigned width, unsigned height);
//fill.hpp
inline void fill(uint64_t color = 0);
inline void gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d);
inline void gradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY, function<double (double, double)> callback);
inline void crossGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void diamondGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void horizontalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void radialGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void sphericalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void squareGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
inline void verticalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY);
//scale.hpp
inline void scale(unsigned width, unsigned height, bool linear = true);
//blend.hpp
inline void impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned x, unsigned y, unsigned width, unsigned height);
//utility.hpp
inline bool crop(unsigned x, unsigned y, unsigned width, unsigned height);
inline void alphaBlend(uint64_t alphaColor);
inline void transform(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
protected:
//core.hpp
inline uint8_t* allocate(unsigned width, unsigned height, unsigned stride);
//scale.hpp
inline void scaleLinearWidth(unsigned width);
inline void scaleLinearHeight(unsigned height);
inline void scaleLinear(unsigned width, unsigned height);
inline void scaleNearest(unsigned width, unsigned height);
//load.hpp
inline bool loadBMP(const string& filename);
inline bool loadPNG(const string& filename);
inline bool loadPNG(const uint8_t* data, unsigned size);
//interpolation.hpp
alwaysinline void isplit(uint64_t* component, uint64_t color);
alwaysinline uint64_t imerge(const uint64_t* component);
alwaysinline uint64_t interpolate1f(uint64_t a, uint64_t b, double x);
alwaysinline uint64_t interpolate1f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y);
alwaysinline uint64_t interpolate1i(int64_t a, int64_t b, uint32_t x);
alwaysinline uint64_t interpolate1i(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y);
inline uint64_t interpolate4f(uint64_t a, uint64_t b, double x);
inline uint64_t interpolate4f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y);
inline uint64_t interpolate4i(uint64_t a, uint64_t b, uint32_t x);
inline uint64_t interpolate4i(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint32_t x, uint32_t y);
};
}
#endif