Skip to content

Commit bca8166

Browse files
committed
0.3.0 GAMMA
1 parent 2510474 commit bca8166

File tree

11 files changed

+187
-49
lines changed

11 files changed

+187
-49
lines changed

libraries/GAMMA/README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ In short, choose the size that fits your application.
2929

3030
The library has a **setGamma(float gamma)** function that allows an application
3131
to change the gamma value runtime.
32-
This allows adjustments that a fixed table does not have.
32+
This allows adjustments that are not possible with a fixed table.
3333

3434
The class provides **dump()** to create a table e.g. to place in PROGMEM.
3535
Since 0.2.2 the library also has **dumpArray()** to generate a C-style array.
@@ -46,18 +46,22 @@ array as parameter. The default for size = 32 as this is a good balance between
4646
and size of the internal array.
4747
The size parameter must be in {2, 4, 8, 16, 32, 64, 128, 256 }.
4848
- **~GAMMA()** destructor.
49-
- **void begin()** The internal array is allocated and initialized with a gamma == 2.8.
49+
- **bool begin()** The internal array is allocated and initialized with a gamma == 2.8.
5050
This is an often used value to adjust light to human eye responses.
5151
Note that **begin()** must be called before any other function.
52+
Returns false if allocation fails.
5253
- **void setGamma(float gamma)** calculates and fills the array with new values.
5354
This can be done runtime so runtime adjustment of gamma mapping is possible.
5455
This calculation are relative expensive and takes quite some time (depending on size).
5556
If the array already is calculated for gamma, the calculation will be skipped.
5657
The parameter **gamma** must be > 0. The value 1 gives an 1:1 mapping.
58+
Returns false if gamma <= 0 or if no table is allocated.
5759
- **float getGamma()** returns the set gamma value.
58-
- **uint8_t operator \[\]** allows the GAMMA object to be accessed as an array.
60+
- **uint8_t operator \[uint8_t index\]** allows the GAMMA object to be accessed as an array.
5961
like ```x = G[40];``` Makes it easy to switch with a real array.
60-
The value returned is in the range 0 .. 255, so the user may need to scale it e.g. to 0.0 - 1.0
62+
The value returned is in the range 0 .. 255, so the user may need to scale it e.g. to 0.0 - 1.0.
63+
Note: if internal table not allocated the function returns 0.
64+
As this is a legitimate value the user should take care.
6165

6266

6367
### Development functions
@@ -66,9 +70,11 @@ The value returned is in the range 0 .. 255, so the user may need to scale it e.
6670
This is always a power of 2.
6771
- **uint16_t distinct()** returns the number of distinct values in the table.
6872
Especially with larger internal tables there will be duplicate numbers in the table.
69-
- **void dump(Stream \*str = &Serial)** dumps the internal table to a stream, default Serial.
73+
- **bool dump(Stream \*str = &Serial)** dumps the internal table to a stream, default Serial.
7074
Useful to create an array in RAM, PROGMEM, EEPROM, in a file or wherever.
75+
Returns false if no table is allocated.
7176
- **void dumpArray(Stream \*str = &Serial)** dumps the internal table to a stream, default Serial, as a C-style array. See example.
77+
Returns false if no table is allocated.
7278

7379

7480
## Operation
@@ -83,10 +89,8 @@ See example.
8389
- look for optimizations
8490
- getter \[\]
8591
- setGamma -> pow() is expensive
86-
- improvements (0.3.0)
87-
- return bool => begin() + setGamma() + dump()?
88-
- check \_table != NULL in functions
89-
- add gamma<=0 check in setGamma()
9092
- uint16 version?
93+
- GAMMA16, GAMMA32,
94+
- GAMMA_RGB ?
9195
-
9296

libraries/GAMMA/examples/GammaErrorAnalysis/GammaErrorAnalysis.ino

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ GAMMA gt8(2);
1919
uint32_t start, d1;
2020
volatile int x;
2121

22+
int total = 0;
2223

2324
void setup()
2425
{
@@ -39,21 +40,22 @@ void setup()
3940

4041
Serial.println("\nError Analysis 256 elements = reference\n");
4142
Serial.println("Size\tErrors\tMaximum");
42-
test_error(gt1);
43-
test_error(gt2);
44-
test_error(gt3);
45-
test_error(gt4);
46-
test_error(gt5);
47-
test_error(gt6);
48-
test_error(gt7);
49-
test_error(gt8);
50-
Serial.println();
43+
total += test_error(gt1);
44+
total += test_error(gt2);
45+
total += test_error(gt3);
46+
total += test_error(gt4);
47+
total += test_error(gt5);
48+
total += test_error(gt6);
49+
total += test_error(gt7);
50+
// total += test_error(gt8);
51+
Serial.print("TOT\t");
52+
Serial.println(total);
5153

5254
Serial.println("\ndone...\n");
5355
}
5456

