Skip to content

Commit 6dd17d3

Browse files
committed
Fixes & improvements to Image, including scaling & arbitrary rotation.
This commit adds bilinear interpolation scaling and arbirary rotation methods to `Image`. In the process, several issues with `Image` were found & fixed: * There was no destructor to free the `canvas` memory. This would cause a memory leak unless the client remembered to call `close()` A virtual destructor has been added to free this memory. * There was no explicit copy & move constructor for `Image` This means whenever Image was copied or passed by value a 'shallow copy' was performed resulting in both instances referencing the same shared canvas memory. This works, and several examples were depending on it, but after the addition of the destructor it caused seg faults since the memory was free()'d several times. An explicit copy constuctor for `Image` has been added to perform a 'deep copy' of the `canvas` memory. A C++11 'move' constructor has been added to avoid excessive deep copies being made when passing `Image` as a temporary. * The same logic for copy/move constructors also applies to assignment operators (operator=()) so these are added. * `Image` (and `Color`) are extensively passed by value within the library. This now potentially inefficient due to the deep copy. (if the move c'tor is not used) Since pass-by-reference semantics are required in these cases they are now passed by reference. * Pass-by-(const)-reference changes also required many methods on `Image` and `Color` that did not modify their members to be declared `const` as well as all `Color` preset constants. * New c'tors and getters added to `Color` to support RGBA access as required by the new scaling method on `Image` Also tidied up c'tors to use common helper methods. * Used new/delete instead of malloc/free for heap memory use in `Image` Just coz it's more conventional in C++
1 parent 1323d5a commit 6dd17d3

15 files changed

+469
-217
lines changed

example/demo1.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ unsigned long long currentTimeMillis() {
4141
}
4242

4343

