forked from fuzziqersoftware/phosg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Image.hh
144 lines (120 loc) · 4.5 KB
/
Image.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once
#include <stdint.h>
#include <stdio.h>
#include <stdexcept>
#include <string>
// an Image represents a drawing canvas. this class is fairly simple; it
// supports reading/writing individual pixels, drawing lines, and saving the
// image as a PPM or Windows BMP file.
class Image {
private:
union DataPtrs {
void* raw;
uint8_t* as8;
uint16_t* as16;
uint32_t* as32;
uint64_t* as64;
};
ssize_t width;
ssize_t height;
bool has_alpha;
uint8_t channel_width;
uint64_t max_value;
DataPtrs data;
void load(FILE* f);
public:
Image() = delete;
// construct a black-filled Image in memory
Image(size_t x, size_t y, bool has_alpha = false, uint8_t channel_width = 8);
// copy/move from another image
Image(const Image&);
Image(Image&&);
// load a file (autodetect format)
Image(FILE* f);
Image(const char* filename);
Image(const std::string& filename);
// load from a file (raw data)
Image(FILE* f, ssize_t width, ssize_t height, bool has_alpha = false,
uint8_t channel_width = 0, uint64_t max_value = 0);
Image(const char* filename, ssize_t width, ssize_t height,
bool has_alpha = false, uint8_t channel_width = 0,
uint64_t max_value = 0);
Image(const std::string& filename, ssize_t width, ssize_t height,
bool has_alpha = false, uint8_t channel_width = 0,
uint64_t max_value = 0);
~Image();
const Image& operator=(const Image& other);
const Image& operator=(Image&& other);
bool operator==(const Image& other);
inline size_t get_width() const {
return this->width;
}
inline size_t get_height() const {
return this->height;
}
inline bool get_has_alpha() const {
return this->has_alpha;
}
inline const void* get_data() const {
return this->data.raw;
}
inline uint8_t get_channel_width() const {
return this->channel_width;
}
inline size_t get_data_size() const {
return this->width * this->height * (3 + this->has_alpha) * (this->channel_width / 8);
}
enum ImageFormat {
GrayscalePPM = 0,
ColorPPM = 1,
WindowsBitmap = 2,
};
class unknown_format : virtual public std::runtime_error {
public:
unknown_format(const std::string& what);
};
static const char* mime_type_for_format(ImageFormat format);
static const char* file_extension_for_format(ImageFormat format);
void save(FILE* f, ImageFormat format) const;
void save(const char* filename, ImageFormat format) const;
void save(const std::string& filename, ImageFormat format) const;
std::string save(ImageFormat format) const;
// read/write functions
void clear(uint64_t r, uint64_t g, uint64_t b, uint64_t a = 0xFF);
void read_pixel(ssize_t x, ssize_t y, uint64_t* r, uint64_t* g, uint64_t* b, uint64_t* a = NULL) const;
void write_pixel(ssize_t x, ssize_t y, uint64_t r, uint64_t g, uint64_t b, uint64_t a = 0xFF);
// canvas functions
void reverse_horizontal();
void reverse_vertical();
void set_has_alpha(bool has_alpha);
// drawing functions
// note: no drawing functions respect the alpha channel - they all set it to
// the given alpha value and ignore whatever's already in the image
void draw_line(ssize_t x1, ssize_t y1, ssize_t x2, ssize_t y2, uint64_t r,
uint64_t g, uint64_t b, uint64_t a = 0xFF);
void draw_horizontal_line(ssize_t x1, ssize_t x2, ssize_t y,
ssize_t dash_length, uint64_t r, uint64_t g, uint64_t b,
uint64_t a = 0xFF);
void draw_vertical_line(ssize_t x, ssize_t y1, ssize_t y2,
ssize_t dash_length, uint64_t r, uint64_t g, uint64_t b,
uint64_t a = 0xFF);
#ifndef WINDOWS
void draw_text(ssize_t x, ssize_t y, ssize_t* width, ssize_t* height,
uint64_t r, uint64_t g, uint64_t b, uint64_t a, uint64_t br, uint64_t bg,
uint64_t bb, uint64_t ba, const char* fmt, ...);
#endif
void fill_rect(ssize_t x, ssize_t y, ssize_t w, ssize_t h, uint64_t r,
uint64_t g, uint64_t b, uint64_t a = 0xFF);
// copy functions
// this doesn't respect alpha; the written pixels will have the same alpha as
// in the source image
void blit(const Image& source, ssize_t x, ssize_t y, ssize_t w, ssize_t h,
ssize_t sx, ssize_t sy);
void mask_blit(const Image& source, ssize_t x, ssize_t y, ssize_t w,
ssize_t h, ssize_t sx, ssize_t sy, uint64_t r, uint64_t g, uint64_t b);
void mask_blit(const Image& source, ssize_t x, ssize_t y, ssize_t w,
ssize_t h, ssize_t sx, ssize_t sy, const Image& mask);
// blend functions
void blend_blit(const Image& source, ssize_t x, ssize_t y, ssize_t w, ssize_t h,
ssize_t sx, ssize_t sy);
};