mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
148 lines
No EOL
6.9 KiB
C++
148 lines
No EOL
6.9 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
namespace image
|
|
{
|
|
class Image
|
|
{
|
|
protected:
|
|
// Image buffer
|
|
size_t data_size = 0;
|
|
size_t type_size = 0;
|
|
void *d_data = nullptr;
|
|
|
|
// Size and parameters
|
|
int d_depth = 0;
|
|
int d_maxv = 0;
|
|
size_t d_width = 0;
|
|
size_t d_height = 0;
|
|
int d_channels = 0;
|
|
|
|
public:
|
|
// Metadata stuff
|
|
void *metadata_obj = nullptr; // DO NOT USE DIRECTLY!
|
|
protected:
|
|
void copy_meta(const Image &img);
|
|
|
|
public:
|
|
Image(); // Init null image
|
|
Image(int bit_depth, size_t width, size_t height, int channels); // Init emtpy image, set to 0
|
|
Image(void *buffer, int bit_depth, size_t width, size_t height, int channels); // Init from existing buffer
|
|
Image(const Image &img); // Copy constructor
|
|
~Image(); // Destructor
|
|
|
|
Image &operator=(const Image &img);
|
|
|
|
public:
|
|
void to_rgb(); // Convert this image from B&W to RGB (if it is B&W / RGBA)
|
|
void to_rgba(); // Convert this image from to RGBA (if it is B&W / RGB)
|
|
Image to8bits(); // Convert to 8-bits. Returns the current image if it's already 8-bits
|
|
Image to16bits(); // Convert to 16-bits. Returns the current image if it's already 16-bits
|
|
Image to_depth(int bit_depth); // Converts to a specific target bit depth
|
|
|
|
public:
|
|
void draw_image(int channel, Image image, int x = 0, int y = 0); // Draw a B&W Image onto a channel
|
|
void draw_pixel(size_t x, size_t y, std::vector<double> color); // Set a pixel's color
|
|
void draw_line(int x0, int y0, int x1, int y1, std::vector<double> color); // Draw a line with Bresenham's algorithm
|
|
void draw_circle(int x0, int y0, int radius, std::vector<double> color, bool fill = false); // Draw a circle with Bresenham's Midpoint algorithm
|
|
void draw_rectangle(int x0, int y0, int x1, int y1, std::vector<double> color, bool fill = true); // Draw a rectangle onto the image
|
|
|
|
public:
|
|
// Init (empty) image buffer
|
|
void init(int bit_depth, size_t width, size_t height, int channels);
|
|
|
|
// Delete current buffer.
|
|
void clear();
|
|
|
|
public:
|
|
int clamp(int input); // Clamp input value to what this image can handle
|
|
double clampf(double input); // Clamp input value to what this image can handle as float (0, 1)
|
|
|
|
void *raw_data() const { return d_data; } // Returns the RAW void pointer. MUST ONLY BE USED IF YOU KNOW WHAT YOU ARE DOING!
|
|
int depth() const { return d_depth; } // Returns image bit depth
|
|
int typesize() const { return type_size; } // Returns image type size (in bytes)
|
|
size_t width() const { return d_width; } // Returns image width
|
|
size_t height() const { return d_height; } // Returns image height
|
|
int channels() const { return d_channels; } // Returns image channel count
|
|
size_t size() const { return data_size; } // Returns image data size
|
|
int maxval() const { return d_maxv; } // Returns image max value
|
|
|
|
public:
|
|
void crop(int x0, int y0, int x1, int y1); // Crop an image region. Must be with x0 <= x1 and y0 <= y1
|
|
void crop(int x0, int x1); // Crop an image region, x axis only
|
|
Image crop_to(int x0, int y0, int x1, int y1); // Crop an image region. Must be with x0 <= x1 and y0 <= y1, returning the output
|
|
Image crop_to(int x0, int x1); // Crop an image region. Must be with x0 <= x1 and y0 <= y1, returning the output
|
|
|
|
public:
|
|
void mirror(bool x, bool y);
|
|
|
|
public:
|
|
void resize(int width, int height); // Resize image, using a simple pixel scaling attribution (not the best, but fast)
|
|
Image resize_to(int width, int height); // Resize image, to another image
|
|
void resize_bilinear(int width, int height, bool text_mode = false); // Resize image, using a bilinear algorithm
|
|
|
|
int get_pixel_bilinear(int channel, double x, double y);
|
|
|
|
public:
|
|
void fill(int val); // Fill image with a single value
|
|
void fill_color(std::vector<double> color); // Fill image with a color
|
|
|
|
public:
|
|
// Standard int set. No bound check!
|
|
inline void set(size_t p, int v)
|
|
{
|
|
if (d_depth > 8)
|
|
((uint16_t *)d_data)[p] = v;
|
|
else
|
|
((uint8_t *)d_data)[p] = v;
|
|
}
|
|
|
|
// Standard int get. No bound check!
|
|
inline int get(size_t p)
|
|
{
|
|
if (d_depth > 8)
|
|
return ((uint16_t *)d_data)[p];
|
|
else
|
|
return ((uint8_t *)d_data)[p];
|
|
}
|
|
|
|
// Standard double set. No bound check!
|
|
inline void setf(size_t p, double v)
|
|
{
|
|
if (d_depth > 8)
|
|
((uint16_t *)d_data)[p] = v * (double)d_maxv;
|
|
else
|
|
((uint8_t *)d_data)[p] = v * (double)d_maxv;
|
|
}
|
|
|
|
// Standard double get. No bound check!
|
|
inline double getf(size_t p)
|
|
{
|
|
if (d_depth > 8)
|
|
return (double)((uint16_t *)d_data)[p] / (double)d_maxv;
|
|
else
|
|
return (double)((uint8_t *)d_data)[p] / (double)d_maxv;
|
|
}
|
|
|
|
// Easier int set/get
|
|
inline void set(size_t channel, size_t p, int v) { set(channel * d_width * d_height + p, v); }
|
|
inline int get(size_t channel, size_t p) { return get(channel * d_width * d_height + p); }
|
|
inline void set(size_t channel, size_t x, size_t y, int v) { set(channel * d_width * d_height + y * d_width + x, v); }
|
|
inline int get(size_t channel, size_t x, size_t y) { return get(channel * d_width * d_height + y * d_width + x); }
|
|
|
|
// Easier double setf/getf
|
|
inline void setf(size_t channel, size_t p, double v) { setf(channel * d_width * d_height + p, v); }
|
|
inline double getf(size_t channel, size_t p) { return getf(channel * d_width * d_height + p); }
|
|
inline void setf(size_t channel, size_t x, size_t y, double v) { setf(channel * d_width * d_height + y * d_width + x, v); }
|
|
inline double getf(size_t channel, size_t x, size_t y) { return getf(channel * d_width * d_height + y * d_width + x); }
|
|
};
|
|
|
|
// Copy part of an image over. Safe way to do it with variable bit depths
|
|
void imemcpy(Image &img1, size_t pos1, Image &img2, size_t pos2, size_t px_size);
|
|
|
|
// Convert an image to a 8-bit RGBA buffer for OpenGL/etc textures
|
|
void image_to_rgba(Image &img, uint32_t *output);
|
|
} |