+#ifdef HAVE_SQLITE3_H
+/*
+static int sql_select_tile_dump_cb (void *data, int cols, char **fields, char **col_names )
+{
+ g_warning ( "Found %d columns", cols );
+ int i;
+ for ( i = 0; i < cols; i++ ) {
+ g_warning ( "SQL processing %s = %s", col_names[i], fields[i] );
+ }
+ return 0;
+}
+*/
+
+/**
+ *
+ */
+static GdkPixbuf *get_pixbuf_sql_exec ( sqlite3 *sql, gint xx, gint yy, gint zoom )
+{
+ GdkPixbuf *pixbuf = NULL;
+
+ // MBTiles stored internally with the flipping y thingy (i.e. TMS scheme).
+ gint flip_y = (gint) pow(2, zoom)-1 - yy;
+ gchar *statement = g_strdup_printf ( "SELECT tile_data FROM tiles WHERE zoom_level=%d AND tile_column=%d AND tile_row=%d;", zoom, xx, flip_y );
+
+ gboolean finished = FALSE;
+
+ sqlite3_stmt *sql_stmt = NULL;
+ int ans = sqlite3_prepare_v2 ( sql, statement, -1, &sql_stmt, NULL );
+ if ( ans != SQLITE_OK ) {
+ g_warning ( "%s: %s - %d", __FUNCTION__, "prepare failure", ans );
+ finished = TRUE;
+ }
+
+ while ( !finished ) {
+ ans = sqlite3_step ( sql_stmt );
+ switch (ans) {
+ case SQLITE_ROW: {
+ // Get tile_data blob
+ int count = sqlite3_column_count(sql_stmt);
+ if ( count != 1 ) {
+ g_warning ( "%s: %s - %d", __FUNCTION__, "count not one", count );
+ finished = TRUE;
+ }
+ else {
+ const void *data = sqlite3_column_blob ( sql_stmt, 0 );
+ int bytes = sqlite3_column_bytes ( sql_stmt, 0 );
+ if ( bytes < 1 ) {
+ g_warning ( "%s: %s (%d)", __FUNCTION__, "not enough bytes", bytes );
+ finished = TRUE;
+ }
+ else {
+ // Convert these blob bytes into a pixbuf via these streaming operations
+ GInputStream *stream = g_memory_input_stream_new_from_data ( data, bytes, NULL );
+ GError *error = NULL;
+ pixbuf = gdk_pixbuf_new_from_stream ( stream, NULL, &error );
+ if (error || (!pixbuf)) {
+ g_warning ( "%s: %s", __FUNCTION__, error->message );
+ g_error_free ( error );
+ }
+ g_input_stream_close ( stream, NULL, NULL );
+ }
+ }
+ break;
+ }
+ default:
+ // e.g. SQLITE_DONE | SQLITE_ERROR | SQLITE_MISUSE | etc...
+ // Finished normally
+ // and give up on any errors
+ if ( ans != SQLITE_DONE )
+ g_warning ( "%s: %s - %d", __FUNCTION__, "step issue", ans );
+ finished = TRUE;
+ break;
+ }
+ }
+ ans = sqlite3_finalize ( sql_stmt );
+
+ g_free ( statement );
+
+ return pixbuf;
+}
+#endif
+
+static GdkPixbuf *get_mbtiles_pixbuf ( VikMapsLayer *vml, gint xx, gint yy, gint zoom )
+{
+ GdkPixbuf *pixbuf = NULL;
+
+#ifdef HAVE_SQLITE3_H
+ if ( vml->mbtiles ) {
+ /*
+ gchar *statement = g_strdup_printf ( "SELECT name FROM sqlite_master WHERE type='table';" );
+ char *errMsg = NULL;
+ int ans = sqlite3_exec ( vml->mbtiles, statement, sql_select_tile_dump_cb, pixbuf, &errMsg );
+ if ( ans != SQLITE_OK ) {
+ // Only to console for information purposes only
+ g_warning ( "SQL problem: %d for %s - error: %s", ans, statement, errMsg );
+ sqlite3_free( errMsg );
+ }
+ g_free ( statement );
+ */
+
+ // Reading BLOBS is a bit more involved and so can't use the simpler sqlite3_exec ()
+ // Hence this specific function
+ pixbuf = get_pixbuf_sql_exec ( vml->mbtiles, xx, yy, zoom );
+ }
+#endif
+
+ return pixbuf;
+}
+
+static GdkPixbuf *get_pixbuf_from_metatile ( VikMapsLayer *vml, gint xx, gint yy, gint zz )
+{
+ const int tile_max = METATILE_MAX_SIZE;
+ char err_msg[PATH_MAX];
+ char *buf;
+ int len;
+ int compressed;
+
+ buf = malloc(tile_max);
+ if (!buf) {