diff options
Diffstat (limited to 'core/render.c')
| -rw-r--r-- | core/render.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/core/render.c b/core/render.c new file mode 100644 index 0000000..f9da65d --- /dev/null +++ b/core/render.c @@ -0,0 +1,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); +} |
