void dt_selection_select_range(dt_selection_t *selection, uint32_t imgid) { gchar *fullq = NULL; sqlite3_stmt *stmt; if (!selection->collection || selection->last_single_id == -1) return; /* get start and end rows for range selection */ int rc=0; uint32_t sr=-1,er=-1; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), dt_collection_get_query(selection->collection), -1, &stmt, NULL); while(sqlite3_step(stmt)==SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); if (id == selection->last_single_id) sr = rc; if (id == imgid) er = rc; if (sr != -1 && er != -1 ) break; rc++; } sqlite3_finalize(stmt); /* selece the images in range from start to end */ uint32_t old_flags = dt_collection_get_query_flags(selection->collection); /* use the limit to select range of images */ dt_collection_set_query_flags(selection->collection, (old_flags |COLLECTION_QUERY_USE_LIMIT)); dt_collection_update(selection->collection); fullq = dt_util_dstrcat(fullq, "%s", "insert or ignore into selected_images "); fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), fullq, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, MIN(sr,er)); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, (MAX(sr,er)-MIN(sr,er))+1); sqlite3_step(stmt); /* reset filter */ dt_collection_set_query_flags(selection->collection, old_flags); dt_collection_update(selection->collection); selection->last_single_id = -1; }
void dt_selection_select_range(dt_selection_t *selection, uint32_t imgid) { gchar *fullq = NULL; if(!selection->collection || selection->last_single_id == -1) return; /* get start and end rows for range selection */ sqlite3_stmt *stmt; int rc = 0; uint32_t sr = -1, er = -1; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), dt_collection_get_query_no_group(selection->collection), -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { const int id = sqlite3_column_int(stmt, 0); if(id == selection->last_single_id) sr = rc; if(id == imgid) er = rc; if(sr != -1 && er != -1) break; rc++; } sqlite3_finalize(stmt); /* select the images in range from start to end */ const uint32_t old_flags = dt_collection_get_query_flags(selection->collection); /* use the limit to select range of images */ dt_collection_set_query_flags(selection->collection, (old_flags | COLLECTION_QUERY_USE_LIMIT)); dt_collection_update(selection->collection); fullq = dt_util_dstrcat(fullq, "%s", "INSERT OR IGNORE INTO main.selected_images "); fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query_no_group(selection->collection)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), fullq, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, MIN(sr, er)); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, (MAX(sr, er) - MIN(sr, er)) + 1); sqlite3_step(stmt); sqlite3_finalize(stmt); /* reset filter */ dt_collection_set_query_flags(selection->collection, old_flags); dt_collection_update(selection->collection); // The logic above doesn't handle groups, so explicitly select the beginning and end to make sure those are selected properly dt_selection_select(selection, selection->last_single_id); dt_selection_select(selection, imgid); g_free(fullq); }
void _selection_update_collection(gpointer instance, gpointer user_data) { dt_selection_t *selection = (dt_selection_t *)user_data; /* free previous collection copy if any */ if(selection->collection) dt_collection_free(selection->collection); /* create a new fresh copy of darktable collection */ selection->collection = dt_collection_new(darktable.collection); /* remove limit part of local collection */ dt_collection_set_query_flags(selection->collection, (dt_collection_get_query_flags(selection->collection) & (~(COLLECTION_QUERY_USE_LIMIT)))); dt_collection_update(selection->collection); }
void dt_similarity_match_image(uint32_t imgid,dt_similarity_t *data) { sqlite3_stmt *stmt; gboolean all_ok_for_match = TRUE; dt_similarity_histogram_t orginal_histogram,test_histogram; dt_similarity_lightmap_t orginal_lightmap,test_lightmap; /* create temporary mem table for matches */ DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "create temporary table if not exists similar_images (id integer,score real)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from similar_images", NULL, NULL, NULL); /* * get the histogram and lightmap data for image to match against */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select histogram,lightmap from images where id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); if (sqlite3_step(stmt) == SQLITE_ROW) { /* get the histogram data */ uint32_t size = sqlite3_column_bytes(stmt,0); if (size!=sizeof(dt_similarity_histogram_t)) { all_ok_for_match = FALSE; dt_control_log(_("this image has not been indexed yet.")); } else memcpy(&orginal_histogram, sqlite3_column_blob(stmt, 0), sizeof(dt_similarity_histogram_t)); /* get the lightmap data */ size = sqlite3_column_bytes(stmt,1); if (size!=sizeof(dt_similarity_lightmap_t)) { all_ok_for_match = FALSE; dt_control_log(_("this image has not been indexed yet.")); } else memcpy(&orginal_lightmap, sqlite3_column_blob(stmt, 1), sizeof(dt_similarity_lightmap_t)); } else { all_ok_for_match = FALSE; dt_control_log(_("this image has not been indexed yet.")); } sqlite3_reset(stmt); sqlite3_clear_bindings(stmt); /* * if all ok lets begin matching */ if (all_ok_for_match) { char query[4096]={0}; /* add target image with 100.0 in score into result to ensure it always shown in top */ sprintf(query,"insert into similar_images(id,score) values(%d,%f)",imgid,100.0); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); /* set an extended collection query for viewing the result of match */ dt_collection_set_extended_where(darktable.collection, ", similar_images where images.id = similar_images.id order by similar_images.score desc"); dt_collection_set_query_flags( darktable.collection, dt_collection_get_query_flags(darktable.collection) | COLLECTION_QUERY_USE_ONLY_WHERE_EXT); dt_collection_update(darktable.collection); dt_control_signal_raise(darktable.signals, DT_SIGNAL_COLLECTION_CHANGED); /* loop thru images and generate score table */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id,histogram,lightmap from images", -1, &stmt, NULL); while (sqlite3_step(stmt) == SQLITE_ROW) { float score_histogram=0, score_lightmap=0, score_colormap=0; /* verify size of histogram and lightmap blob of test image */ if ( (sqlite3_column_bytes(stmt,1) == sizeof(dt_similarity_histogram_t)) && (sqlite3_column_bytes(stmt,2) == sizeof(dt_similarity_lightmap_t)) ) { /* * Get the histogram blob and calculate the similarity score */ memcpy(&test_histogram, sqlite3_column_blob(stmt, 1), sizeof(dt_similarity_histogram_t)); score_histogram = _similarity_match_histogram_rgb(data, &orginal_histogram, &test_histogram); /* * Get the lightmap blob and calculate the similarity score * 1.08 is a tuned constant that works well with threshold */ memcpy(&test_lightmap, sqlite3_column_blob(stmt, 2), sizeof(dt_similarity_lightmap_t)); score_lightmap = _similarity_match_lightmap(data, &orginal_lightmap, &test_lightmap); /* * then calculate the colormap similarity score */ score_colormap = _similarity_match_colormap(data, &orginal_lightmap, &test_lightmap); /* * calculate the similarity score */ float score = (pow(score_histogram, data->histogram_weight) * pow(score_lightmap, data->lightmap_weight) * pow(score_colormap, data->redmap_weight)); // fprintf(stderr,"score: %f, histo: %f, light: %f, color: %f\n",score,score_histogram,score_lightmap,score_colormap); /* * If current images scored, lets add it to similar_images table */ if(score >= 0.92) { sprintf(query,"insert into similar_images(id,score) values(%d,%f)",sqlite3_column_int(stmt, 0),score); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); /* lets redraw the view */ dt_control_queue_redraw_center(); } } else fprintf(stderr,"Image has inconsisten similarity matching data..\n"); } } sqlite3_finalize (stmt); }
void dt_collection_update_query(const dt_collection_t *collection) { char query[1024], confname[200]; gchar *complete_query = NULL; const int _n_r = dt_conf_get_int("plugins/lighttable/collect/num_rules"); const int num_rules = CLAMP(_n_r, 1, 10); char *conj[] = {"and", "or", "and not"}; complete_query = dt_util_dstrcat(complete_query, "("); for(int i=0; i<num_rules; i++) { snprintf(confname, sizeof(confname), "plugins/lighttable/collect/item%1d", i); const int property = dt_conf_get_int(confname); snprintf(confname, sizeof(confname), "plugins/lighttable/collect/string%1d", i); gchar *text = dt_conf_get_string(confname); if(!text) break; snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", i); const int mode = dt_conf_get_int(confname); gchar *escaped_text = dt_util_str_replace(text, "'", "''"); get_query_string(property, escaped_text, query, sizeof(query)); if(i > 0) complete_query = dt_util_dstrcat(complete_query, " %s %s", conj[mode], query); else complete_query = dt_util_dstrcat(complete_query, "%s", query); g_free(escaped_text); g_free(text); } complete_query = dt_util_dstrcat(complete_query, ")"); // printf("complete query: `%s'\n", complete_query); /* set the extended where and the use of it in the query */ dt_collection_set_extended_where (collection, complete_query); dt_collection_set_query_flags (collection, (dt_collection_get_query_flags (collection) | COLLECTION_QUERY_USE_WHERE_EXT)); /* remove film id from default filter */ dt_collection_set_filter_flags (collection, (dt_collection_get_filter_flags (collection) & ~COLLECTION_FILTER_FILM_ID)); /* update query and at last the visual */ dt_collection_update (collection); /* free string */ g_free(complete_query); // remove from selected images where not in this query. sqlite3_stmt *stmt = NULL; const gchar *cquery = dt_collection_get_query(collection); complete_query = NULL; if(cquery && cquery[0] != '\0') { complete_query = dt_util_dstrcat(complete_query, "delete from selected_images where imgid not in (%s)", cquery); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), complete_query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, 0); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, -1); sqlite3_step(stmt); sqlite3_finalize(stmt); /* free allocated strings */ g_free(complete_query); } /* raise signal of collection change, only if this is an original */ if (!collection->clone) dt_control_signal_raise(darktable.signals, DT_SIGNAL_COLLECTION_CHANGED); }