summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/gray_core.c')
-rw-r--r--apps/plugins/lib/gray_core.c216
1 files changed, 212 insertions, 4 deletions
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index 6cc33e05da..ef41e7e215 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -33,7 +33,117 @@ struct plugin_api *_gray_rb = NULL; /* global api struct pointer */
33struct _gray_info _gray_info; /* global info structure */ 33struct _gray_info _gray_info; /* global info structure */
34#ifndef SIMULATOR 34#ifndef SIMULATOR
35short _gray_random_buffer; /* buffer for random number generator */ 35short _gray_random_buffer; /* buffer for random number generator */
36
37#if CONFIG_LCD == LCD_SSD1815
38/* measured and interpolated curve */
39static const unsigned char lcdlinear[256] = {
40 0, 3, 5, 8, 11, 13, 16, 18,
41 21, 23, 26, 28, 31, 33, 36, 38,
42 40, 42, 45, 47, 49, 51, 53, 55,
43 57, 59, 60, 62, 64, 66, 67, 69,
44 70, 72, 73, 74, 76, 77, 78, 79,
45 81, 82, 83, 84, 85, 86, 87, 88,
46 88, 89, 90, 91, 92, 92, 93, 94,
47 95, 95, 96, 97, 97, 98, 99, 99,
48 100, 101, 102, 102, 103, 104, 104, 105,
49 106, 106, 107, 107, 108, 109, 109, 110,
50 111, 111, 112, 113, 113, 114, 114, 115,
51 116, 116, 117, 117, 118, 119, 119, 120,
52 120, 121, 121, 122, 122, 123, 123, 124,
53 124, 125, 125, 126, 126, 127, 127, 128,
54 128, 128, 129, 129, 130, 130, 131, 131,
55 132, 132, 133, 133, 133, 134, 134, 135,
56 135, 136, 136, 137, 137, 138, 138, 138,
57 139, 139, 140, 140, 141, 141, 142, 142,
58 143, 143, 144, 144, 145, 145, 146, 146,
59 147, 147, 148, 148, 148, 149, 149, 150,
60 150, 151, 151, 152, 152, 153, 153, 153,
61 154, 154, 155, 155, 156, 156, 157, 157,
62 158, 158, 158, 159, 159, 160, 160, 161,
63 161, 162, 162, 163, 163, 164, 164, 165,
64 165, 166, 167, 167, 168, 168, 169, 169,
65 170, 171, 171, 172, 173, 173, 174, 175,
66 176, 176, 177, 178, 179, 180, 181, 181,
67 182, 183, 184, 185, 186, 188, 189, 190,
68 191, 192, 194, 195, 196, 198, 199, 201,
69 202, 204, 205, 207, 209, 211, 213, 215,
70 217, 219, 222, 224, 226, 229, 231, 234,
71 236, 239, 242, 244, 247, 250, 252, 255
72};
73#elif CONFIG_LCD == LCD_S1D15E06
74/* measured and interpolated curve */
75static const unsigned char lcdlinear[256] = {
76 0, 5, 11, 16, 21, 27, 32, 37,
77 42, 47, 51, 56, 60, 64, 68, 72,
78 75, 78, 81, 84, 87, 89, 91, 93,
79 95, 96, 98, 99, 101, 102, 103, 104,
80 105, 106, 107, 108, 109, 110, 111, 111,
81 112, 113, 113, 114, 115, 115, 116, 117,
82 117, 118, 118, 119, 119, 120, 120, 121,
83 121, 122, 122, 123, 123, 124, 124, 125,
84 125, 126, 126, 127, 127, 127, 128, 128,
85 129, 129, 130, 130, 131, 131, 132, 132,
86 133, 133, 134, 134, 135, 135, 136, 136,
87 137, 137, 138, 138, 138, 139, 139, 140,
88 140, 141, 141, 141, 142, 142, 143, 143,
89 143, 144, 144, 145, 145, 145, 146, 146,
90 146, 147, 147, 147, 148, 148, 149, 149,
91 149, 150, 150, 150, 151, 151, 151, 152,
92 152, 153, 153, 153, 154, 154, 155, 155,
93 155, 156, 156, 157, 157, 157, 158, 158,
94 159, 159, 159, 160, 160, 161, 161, 162,
95 162, 162, 163, 163, 164, 164, 164, 165,
96 165, 166, 166, 167, 167, 167, 168, 168,
97 169, 169, 170, 170, 170, 171, 171, 172,
98 172, 173, 173, 174, 174, 175, 175, 176,
99 176, 177, 177, 178, 178, 179, 179, 180,
100 180, 181, 182, 182, 183, 184, 184, 185,
101 186, 186, 187, 188, 188, 189, 190, 191,
102 191, 192, 193, 194, 195, 196, 196, 197,
103 198, 199, 200, 201, 202, 203, 204, 205,
104 206, 207, 208, 209, 210, 211, 213, 214,
105 215, 216, 218, 219, 220, 222, 223, 225,
106 227, 228, 230, 232, 233, 235, 237, 239,
107 241, 243, 245, 247, 249, 251, 253, 255
108};
36#endif 109#endif
110#else /* SIMULATOR */
111/* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */
112static const unsigned char lcdlinear[256] = {
113 0, 16, 23, 28, 32, 36, 39, 42,
114 45, 48, 50, 53, 55, 58, 60, 62,
115 64, 66, 68, 70, 71, 73, 75, 77,
116 78, 80, 81, 83, 84, 86, 87, 89,
117 90, 92, 93, 94, 96, 97, 98, 100,
118 101, 102, 103, 105, 106, 107, 108, 109,
119 111, 112, 113, 114, 115, 116, 117, 118,
120 119, 121, 122, 123, 124, 125, 126, 127,
121 128, 129, 130, 131, 132, 133, 134, 135,
122 135, 136, 137, 138, 139, 140, 141, 142,
123 143, 144, 145, 145, 146, 147, 148, 149,
124 150, 151, 151, 152, 153, 154, 155, 156,
125 156, 157, 158, 159, 160, 160, 161, 162,
126 163, 164, 164, 165, 166, 167, 167, 168,
127 169, 170, 170, 171, 172, 173, 173, 174,
128 175, 176, 176, 177, 178, 179, 179, 180,
129 181, 181, 182, 183, 183, 184, 185, 186,
130 186, 187, 188, 188, 189, 190, 190, 191,
131 192, 192, 193, 194, 194, 195, 196, 196,
132 197, 198, 198, 199, 199, 200, 201, 201,
133 202, 203, 203, 204, 204, 205, 206, 206,
134 207, 208, 208, 209, 209, 210, 211, 211,
135 212, 212, 213, 214, 214, 215, 215, 216,
136 217, 217, 218, 218, 219, 220, 220, 221,
137 221, 222, 222, 223, 224, 224, 225, 225,
138 226, 226, 227, 228, 228, 229, 229, 230,
139 230, 231, 231, 232, 233, 233, 234, 234,
140 235, 235, 236, 236, 237, 237, 238, 238,
141 239, 240, 240, 241, 241, 242, 242, 243,
142 243, 244, 244, 245, 245, 246, 246, 247,
143 247, 248, 248, 249, 249, 250, 250, 251,
144 251, 252, 252, 253, 253, 254, 254, 255
145};
146#endif /* SIMULATOR */
37 147
38/* Prototypes */ 148/* Prototypes */
39static inline void _deferred_update(void) __attribute__ ((always_inline)); 149static inline void _deferred_update(void) __attribute__ ((always_inline));
@@ -84,6 +194,75 @@ static void _timer_isr(void)
84} 194}
85#endif /* !SIMULATOR */ 195#endif /* !SIMULATOR */
86 196
197/* fixed point exp() */
198static int exp_s16p16(int x)
199{
200 int t;
201 int y = 0x00010000;
202
203 if (x == 0)
204 {
205 return y;
206 }
207 else if (x > 0)
208 {
209 t = x - 0x58b91; if (t >= 0) x = t, y <<= 8;
210 t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4;
211 t = x - 0x162e4; if (t >= 0) x = t, y <<= 2;
212 t = x - 0x0b172; if (t >= 0) x = t, y <<= 1;
213 }
214 else
215 {
216 t = x + 0x58b91; if (t < 0) x = t, y >>= 8;
217 t = x + 0x2c5c8; if (t < 0) x = t, y >>= 4;
218 t = x + 0x162e4; if (t < 0) x = t, y >>= 2;
219 t = x + 0x0b172; if (t < 0) x = t, y >>= 1;
220 x += 0x0b172; y >>= 1;
221 }
222 t = x - 0x067cd; if (t >= 0) x = t, y += y >> 1;
223 t = x - 0x03920; if (t >= 0) x = t, y += y >> 2;
224 t = x - 0x01e27; if (t >= 0) x = t, y += y >> 3;
225 t = x - 0x00f85; if (t >= 0) x = t, y += y >> 4;
226 t = x - 0x007e1; if (t >= 0) x = t, y += y >> 5;
227 t = x - 0x003f8; if (t >= 0) x = t, y += y >> 6;
228 t = x - 0x001fe; if (t >= 0) x = t, y += y >> 7;
229 if (x & 0x100) y += y >> 8;
230 if (x & 0x080) y += y >> 9;
231 if (x & 0x040) y += y >> 10;
232 if (x & 0x020) y += y >> 11;
233 if (x & 0x010) y += y >> 12;
234 if (x & 0x008) y += y >> 13;
235 if (x & 0x004) y += y >> 14;
236 if (x & 0x002) y += y >> 15;
237 if (x & 0x001) y += y >> 16;
238
239 return y;
240}
241
242/* fixed point log() */
243int log_s16p16(int x)
244{
245 int t;
246 int y = 0xa65af;
247
248 if (x < 0x00008000) x <<=16, y -= 0xb1721;
249 if (x < 0x00800000) x <<= 8, y -= 0x58b91;
250 if (x < 0x08000000) x <<= 4, y -= 0x2c5c8;
251 if (x < 0x20000000) x <<= 2, y -= 0x162e4;
252 if (x < 0x40000000) x <<= 1, y -= 0x0b172;
253 t = x + (x >> 1); if ((t & 0x80000000) == 0) x = t, y -= 0x067cd;
254 t = x + (x >> 2); if ((t & 0x80000000) == 0) x = t, y -= 0x03920;
255 t = x + (x >> 3); if ((t & 0x80000000) == 0) x = t, y -= 0x01e27;
256 t = x + (x >> 4); if ((t & 0x80000000) == 0) x = t, y -= 0x00f85;
257 t = x + (x >> 5); if ((t & 0x80000000) == 0) x = t, y -= 0x007e1;
258 t = x + (x >> 6); if ((t & 0x80000000) == 0) x = t, y -= 0x003f8;
259 t = x + (x >> 7); if ((t & 0x80000000) == 0) x = t, y -= 0x001fe;
260 x = 0x80000000 - x;
261 y -= x >> 15;
262
263 return y;
264}
265
87/* Initialise the framework and prepare the greyscale display buffer 266/* Initialise the framework and prepare the greyscale display buffer
88 267
89 arguments: 268 arguments:
@@ -97,6 +276,8 @@ static void _timer_isr(void)
97 width = width in pixels (1..LCD_WIDTH) 276 width = width in pixels (1..LCD_WIDTH)
98 bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8) 277 bheight = height in LCD pixel-block units (8 pixels) (1..LCD_HEIGHT/8)
99 depth = number of bitplanes to use (1..32). 278 depth = number of bitplanes to use (1..32).
279 gamma = gamma value as s8p8 fixed point. gamma <= 0 means no
280 correction at all, i.e. no LCD linearisation as well.
100 281
101 result: 282 result:
102 = depth if there was enough memory 283 = depth if there was enough memory
@@ -128,12 +309,14 @@ static void _timer_isr(void)
128 one situation where it will consume more memory on the sim than on the 309 one situation where it will consume more memory on the sim than on the
129 target: if you're allocating a low depth (< 8) without buffering. */ 310 target: if you're allocating a low depth (< 8) without buffering. */
130int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, 311int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
131 bool buffered, int width, int bheight, int depth, long *buf_taken) 312 bool buffered, int width, int bheight, int depth, int gamma,
313 long *buf_taken)
132{ 314{
133 int possible_depth; 315 int possible_depth, i;
134 long plane_size, buftaken; 316 long plane_size, buftaken;
317 unsigned data;
135#ifndef SIMULATOR 318#ifndef SIMULATOR
136 int i, j; 319 int j;
137#endif 320#endif
138 321
139 _gray_rb = newrb; 322 _gray_rb = newrb;
@@ -240,8 +423,33 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
240 } 423 }
241#endif 424#endif
242 425
426 /* precalculate the value -> pattern index conversion table, taking
427 linearisation and gamma correction into account */
428 if (gamma <= 0)
429 {
430 for (i = 0; i < 256; i++)
431 {
432 data = MULU16(depth, lcdlinear[i]) + 127;
433 _gray_info.idxtable[i] = (data + (data >> 8)) >> 8;
434 /* approx. data / 255 */
435 }
436 }
437 else
438 {
439 for (i = 0; i < 256; i++)
440 {
441 data = exp_s16p16(gamma * (log_s16p16(i * 257 + 1) >> 8));
442 data = (data - (data >> 8)) >> 8; /* approx. data /= 257 */
443 data = MULU16(depth, lcdlinear[data]) + 127;
444 _gray_info.idxtable[i] = (data + (data >> 8)) >> 8;
445 /* approx. data / 255 */
446 }
447 }
448
449 _gray_info.fg_index = 0;
450 _gray_info.bg_index = depth;
243 _gray_info.fg_brightness = 0; 451 _gray_info.fg_brightness = 0;
244 _gray_info.bg_brightness = depth; 452 _gray_info.bg_brightness = 255;
245 _gray_info.drawmode = DRMODE_SOLID; 453 _gray_info.drawmode = DRMODE_SOLID;
246 _gray_info.curfont = FONT_SYSFIXED; 454 _gray_info.curfont = FONT_SYSFIXED;
247 455