-
Notifications
You must be signed in to change notification settings - Fork 6
/
pixels.h
93 lines (73 loc) · 2.69 KB
/
pixels.h
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
/*
* Class to allow pixel access and rotation to an image
*
* Note: Remember to ilInit() before using this
*/
#ifndef H_PIXELS
#define H_PIXELS
#include <mutex>
#include <vector>
#include <string>
#include <IL/il.h>
#include "data.h"
#include "options.h"
struct Mark
{
Coord coord;
int size;
Mark(Coord c, int s)
:coord(c), size(s) { }
};
class Pixels
{
std::vector<Mark> marks;
std::vector<std::vector<unsigned char>> p;
int w;
int h;
bool loaded;
std::string fn;
unsigned char gray_shade;
// Lock this so that only one thread can read an image or save()
// OpenIL/DevIL is not multithreaded
static std::mutex lock;
public:
Pixels(); // Useful for placeholder
Pixels(ILenum type, const char* lump, const int size, const std::string& fn = "");
inline bool valid() const { return loaded; }
inline int width() const { return w; }
inline int height() const { return h; }
inline const std::string& filename() const { return fn; }
// This doesn't extend the image at all. If rotation and points
// are determined correctly, it won't rotate out of the image.
// Note: rad is angle of rotation in radians
void rotate(double rad, const Coord& point);
// Default is used if coord doesn't exist (which should never happen)
// Default to white to assume that this isn't a useful pixel
inline bool black(const Coord& c, const bool default_value = false) const;
// When saving, we'll display marks optionally
void mark(const Coord& m, int size = MARK_SIZE);
// Mark every pixel on the line between p1 and p2
void line(const Coord& p1, const Coord& p2);
// Used for debugging, all processing (converting to black-and-white, adding
// the marks, dimming the image) is done on a copy of the image
void save(const std::string& filename, const bool show_marks = true,
const bool dim = true, const bool bw = true) const;
// Rotate p around origin an amount in radians, sin_rad = sin(rad) and
// cos_rad = cos(rad). We pass in these values because otherwise we calculate
// them thousands of times.
Coord rotatePoint(const Coord& origin, const Coord& p,
double sin_rad, double cos_rad) const;
// Rotate all points in a vector
void rotateVector(std::vector<Coord>& v, const Coord& point, double rad) const;
// Was the image successfully loaded?
bool isLoaded() const { return loaded; }
};
// Used so frequently and so small, so make this inline
inline bool Pixels::black(const Coord& c, const bool default_value) const
{
if (c.x >= 0 && c.y >= 0 &&
c.x < w && c.y < h)
return p[c.y][c.x] < gray_shade;
return default_value;
}
#endif