5557

56-
void test_error(GAMMA gt)
58+
int test_error(GAMMA gt)
5759
{
5860
int count = 0;
5961
int maxdiff = 0;
@@ -70,6 +72,7 @@ void test_error(GAMMA gt)
7072
Serial.print(count);
7173
Serial.print('\t');
7274
Serial.println(maxdiff);
75+
return count;
7376
}
7477

7578

@@ -79,4 +82,3 @@ void loop()
7982

8083

8184
// -- END OF FILE --
82-
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Arduino UNO
2+
IDE 1.8.19
3+
4+
GammaErrorAnalysis.ino
5+
GAMMA_LIB_VERSION: 0.2.2
6+
7+
Error Analysis 256 elements = reference
8+
9+
Size Errors Maximum
10+
257 0 0
11+
129 29 1
12+
65 38 2
13+
33 46 2
14+
17 58 2
15+
9 177 2
16+
5 233 8
17+
TOT 581
18+
19+
done...
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Arduino UNO
2+
IDE 1.8.19
3+
4+
GammaErrorAnalysis.ino
5+
GAMMA_LIB_VERSION: 0.3.0
6+
7+
Error Analysis 256 elements = reference
8+
9+
Size Errors Maximum
10+
257 0 0
11+
129 29 1
12+
65 34 2
13+
33 32 2
14+
17 46 2
15+
9 159 2
16+
5 235 8
17+
TOT 535
18+
19+
done...
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Arduino UNO
2+
IDE 1.8.19
3+
4+
GammaPerformance.ino
5+
GAMMA_LIB_VERSION: 0.3.0
6+
7+
timing in microseconds
8+
9+
SETGAMMA
10+
SIZE TIME TIME per element
11+
257 85872 334.13
12+
129 42696 330.98
13+
65 21172 325.72
14+
33 10420 315.76
15+
17 5052 297.18
16+
17+
SETGAMMA II
18+
SIZE TIME TIME per element
19+
257 8 0.03
20+
129 8 0.06
21+
65 8 0.12
22+
33 8 0.24
23+
17 8 0.47
24+
25+
GET[]
26+
SIZE TIME TIME per element
27+
257 460 1.80
28+
129 972 3.80
29+
65 1212 4.73
30+
33 1428 5.58
31+
17 1616 6.31
32+
33+
34+
done...

libraries/GAMMA/gamma.cpp

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: gamma.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.2.2
4+
// VERSION: 0.3.0
55
// DATE: 2020-08-08
66
// PURPOSE: Arduino Library to efficiently hold a gamma lookup table
77

@@ -16,6 +16,13 @@
1616
// add Stream parameter to dump()
1717
// add dumpArray(Stream)
1818
// fix distinct()
19+
//
20+
// 0.3.0 2022-07-26 change return type begin() + setGamma()
21+
// add test gamma <=0 in setGamma()
22+
// add _table == NULL tests
23+
// fixed type of index in [] operator.
24+
// adjust rounding in setGamma() to minimize errors.
25+
// update build-CI
1926

2027

2128
#include "gamma.h"
@@ -45,21 +52,25 @@ GAMMA::~GAMMA()
4552
};
4653

4754

48-
void GAMMA::begin()
55+
bool GAMMA::begin()
4956
{
5057
if (_table == NULL)
5158
{
5259
_table = (uint8_t *)malloc(_size + 1);
5360
}
61+
if (_table == NULL) return false;
5462
setGamma(2.8);
63+
return true;
5564
};
5665

5766

58-
void GAMMA::setGamma(float gamma)
67+
bool GAMMA::setGamma(float gamma)
5968
{
69+
if (_table == NULL) return false;
70+
if (gamma <= 0) return false;
6071
if (_gamma != gamma)
6172
{
62-
yield(); // keep ESP happy
73+
yield(); // try to keep ESP happy
6374
_gamma = gamma;
6475
// marginally faster
6576
// uint16_t iv = _interval;
@@ -70,12 +81,15 @@ void GAMMA::setGamma(float gamma)
7081
// _table[i] = exp(x * _gamma) * 255 + 0.5;
7182
// }
7283
// REFERENCE
73-
for (uint16_t i = 0; i < _size; i++)
84+
// rounding factor 0.444 optimized with error example.
85+
for (uint16_t i = 1; i < _size; i++)
7486
{
75-
_table[i] = pow(i * _interval * (1.0/ 255.0), _gamma) * 255 + 0.5;
87+
_table[i] = pow(i * _interval * (1.0/ 255.0), _gamma) * 255 + 0.444;
7688
}
77-
_table[_size] = 255; // anchor for interpolation..
89+
_table[0] = 0;
90+
_table[_size] = 255; // anchor for interpolation.
7891
}
92+
return true;
7993
};
8094

