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
|
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <zlib.h>
#include "compress.c"
#define EVA_SIZE (sizeof(uint64_t) * MVEC_SIZE)
void eva_render(sqlite3_context *context, int argc, sqlite3_value **argv) {
assert(context);
assert(argc == 4);
assert(argv);
(void)argc;
size_t left = (size_t)sqlite3_value_int(argv[0]);
#if defined(MVEC_LOOP)
left %= MVEC_SIZE;
#endif
size_t px_count = (size_t)sqlite3_value_int(argv[1]);
size_t px_pow = (size_t)sqlite3_value_int(argv[2]);
size_t px_res = 1 << px_pow;
#if !defined(MVEC_LOOP)
#if !defined(NDEBUG)
size_t right = left + px_res * px_count;
#endif
assert(left < MVEC_SIZE);
assert(right <= MVEC_SIZE);
#endif
const void *blob = sqlite3_value_blob(argv[3]);
size_t blob_size = (size_t)sqlite3_value_bytes(argv[3]);
// Inflate blob
size_t out_size = sizeof(uint64_t) * px_count;
uint64_t *eva = sqlite3_malloc(EVA_SIZE);
uint64_t *out = sqlite3_malloc(out_size);
z_stream strm = { 0 };
salis_inflate(&strm, blob_size, EVA_SIZE, (Bytef *)blob, (Bytef *)eva);
salis_inflate_end(&strm);
// Render image
for (size_t i = 0; i < px_count; i++) {
out[i] = 0;
for (size_t j = 0; j < px_res; j++) {
size_t in_coord = left + i * px_res + j;
#if defined(MVEC_LOOP)
in_coord %= MVEC_SIZE;
#endif
out[i] += eva[in_coord];
}
}
sqlite3_free(eva);
// Transform rendered image into textual representation
// A comma-separated list of hexadecimal integers
char *csv = sqlite3_malloc(px_count * 17 + 1);
char *ptr = csv;
for (size_t i = 0; i < px_count; i++) {
ptr += sprintf(ptr, "%lx ", out[i]);
}
*(--ptr) = '\0';
sqlite3_free(out);
sqlite3_result_text(context, csv, -1, sqlite3_free);
}
int sqlite3_render_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) {
assert(db);
assert(pzErrMsg);
assert(pApi);
(void)pzErrMsg;
SQLITE_EXTENSION_INIT2(pApi);
return sqlite3_create_function(db, "eva_render", 4, SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS | SQLITE_UTF8, NULL, eva_render, NULL, NULL);
}
|