44-
void drawSine(Image image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
44+
void drawSine(Image &image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
4545
bool first = true;;
4646
int lx = -1, ly = -1;
4747
double vx = 0;
@@ -62,7 +62,7 @@ void drawSine(Image image, float offset, float speed, int maxX, int maxY, float
6262
}
6363

6464

65-
bool demoSineWave(int frameCount, long long start, Image image) {
65+
bool demoSineWave(int frameCount, long long start, Image &image) {
6666
long long now = currentTimeMillis();
6767
float refVoltage = 5;
6868

@@ -148,6 +148,29 @@ void rotationDemo() {
148148

149149
}
150150

151+
void imageRotationDemo(Image &img) {
152+
Image srcImg = img.scale(0.75f, 0.75f, BILINEAR);
153+
for (int deg = 0; deg < 360; deg += 5) {
154+
printf("Rotate: %d degrees CW\n", deg); fflush(stdout);
155+
d1.showImage(srcImg.rotate(deg, DEGREES), DEGREE_270);
156+
}
157+
for (int deg = 0; deg > -360; deg -= 5) {
158+
printf("Rotate: %d degrees CCW\n", deg); fflush(stdout);
159+
d1.showImage(srcImg.rotate(deg, DEGREES), DEGREE_270);
160+
}
161+
}
162+
163+
void imageScalingDemo(Image &img) {
164+
for (int i = 100; i > 0; i -= 10) {
165+
float scale = i / 100.0f;
166+
d1.showImage(img.scale(scale, scale, BILINEAR), DEGREE_270);
167+
}
168+
for (int i = 20; i <= 200; i += 10) {
169+
float scale = i / 100.0f;
170+
d1.showImage(img.scale(scale, scale, BILINEAR), DEGREE_270);
171+
}
172+
}
173+
151174
void display1Demo() {
152175
printf("demo1\n"); fflush(stdout);
153176

@@ -170,8 +193,8 @@ void display1Demo() {
170193
delay(solidsDelay);
171194
d1.clearScreen(BLACK);
172195

173-
d1.showImage(bmp, DEGREE_270);
174-
delay(2000);
196+
imageRotationDemo(bmp);
197+
imageScalingDemo(bmp);
175198

176199
rotationDemo();
177200
delay(4000);
@@ -189,6 +212,7 @@ void configureDisplay1() {
189212
d1Config.width = 240;
190213
d1Config.height = 320;
191214
d1Config.spiSpeed = spiSpeed;
215+
d1Config.spiMode = 0;
192216

193217
d1Config.CS = 21;
194218
d1Config.DC = 22;
@@ -215,14 +239,6 @@ int main(int argc, char **argv)
215239
digitalWrite(10, HIGH);
216240
digitalWrite(11, HIGH);
217241

218-
int demos = 3;
219-
pthread_t threads[demos];
220-
char message[demos][256];
221-
222-
for (int i = 0; i < demos; ++i) {
223-
sprintf(message[i], "demo thread %d", i);
224-
}
225-
226242
configureDisplay1();
227243

228244
printf("press control-c to quit\n");

example/demo2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ unsigned long long currentTimeMillis() {
4242
}
4343

4444

45-
void drawSine(Image image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
45+
void drawSine(Image &image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
4646
bool first = true;;
4747
int lx = -1, ly = -1;
4848
double vx = 0;
@@ -63,7 +63,7 @@ void drawSine(Image image, float offset, float speed, int maxX, int maxY, float
6363
}
6464

6565

66-
bool demoSineWave(int frameCount, long long start, Image image) {
66+
bool demoSineWave(int frameCount, long long start, Image &image) {
6767
long long now = currentTimeMillis();
6868
float refVoltage = 5;
6969

example/neopixel2.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ unsigned long long currentTimeMillis() {
7373
}
7474

7575

76-
void drawSine(Image image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
76+
void drawSine(Image &image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
7777
bool first = true;
7878
int lx = -1, ly = -1;
7979
double vx = 0;
@@ -94,7 +94,7 @@ void drawSine(Image image, float offset, float speed, int maxX, int maxY, float
9494
}
9595

9696

97-
bool demoSineWave(int frameCount, long long start, Image image) {
97+
bool demoSineWave(int frameCount, long long start, Image &image) {
9898
long long now = currentTimeMillis();
9999
float refVoltage = 5;
100100

@@ -394,7 +394,7 @@ void* setBrightness(void *) {
394394

395395
int startTime=currentTimeMillis();
396396
for (int i=0;i<4;++i) {
397-
float v=readVoltage(handle, i, 0);
397+
float v=readVoltage(handle);
398398
if (v>6) {
399399
v=0;
400400
}

example/wsePaperV2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ unsigned long long currentTimeMillis() {
3939
}
4040

4141

42-
void drawSine(Image image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
42+
void drawSine(Image &image, float offset, float speed, int maxX, int maxY, float waveHeight, Color color, int width) {
4343
bool first = true;;
4444
int lx = -1, ly = -1;
4545
double vx = 0;
@@ -60,7 +60,7 @@ void drawSine(Image image, float offset, float speed, int maxX, int maxY, float
6060
}
6161

6262

63-
bool demoSineWave(int frameCount, long long start, Image image) {
63+
bool demoSineWave(int frameCount, long long start, Image &image) {
6464
long long now = currentTimeMillis();
6565
float refVoltage = 5;
6666

src/controller/Color.cpp

Lines changed: 44 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ Color::Color() {
99
color.opacity = 255;
1010
}
1111

12-
1312
Color::Color(ColorType color) {
14-
this->color.red = color.red;
15-
this->color.green = color.green;
16-
this->color.blue = color.blue;
17-
this->color.opacity = color.opacity;
13+
memcpy(&this->color, &color, sizeof(ColorType));
1814
}
1915

20-
2116
Color::Color(_byte red, _byte green, _byte blue) {
22-
color.red = red;
23-
color.green = green;
24-
color.blue = blue;
25-
color.opacity = 255;
17+
setColor(red, green, blue, 255);
18+
}
19+
20+
Color::Color(_byte red, _byte green, _byte blue, _byte opacity) {
21+
setColor(red, green, blue, opacity);
2622
}
2723

24+
Color::Color(uint32_t colorRGB24) {
25+
setRGB24(colorRGB24);
26+
}
27+
2828
Color::Color(const char* hexbytes) {
2929
char buf[3];
3030
int intensity;
@@ -68,63 +68,37 @@ Color::Color(const char* hexbytes) {
6868
}
6969
}
7070

71-
bool Color::equals(Color otherColor) {
72-
if (this->color.blue != otherColor.color.blue) {
73-
return false;
74-
}
75-
if (this->color.red!= otherColor.color.red) {
76-
return false;
77-
}
78-
if (this->color.green != otherColor.color.green) {
79-
return false;
80-
}
81-
return true;
71+
bool Color::equals(const Color &otherColor) const {
72+
return equals(otherColor.color);
8273
}
8374

84-
bool Color::equals(ColorType otherColor) {
85-
if (this->color.blue != otherColor.blue) {
75+
bool Color::equals(const ColorType &otherColor) const {
76+
if (color.blue != otherColor.blue) {
8677
return false;
8778
}
88-
if (this->color.red != otherColor.red) {
79+
if (color.red != otherColor.red) {
8980
return false;
9081
}
91-
if (this->color.green != otherColor.green) {
82+
if (color.green != otherColor.green) {
9283
return false;
9384
}
9485
return true;
9586
}
9687

97-
bool Color::equals(ColorType *otherColor) {
98-
if (this->color.blue != otherColor->blue) {
99-
return false;
100-
}
101-
if (this->color.red != otherColor->red) {
102-
return false;
103-
}
104-
if (this->color.green != otherColor->green) {
105-
return false;
106-
}
107-
return true;
108-
}
109-
110-
111-
Color::Color(_byte red, _byte green, _byte blue, _byte opacity) {
112-
color.red = red;
113-
color.green = green;
114-
color.blue = blue;
115-
color.opacity = opacity;
116-
}
117-
118-
ColorType Color::toType() {
119-
return color;
88+
inline void Color::setColor(_byte red, _byte green, _byte blue, _byte opacity) {
89+
color.red = red;
90+
color.green = green;
91+
color.blue = blue;
92+
color.opacity = opacity;
12093
}
12194

122-
123-
int32_t Color::rgb24() {
124-
return (color.green<<16)+(color.red<<8)+(color.blue);
95+
inline void Color::setRGB24(uint32_t colorRGB24) {
96+
color.red = (_byte)(colorRGB24 & 0xFF);
97+
color.green = (_byte)((colorRGB24 & 0xFF00) >> 8);
98+
color.blue = (_byte)((colorRGB24 & 0xFF0000) >> 16);
99+
color.opacity = (_byte)((colorRGB24 & 0xFF000000) >> 24);
125100
}
126101

127-
128102
Color::Color(int clr) {
129103
color.opacity = 255;
130104

@@ -150,7 +124,7 @@ Color::Color(int clr) {
150124
}
151125

152126

153-
void Color::print() {
127+
void Color::print() const {
154128

155129
printf("color::print: 0x%02x%02x%02x\n", this->color.red, this->color.blue,this->color.green);
156130
printf("color::print: 0x%02x%02x%02x\n", color.red, color.blue, color.green);
@@ -164,26 +138,26 @@ void Color::print() {
164138

165139

166140
// Original 8
167-
Color BLACK = Color(0, 0, 0);
168-
Color RED = Color(255, 0, 0);
169-
Color GREEN = Color(0, 255, 0);
170-
Color BLUE = Color(0, 0, 255);
171-
Color YELLOW = Color(255, 255, 0);
172-
Color MAGENTA = Color(255, 0, 255);
173-
Color CYAN = Color(0, 255, 255);
174-
Color WHITE = Color(255, 255, 255);
141+
const Color BLACK = Color(0, 0, 0);
142+
const Color RED = Color(255, 0, 0);
143+
const Color GREEN = Color(0, 255, 0);
144+
const Color BLUE = Color(0, 0, 255);
145+
const Color YELLOW = Color(255, 255, 0);
146+
const Color MAGENTA = Color(255, 0, 255);
147+
const Color CYAN = Color(0, 255, 255);
148+
const Color WHITE = Color(255, 255, 255);
175149

176150
// extended colors
177-
Color GRAY = Color("#808080");
178-
Color BROWN = Color(165, 42, 42);
179-
Color ORANGE = Color(255, 128, 0);
151+
const Color GRAY = Color("#808080");
152+
const Color BROWN = Color(165, 42, 42);
153+
const Color ORANGE = Color(255, 128, 0);
180154

181-
Color DARK_RED = Color(128, 0, 0);
182-
Color DARK_GREEN = Color(0, 128, 0);
183-
Color DARK_BLUE = Color(0, 0, 128);
155+
const Color DARK_RED = Color(128, 0, 0);
156+
const Color DARK_GREEN = Color(0, 128, 0);
157+
const Color DARK_BLUE = Color(0, 0, 128);
184158

185159

186-
Color LIGHT_BLUE = Color(204, 228, 255);
187-
Color LIGHT_GRAY = Color("#E0E0E0");
160+
const Color LIGHT_BLUE = Color(204, 228, 255);
161+
const Color LIGHT_GRAY = Color("#E0E0E0");
188162

189-
Color DARK_GRAY_BLUE = Color("003366");
163+
const Color DARK_GRAY_BLUE = Color("003366");

src/controller/Color.h

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,49 +12,54 @@ struct ColorStruct {
1212

1313
typedef ColorStruct ColorType;
1414

15+
inline uint32_t getRGB24(const ColorType *color) {
16+
return (color->opacity << 24 ) | (color->blue << 16) | (color->green << 8) | color->red;
17+
}
1518

1619
class Color {
1720
public:
1821
ColorType color;
1922

2023
Color();
2124
Color(ColorType color);
22-
Color(_byte red, _byte blue, _byte green);
25+
Color(_byte red, _byte green, _byte blue);
26+
Color(_byte red, _byte green, _byte blue, _byte opacity);
27+
Color(uint32_t colorRGB24);
2328
Color(const char *hexbytes);
24-
Color(_byte red, _byte blue, _byte green, _byte opacity);
25-
29+
2630
Color(int pos);
2731

28-
ColorType toType();
29-
int32_t rgb24();
30-
void print();
31-
bool equals(Color otherColor);
32-
bool equals(ColorType otherColor);
33-
bool equals(ColorType *otherColor);
32+
inline ColorType toType() const { return color; }
33+
inline uint32_t rgb24() const { return getRGB24(&color); }
34+
inline void setColor(_byte red, _byte green, _byte blue, _byte opacity);
35+
inline void setRGB24(uint32_t colorRGB24);
36+
void print() const;
37+
bool equals(const Color &otherColor) const;
38+
bool equals(const ColorType &otherColor) const;
3439

3540
};
3641

3742

3843
// original 8
39-
extern Color BLACK;
40-
extern Color RED;
41-
extern Color GREEN;
42-
extern Color BLUE;
43-
extern Color YELLOW;
44-
extern Color MAGENTA;
45-
extern Color CYAN;
46-
extern Color WHITE;
47-
48-
extern Color GRAY;
49-
extern Color BROWN;
50-
extern Color ORANGE;
51-
52-
extern Color LIGHT_BLUE;
53-
extern Color LIGHT_GRAY;
54-
55-
extern Color DARK_BLUE;
56-
extern Color DARK_RED;
57-
extern Color DARK_GREEN;
58-
59-
extern Color DARK_GRAY_BLUE;
44+
extern const Color BLACK;
45+
extern const Color RED;
46+
extern const Color GREEN;
47+
extern const Color BLUE;
48+
extern const Color YELLOW;
49+
extern const Color MAGENTA;
50+
extern const Color CYAN;
51+
extern const Color WHITE;
52+
53+
extern const Color GRAY;
54+
extern const Color BROWN;
55+
extern const Color ORANGE;
56+
57+
extern const Color LIGHT_BLUE;
58+
extern const Color LIGHT_GRAY;
59+
60+
extern const Color DARK_BLUE;
61+
extern const Color DARK_RED;
62+
extern const Color DARK_GREEN;
63+
64+
extern const Color DARK_GRAY_BLUE;
6065

0 commit comments

Comments
 (0)