8195

@@ -87,13 +101,17 @@ float GAMMA::getGamma()
87101

88102
uint8_t GAMMA::operator[] (uint8_t index)
89103
{
104+
// 0.3.0 _table test slows performance ~0.4 us.
105+
if (_table == NULL) return 0;
90106
if (_interval == 1) return _table[index];
91107
// else interpolate
92108
uint8_t i = index >> _shift;
93109
uint8_t m = index & _mask;
94110
// exact element shortcut
95111
if ( m == 0 ) return _table[i];
96-
// interpolation
112+
// interpolation
113+
// delta must be uint16_t to prevent overflow. (small tables)
114+
// delta * m can be > 8 bit.
97115
uint16_t delta = _table[i+1] - _table[i];
98116
delta = (delta * m + _interval/2) >> _shift; // == /_interval;
99117
return _table[i] + delta;
@@ -120,17 +138,20 @@ uint16_t GAMMA::distinct()
120138
};
121139

122140

123-
void GAMMA::dump(Stream *str)
141+
bool GAMMA::dump(Stream *str)
124142
{
143+
if (_table == NULL) return false;
125144
for (uint16_t i = 0; i <= _size; i++)
126145
{
127146
str->println(_table[i]);
128147
}
148+
return true;
129149
};
130150

131151

132-
void GAMMA::dumpArray(Stream *str)
152+
bool GAMMA::dumpArray(Stream *str)
133153
{
154+
if (_table == NULL) return false;
134155
str->println();
135156
str->print("uint8_t gamma[");
136157
str->print(_size + 1);
@@ -143,8 +164,18 @@ void GAMMA::dumpArray(Stream *str)
143164
if (i < _size) str->print(", ");
144165
}
145166
str->print("\n };\n\n");
167+
return true;
146168
};
147169

148170

171+
// performance investigation
172+
// https://stackoverflow.com/questions/43429238/using-boost-cpp-int-for-functions-like-pow-and-rand
173+
inline float GAMMA::fastPow(float a, float b)
174+
{
175+
// reference
176+
return pow(a, b);
177+
}
178+
179+
149180
// -- END OF FILE --
150181

libraries/GAMMA/gamma.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
//
33
// FILE: gamma.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.2.2
5+
// VERSION: 0.3.0
66
// DATE: 2020-08-08
77
// PURPOSE: Arduino Library to efficiently hold a gamma lookup table
88

99

1010
#include "Arduino.h"
1111

12-
#define GAMMA_LIB_VERSION (F("0.2.2"))
12+
#define GAMMA_LIB_VERSION (F("0.3.0"))
1313

1414
#define GAMMA_DEFAULT_SIZE 32
1515
#define GAMMA_MAX_SIZE 256
@@ -25,30 +25,35 @@ class GAMMA
2525

2626
// allocates memory
2727
// sets default gamma = 2.8
28-
void begin();
28+
// Returns false if allocation fails
29+
bool begin();
2930

3031
// CORE
31-
void setGamma(float gamma);
32+
// Returns false if gamma <= 0
33+
bool setGamma(float gamma);
3234
float getGamma();
3335
// access values with index operator
36+
// index = 0 .. size
3437
uint8_t operator[] (uint8_t index);
3538

3639
// META INFO
3740
uint16_t size();
3841
uint16_t distinct();
3942

4043
// DEBUG
41-
void dump(Stream *str = &Serial);
42-
void dumpArray(Stream *str = &Serial);
44+
bool dump(Stream *str = &Serial);
45+
bool dumpArray(Stream *str = &Serial);
4346

4447

4548
private:
4649
uint8_t _shift = 0;
4750
uint8_t _mask = 0;
4851
uint16_t _size = 0;
4952
uint8_t _interval = 0;
50-
float _gamma = 0;
53+
float _gamma = 1.0; // 1.0 == no gamma, linear.
5154
uint8_t * _table = NULL;
55+
56+
float fastPow(float a, float b);
5257
};
5358

5459

libraries/GAMMA/keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ dumpArray KEYWORD2
1515

1616
# Constants (LITERAL1)
1717
GAMMA_LIB_VERSION LITERAL1
18+
GAMMA_DEFAULT_SIZE LITERAL1
19+
GAMMA_MAX_SIZE LITERAL1
1820

libraries/GAMMA/library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"type": "git",
1616
"url": "https://github.com/RobTillaart/GAMMA.git"
1717
},
18-
"version": "0.2.2",
18+
"version": "0.3.0",
1919
"license": "MIT",
2020
"frameworks": "arduino",
2121
"platforms": "*",

0 commit comments

Comments
 (0)