static void _dt_style_update_from_image(int id, int imgid, GList *filter, GList *update) { if (update && imgid!=-1) { GList *list=filter; GList *upd=update; char query[4096] = {0}; char tmp[500]; char *fields[] = {"op_params", "module", "enabled", "blendop_params", "blendop_version", "multi_priority", "multi_name", 0}; do { query[0] = '\0'; // included and update set, we then need to update the corresponding style item if ((glong)upd->data!=-1 && (glong)list->data!=-1) { strcpy(query, "update style_items set "); for (int k=0; fields[k]; k++) { if (k!=0) strcat(query, ","); sprintf(tmp, "%s=(select %s from history where imgid=%d and num=%ld)", fields[k], fields[k], imgid, (glong)upd->data); strcat(query, tmp); } sprintf(tmp, " where styleid=%d and style_items.num=%ld", id, (glong)list->data); strcat(query, tmp); } // update only, so we want to insert the new style item else if ((glong)upd->data!=-1) sprintf(query,"insert into style_items (styleid,num,module,operation,op_params,enabled,blendop_params,blendop_version,multi_priority,multi_name) select %d,(select num+1 from style_items where styleid=%d order by num desc limit 1),module,operation,op_params,enabled,blendop_params,blendop_version,multi_priority,multi_name from history where imgid=%d and num=%ld",id,id,imgid,(glong)upd->data); if (*query) DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); list=g_list_next(list); upd=g_list_next(upd); } while (list); } }
void dt_colorlabels_toggle_label_selection (const int color) { sqlite3_stmt *stmt; // store away all previously unlabeled images in selection: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into memory.color_labels_temp select a.imgid from selected_images as a join color_labels as b on a.imgid = b.imgid where b.color = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, color); sqlite3_step(stmt); sqlite3_finalize(stmt); // delete all currently colored image labels in selection DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from color_labels where imgid in (select imgid from selected_images) and color=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, color); sqlite3_step(stmt); sqlite3_finalize(stmt); // label all previously unlabeled images: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into color_labels select imgid, ?1 from selected_images where imgid not in (select imgid from memory.color_labels_temp)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, color); sqlite3_step(stmt); sqlite3_finalize(stmt); // clean up DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from memory.color_labels_temp", NULL, NULL, NULL); }
void dt_ratings_apply_to_selection(int rating) { uint32_t count = dt_collection_get_selected_count(darktable.collection); if(count) { if(rating == 6) dt_control_log(ngettext("rejecting %d image", "rejecting %d images", count), count); else dt_control_log(ngettext("applying rating %d to %d image", "applying rating %d to %d images", count), rating, count); #if 0 // not updating cache gchar query[1024]= {0}; g_snprintf(query,sizeof(query), "update images set flags=(images.flags & ~7) | (7 & %d) where id in (select imgid from selected_images)", rating ); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); #endif /* for each selected image update rating */ sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images", -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { dt_ratings_apply_to_image(sqlite3_column_int(stmt, 0), rating); } sqlite3_finalize(stmt); /* redraw view */ /* dt_control_queue_redraw_center() */ /* needs to be called in the caller function */ } else dt_control_log(_("no images selected to apply rating")); }
void dt_ratings_apply_to_selection (int rating) { uint32_t count = dt_collection_get_selected_count(darktable.collection); if (count) { dt_control_log(ngettext("applying rating %d to %d image", "applying rating %d to %d images", count), rating, count); #if 0 // not updating cache gchar query[1024]={0}; g_snprintf(query,1024, "update images set flags=(images.flags & ~7) | (7 & %d) where id in (select imgid from selected_images)", rating ); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); #endif /* for each selected image update rating */ sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images", -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { const dt_image_t *cimg = dt_image_cache_read_get(darktable.image_cache, sqlite3_column_int(stmt, 0)); dt_image_t *image = dt_image_cache_write_get(darktable.image_cache, cimg); image->flags = (image->flags & ~0x7) | (0x7 & rating); // synch through: dt_image_cache_write_release(darktable.image_cache, image, DT_IMAGE_CACHE_SAFE); dt_image_cache_read_release(darktable.image_cache, image); } sqlite3_finalize(stmt); /* redraw view */ dt_control_queue_redraw_center(); } else dt_control_log(_("no images selected to apply rating")); }
void init_presets(dt_iop_module_so_t *self) { dt_iop_lowlight_params_t p; DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "BEGIN", NULL, NULL, NULL); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 1.000000; p.transition_y[1] = 1.000000; p.transition_y[2] = 1.000000; p.transition_y[3] = 1.000000; p.transition_y[4] = 1.000000; p.transition_y[5] = 1.000000; p.blueness = 0.0f; dt_gui_presets_add_generic(_("daylight"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.600000; p.transition_y[1] = 0.800000; p.transition_y[2] = 0.950000; p.transition_y[3] = 0.980000; p.transition_y[4] = 1.000000; p.transition_y[5] = 1.000000; p.blueness = 30.0f; dt_gui_presets_add_generic(_("indoor bright"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.300000; p.transition_y[1] = 0.500000; p.transition_y[2] = 0.700000; p.transition_y[3] = 0.850000; p.transition_y[4] = 0.970000; p.transition_y[5] = 1.000000; p.blueness = 30.0f; dt_gui_presets_add_generic(_("indoor dim"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.050000; p.transition_y[1] = 0.200000; p.transition_y[2] = 0.400000; p.transition_y[3] = 0.700000; p.transition_y[4] = 0.920000; p.transition_y[5] = 1.000000; p.blueness = 40.0f; dt_gui_presets_add_generic(_("indoor dark"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.070000; p.transition_y[1] = 0.100000; p.transition_y[2] = 0.180000; p.transition_y[3] = 0.350000; p.transition_y[4] = 0.750000; p.transition_y[5] = 1.000000; p.blueness = 50.0f; dt_gui_presets_add_generic(_("twilight"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.000000; p.transition_y[1] = 0.450000; p.transition_y[2] = 0.750000; p.transition_y[3] = 0.930000; p.transition_y[4] = 0.990000; p.transition_y[5] = 1.000000; p.blueness = 30.0f; dt_gui_presets_add_generic(_("night street lit"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.000000; p.transition_y[1] = 0.150000; p.transition_y[2] = 0.350000; p.transition_y[3] = 0.800000; p.transition_y[4] = 0.970000; p.transition_y[5] = 1.000000; p.blueness = 30.0f; dt_gui_presets_add_generic(_("night street"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.150000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.000000; p.transition_y[1] = 0.020000; p.transition_y[2] = 0.050000; p.transition_y[3] = 0.200000; p.transition_y[4] = 0.550000; p.transition_y[5] = 1.000000; p.blueness = 40.0f; dt_gui_presets_add_generic(_("night street dark"), self->op, self->version(), &p, sizeof(p), 1); p.transition_x[0] = 0.000000; p.transition_x[1] = 0.200000; p.transition_x[2] = 0.400000; p.transition_x[3] = 0.600000; p.transition_x[4] = 0.800000; p.transition_x[5] = 1.000000; p.transition_y[0] = 0.000000; p.transition_y[1] = 0.000000; p.transition_y[2] = 0.000000; p.transition_y[3] = 0.000000; p.transition_y[4] = 0.000000; p.transition_y[5] = 0.000000; p.blueness = 50.0f; dt_gui_presets_add_generic(_("night"), self->op, self->version(), &p, sizeof(p), 1); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "COMMIT", NULL, NULL, NULL); }
int32_t dt_control_delete_images_job_run(dt_job_t *job) { long int imgid = -1; dt_control_image_enumerator_t *t1 = (dt_control_image_enumerator_t *)job->param; GList *t = t1->index; int total = g_list_length(t); char message[512]= {0}; double fraction=0; snprintf(message, 512, ngettext ("deleting %d image", "deleting %d images", total), total ); const guint *jid = dt_control_backgroundjobs_create(darktable.control, 0, message); sqlite3_stmt *stmt; char query[1024]; sprintf(query, "update images set flags = (flags | %d) where id in (select imgid from selected_images)",DT_IMAGE_REMOVE); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); dt_collection_update(darktable.collection); // We need a list of files to regenerate .xmp files if there are duplicates GList *list = NULL; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select distinct folder || '/' || filename from images, film_rolls where images.film_id = film_rolls.id and images.id in (select imgid from selected_images)", -1, &stmt, NULL); if(sqlite3_step(stmt) == SQLITE_ROW) { list = g_list_append(list, g_strdup((const gchar *)sqlite3_column_text(stmt, 0))); } sqlite3_finalize(stmt); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select count(id) from images where filename in (select filename from images where id = ?1) and film_id in (select film_id from images where id = ?1)", -1, &stmt, NULL); while(t) { imgid = (long int)t->data; char filename[DT_MAX_PATH_LEN]; dt_image_full_path(imgid, filename, DT_MAX_PATH_LEN); int duplicates = 0; DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); if(sqlite3_step(stmt) == SQLITE_ROW) duplicates = sqlite3_column_int(stmt, 0); sqlite3_reset(stmt); sqlite3_clear_bindings(stmt); // remove from disk: if(duplicates == 1) // don't remove the actual data if there are (other) duplicates using it (void)g_unlink(filename); dt_image_path_append_version(imgid, filename, DT_MAX_PATH_LEN); char *c = filename + strlen(filename); sprintf(c, ".xmp"); (void)g_unlink(filename); dt_image_remove(imgid); t = g_list_delete_link(t, t); fraction=1.0/total; dt_control_backgroundjobs_progress(darktable.control, jid, fraction); } sqlite3_finalize(stmt); char *imgname; while(list) { imgname = (char *)list->data; dt_image_synch_all_xmp(imgname); list = g_list_delete_link(list, list); } g_list_free(list); dt_control_backgroundjobs_destroy(darktable.control, jid); dt_film_remove_empty(); dt_control_queue_redraw_center(); return 0; }
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); }
static void auto_apply_presets(dt_develop_t *dev) { const int imgid = dev->image_storage.id; if(imgid <= 0) return; int run = 0; const dt_image_t *cimg = dt_image_cache_read_get(darktable.image_cache, imgid); if(!(cimg->flags & DT_IMAGE_AUTO_PRESETS_APPLIED)) run = 1; // flag was already set? only apply presets once in the lifetime of a history stack. // (the flag will be cleared when removing it) if(!run || cimg->id <= 0) { dt_image_cache_read_release(darktable.image_cache, cimg); return; } // keep locked, we want to be alone messing with the history of the poor fellow: dt_image_t *image = dt_image_cache_write_get(darktable.image_cache, cimg); // be extra sure that we don't mess up history in separate threads: dt_pthread_mutex_lock(&darktable.db_insert); // cleanup DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from memory.history", NULL, NULL, NULL); const char *preset_table[2] = {"presets", "legacy_presets"}; const int legacy = (image->flags & DT_IMAGE_NO_LEGACY_PRESETS) ? 0 : 1; char query[1024]; snprintf(query, 1024, "insert into memory.history select ?1, 0, op_version, operation, op_params, enabled, blendop_params, blendop_version, multi_priority, multi_name " "from %s where autoapply=1 and " "?2 like model and ?3 like maker and ?4 like lens and " "?5 between iso_min and iso_max and " "?6 between exposure_min and exposure_max and " "?7 between aperture_min and aperture_max and " "?8 between focal_length_min and focal_length_max and " "(isldr = 0 or isldr=?9) order by writeprotect desc, " "length(model), length(maker), length(lens)", preset_table[legacy]); // query for all modules at once: sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, cimg->exif_model, strlen(cimg->exif_model), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, cimg->exif_maker, strlen(cimg->exif_maker), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 4, cimg->exif_lens, strlen(cimg->exif_lens), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 5, fmaxf(0.0f, fminf(1000000, cimg->exif_iso))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 6, fmaxf(0.0f, fminf(1000000, cimg->exif_exposure))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 7, fmaxf(0.0f, fminf(1000000, cimg->exif_aperture))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 8, fmaxf(0.0f, fminf(1000000, cimg->exif_focal_length))); // 0: dontcare, 1: ldr, 2: raw DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 9, 2-dt_image_is_ldr(cimg)); if(sqlite3_step(stmt) == SQLITE_DONE) { sqlite3_finalize(stmt); int cnt = 0; // count what we found: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select count(*) from memory.history", -1, &stmt, NULL); if(sqlite3_step(stmt) == SQLITE_ROW) { // if there is anything.. cnt = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); // fprintf(stderr, "[auto_apply_presets] imageid %d found %d matching presets (legacy %d)\n", imgid, cnt, legacy); // advance the current history by that amount: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "update history set num=num+?1 where imgid=?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, cnt); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, imgid); if(sqlite3_step(stmt) == SQLITE_DONE) { // and finally prepend the rest with increasing numbers (starting at 0) sqlite3_finalize(stmt); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into history select imgid, rowid-1, module, operation, op_params, enabled, " "blendop_params, blendop_version, multi_priority, multi_name from memory.history", -1, &stmt, NULL); sqlite3_step(stmt); } } } sqlite3_finalize(stmt); // first time we are loading the image, try to import lightroom .xmp if any if (dev->image_loading) dt_lightroom_import(dev->image_storage.id, dev, TRUE); image->flags |= DT_IMAGE_AUTO_PRESETS_APPLIED | DT_IMAGE_NO_LEGACY_PRESETS; dt_pthread_mutex_unlock(&darktable.db_insert); // make sure these end up in the image_cache + xmp (sync through here if we set the flag) dt_image_cache_write_release(darktable.image_cache, image, DT_IMAGE_CACHE_SAFE); dt_image_cache_read_release(darktable.image_cache, cimg); }
void dt_selection_select_single(dt_selection_t *selection, uint32_t imgid) { selection->last_single_id = imgid; DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM main.selected_images", NULL, NULL, NULL); dt_selection_select(selection, imgid); }
dt_database_t *dt_database_init(char *alternative) { /* migrate default database location to new default */ _database_migrate_to_xdg_structure(); /* delete old mipmaps files */ _database_delete_mipmaps_files(); /* lets construct the db filename */ gchar * dbname = NULL; gchar dbfilename[DT_MAX_PATH_LEN] = {0}; gchar datadir[DT_MAX_PATH_LEN] = {0}; dt_loc_get_user_config_dir(datadir, DT_MAX_PATH_LEN); if ( alternative == NULL ) { dbname = dt_conf_get_string ("database"); if(!dbname) snprintf(dbfilename, DT_MAX_PATH_LEN, "%s/library.db", datadir); else if(dbname[0] != '/') snprintf(dbfilename, DT_MAX_PATH_LEN, "%s/%s", datadir, dbname); else snprintf(dbfilename, DT_MAX_PATH_LEN, "%s", dbname); } else { snprintf(dbfilename, DT_MAX_PATH_LEN, "%s", alternative); GFile *galternative = g_file_new_for_path(alternative); dbname = g_file_get_basename (galternative); g_object_unref(galternative); } /* create database */ dt_database_t *db = (dt_database_t *)g_malloc(sizeof(dt_database_t)); memset(db,0,sizeof(dt_database_t)); db->dbfilename = g_strdup(dbfilename); db->is_new_database = FALSE; db->lock_acquired = FALSE; /* having more than one instance of darktable using the same database is a bad idea */ /* try to get a lock for the database */ #ifdef __WIN32__ db->lock_acquired = TRUE; #else mode_t old_mode; int fd, lock_tries = 0; if(!strcmp(dbfilename, ":memory:")) { db->lock_acquired = TRUE; } else { db->lockfile = g_strconcat(dbfilename, ".lock", NULL); lock_again: lock_tries++; old_mode = umask(0); fd = open(db->lockfile, O_RDWR | O_CREAT | O_EXCL, 0666); umask(old_mode); if(fd >= 0) // the lockfile was successfully created - write our PID into it { gchar *pid = g_strdup_printf("%d", getpid()); if(write(fd, pid, strlen(pid)+1) > -1) db->lock_acquired = TRUE; close(fd); } else // the lockfile already exists - see if it's a stale one left over from a crashed instance { char buf[64]; memset(buf, 0, sizeof(buf)); fd = open(db->lockfile, O_RDWR | O_CREAT, 0666); if(fd >= 0) { if(read(fd, buf, sizeof(buf) - 1) > -1) { int other_pid = atoi(buf); if((kill(other_pid, 0) == -1) && errno == ESRCH) { // the other process seems to no longer exist. unlink the .lock file and try again unlink(db->lockfile); if(lock_tries < 5) goto lock_again; } } close(fd); } } } #endif if(!db->lock_acquired) { fprintf(stderr, "[init] database is locked, probably another process is already using it\n"); g_free(dbname); return db; } /* test if databasefile is available */ if(!g_file_test(dbfilename, G_FILE_TEST_IS_REGULAR)) db->is_new_database = TRUE; /* opening / creating database */ if(sqlite3_open(db->dbfilename, &db->handle)) { fprintf(stderr, "[init] could not find database "); if(dbname) fprintf(stderr, "`%s'!\n", dbname); else fprintf(stderr, "\n"); fprintf(stderr, "[init] maybe your %s/darktablerc is corrupt?\n",datadir); dt_loc_get_datadir(dbfilename, 512); fprintf(stderr, "[init] try `cp %s/darktablerc %s/darktablerc'\n", dbfilename,datadir); sqlite3_close(db->handle); g_free(dbname); g_free(db->lockfile); g_free(db); return NULL; } /* attach a memory database to db connection for use with temporary tables used during instance life time, which is discarded on exit. */ sqlite3_exec(db->handle, "attach database ':memory:' as memory",NULL,NULL,NULL); sqlite3_exec(db->handle, "PRAGMA synchronous = OFF", NULL, NULL, NULL); sqlite3_exec(db->handle, "PRAGMA journal_mode = MEMORY", NULL, NULL, NULL); sqlite3_exec(db->handle, "PRAGMA page_size = 32768", NULL, NULL, NULL); /* now that we got a functional database that is locked for us we can make sure that the schema is set up */ // does the db contain the new 'db_info' table? sqlite3_stmt *stmt; int rc = sqlite3_prepare_v2(db->handle, "select value from db_info where key = 'version'", -1, &stmt, NULL); if(rc == SQLITE_OK && sqlite3_step(stmt) == SQLITE_ROW) { // compare the version of the db with what is current for this executable const int db_version = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); if(db_version < CURRENT_DATABASE_VERSION) { // older: upgrade if(!_upgrade_schema(db, db_version)) { // we couldn't upgrade the db for some reason. bail out. fprintf(stderr, "[init] database `%s' couldn't be upgraded from version %d to %d. aborting\n", dbname, db_version, CURRENT_DATABASE_VERSION); dt_database_destroy(db); db = NULL; goto error; } } else if(db_version > CURRENT_DATABASE_VERSION) { // newer: bail out. it's better than what we did before: delete everything fprintf(stderr, "[init] database version of `%s' is too new for this build of darktable. aborting\n", dbname); dt_database_destroy(db); db = NULL; goto error; } // else: the current version, do nothing } else { // does it contain the legacy 'settings' table? sqlite3_finalize(stmt); rc = sqlite3_prepare_v2(db->handle, "select settings from settings", -1, &stmt, NULL); if(rc == SQLITE_OK && sqlite3_step(stmt) == SQLITE_ROW) { // the old blob had the version as an int in the first place const void *set = sqlite3_column_blob(stmt, 0); const int db_version = *(int*)set; sqlite3_finalize(stmt); if(!_migrate_schema(db, db_version)) // bring the legacy layout to the first one known to our upgrade path ... { // we couldn't migrate the db for some reason. bail out. fprintf(stderr, "[init] database `%s' couldn't be migrated from the legacy version %d. aborting\n", dbname, db_version); dt_database_destroy(db); db = NULL; goto error; } if(!_upgrade_schema(db, 1)) // ... and upgrade it { // we couldn't upgrade the db for some reason. bail out. fprintf(stderr, "[init] database `%s' couldn't be upgraded from version 1 to %d. aborting\n", dbname, CURRENT_DATABASE_VERSION); dt_database_destroy(db); db = NULL; goto error; } } else { sqlite3_finalize(stmt); _create_schema(db); // a brand new db it seems } } // create the in-memory tables // temporary stuff for some ops, need this for some reason with newer sqlite3: DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.color_labels_temp (imgid INTEGER PRIMARY KEY)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.collected_images (rowid INTEGER PRIMARY KEY AUTOINCREMENT, imgid INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.tmp_selection (imgid INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.tagq (tmpid INTEGER PRIMARY KEY, id INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.taglist " "(tmpid INTEGER PRIMARY KEY, id INTEGER UNIQUE ON CONFLICT REPLACE, " "count INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE memory.history (imgid INTEGER, num INTEGER, module INTEGER, " "operation VARCHAR(256) UNIQUE ON CONFLICT REPLACE, op_params BLOB, enabled INTEGER, " "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE MEMORY.style_items (styleid INTEGER, num INTEGER, module INTEGER, " "operation VARCHAR(256), op_params BLOB, enabled INTEGER, " "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))", NULL, NULL, NULL); // create a table legacy_presets with all the presets from pre-auto-apply-cleanup darktable. dt_legacy_presets_create(db); // drop table settings -- we don't want old versions of dt to drop our tables sqlite3_exec(db->handle, "drop table settings", NULL, NULL, NULL); error: g_free(dbname); return db; }
/* create the current database schema and set the version in db_info accordingly */ static void _create_schema(dt_database_t *db) { sqlite3_stmt *stmt; ////////////////////////////// db_info DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE db_info (key VARCHAR PRIMARY KEY, value VARCHAR)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_PREPARE_V2(db->handle, "INSERT OR REPLACE INTO db_info (key, value) VALUES ('version', ?1)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, CURRENT_DATABASE_VERSION); sqlite3_step(stmt); sqlite3_finalize(stmt); ////////////////////////////// film_rolls DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE film_rolls " "(id INTEGER PRIMARY KEY, datetime_accessed CHAR(20), " // "folder VARCHAR(1024), external_drive VARCHAR(1024))", // FIXME: make sure to bump CURRENT_DATABASE_VERSION and add a case to _upgrade_schema_step when adding this! "folder VARCHAR(1024))", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX film_rolls_folder_index ON film_rolls (folder)", NULL, NULL, NULL); ////////////////////////////// images DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE images (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, " "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, " "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, " "focus_distance REAL, datetime_taken CHAR(20), flags INTEGER, " "output_width INTEGER, output_height INTEGER, crop REAL, " "raw_parameters INTEGER, raw_denoise_threshold REAL, " "raw_auto_bright_threshold REAL, raw_black REAL, raw_maximum REAL, " "caption VARCHAR, description VARCHAR, license VARCHAR, sha1sum CHAR(40), " "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, " "latitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, max_version INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX images_group_id_index ON images (group_id)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX images_film_id_index ON images (film_id)", NULL, NULL, NULL); ////////////////////////////// selected_images DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE selected_images (imgid INTEGER PRIMARY KEY)", NULL, NULL, NULL); ////////////////////////////// history DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE history (imgid INTEGER, num INTEGER, module INTEGER, " "operation VARCHAR(256), op_params BLOB, enabled INTEGER, " "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX history_imgid_index ON history (imgid)", NULL, NULL, NULL); ////////////////////////////// mask DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE mask (imgid INTEGER, formid INTEGER, form INTEGER, name VARCHAR(256), " "version INTEGER, points BLOB, points_count INTEGER, source BLOB)", NULL, NULL, NULL); ////////////////////////////// tags DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE tags (id INTEGER PRIMARY KEY, name VARCHAR, icon BLOB, " "description VARCHAR, flags INTEGER)", NULL, NULL, NULL); ////////////////////////////// tagxtag DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE tagxtag (id1 INTEGER, id2 INTEGER, count INTEGER, " "PRIMARY KEY (id1, id2))", NULL, NULL, NULL); ////////////////////////////// tagged_images DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE tagged_images (imgid INTEGER, tagid INTEGER, " "PRIMARY KEY (imgid, tagid))", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX tagged_images_tagid_index ON tagged_images (tagid)", NULL, NULL, NULL); ////////////////////////////// styles DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE styles (id INTEGER, name VARCHAR, description VARCHAR)", NULL, NULL, NULL); ////////////////////////////// style_items DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE style_items (styleid INTEGER, num INTEGER, module INTEGER, " "operation VARCHAR(256), op_params BLOB, enabled INTEGER, " "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))", NULL, NULL, NULL); ////////////////////////////// color_labels DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE color_labels (imgid INTEGER, color INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE UNIQUE INDEX color_labels_idx ON color_labels (imgid, color)", NULL, NULL, NULL); ////////////////////////////// meta_data DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE meta_data (id INTEGER, key INTEGER, value VARCHAR)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE INDEX metadata_index ON meta_data (id, key)", NULL, NULL, NULL); ////////////////////////////// presets DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE TABLE presets (name VARCHAR, description VARCHAR, operation VARCHAR, op_version INTEGER, op_params BLOB, " "enabled INTEGER, blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256), " "model VARCHAR, maker VARCHAR, lens VARCHAR, iso_min REAL, iso_max REAL, exposure_min REAL, exposure_max REAL, " "aperture_min REAL, aperture_max REAL, focal_length_min REAL, focal_length_max REAL, writeprotect INTEGER, " "autoapply INTEGER, filter INTEGER, def INTEGER, isldr INTEGER)", NULL, NULL, NULL); DT_DEBUG_SQLITE3_EXEC(db->handle, "CREATE UNIQUE INDEX presets_idx ON presets(name, operation, op_version)", NULL, NULL, NULL); }
int32_t dt_control_remove_images_job_run(dt_job_t *job) { long int imgid = -1; dt_control_image_enumerator_t *t1 = (dt_control_image_enumerator_t *)job->param; GList *t = t1->index; int total = g_list_length(t); char message[512]= {0}; double fraction=0; snprintf(message, 512, ngettext ("removing %d image", "removing %d images", total), total ); const guint *jid = dt_control_backgroundjobs_create(darktable.control, 0, message); sqlite3_stmt *stmt = NULL; // check that we can safely remove the image char query[1024]; gboolean remove_ok = TRUE; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT id FROM images WHERE id IN (SELECT imgid FROM selected_images) AND flags&?1=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, DT_IMAGE_LOCAL_COPY); while(sqlite3_step(stmt) == SQLITE_ROW) { int imgid = sqlite3_column_int(stmt, 0); if (!dt_image_safe_remove(imgid)) { remove_ok = FALSE; break; } } sqlite3_finalize(stmt); if (!remove_ok) { dt_control_log(_("cannot remove local copy when the original file is not accessible.")); dt_control_backgroundjobs_destroy(darktable.control, jid); return 0; } // update remove status sprintf(query, "update images set flags = (flags | %d) where id in (select imgid from selected_images)",DT_IMAGE_REMOVE); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL); dt_collection_update(darktable.collection); // We need a list of files to regenerate .xmp files if there are duplicates GList *list = NULL; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select distinct folder || '/' || filename from images, film_rolls where images.film_id = film_rolls.id and images.id in (select imgid from selected_images)", -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { list = g_list_append(list, g_strdup((const gchar *)sqlite3_column_text(stmt, 0))); } sqlite3_finalize(stmt); while(t) { imgid = (long int)t->data; dt_image_remove(imgid); t = g_list_delete_link(t, t); fraction=1.0/total; dt_control_backgroundjobs_progress(darktable.control, jid, fraction); } char *imgname; while(list) { imgname = (char *)list->data; dt_image_synch_all_xmp(imgname); list = g_list_delete_link(list, list); } dt_control_backgroundjobs_destroy(darktable.control, jid); dt_film_remove_empty(); dt_control_queue_redraw_center(); return 0; }
// this is also called for non-gui applications linking to libdarktable! // so beware, don't use any darktable.gui stuff here .. (or change this behaviour in darktable.c) void dt_gui_presets_init() { // remove auto generated presets from plugins, not the user included ones. DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM presets WHERE writeprotect = 1", NULL, NULL, NULL); }
int dt_history_copy_and_paste_on_image(int32_t imgid, int32_t dest_imgid, gboolean merge, GList *ops) { sqlite3_stmt *stmt; if(imgid == dest_imgid) return 1; if(imgid == -1) { dt_control_log(_("you need to copy history from an image before you paste it onto another")); return 1; } // be sure the current history is written before pasting some other history data const dt_view_t *cv = dt_view_manager_get_current_view(darktable.view_manager); if(cv->view((dt_view_t *)cv) == DT_VIEW_DARKROOM) dt_dev_write_history(darktable.develop); /* if merge onto history stack, lets find history offest in destination image */ int32_t offs = 0; if(merge) { /* apply on top of history stack */ // first trim the stack to get rid of whatever is above the selected entry DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "DELETE FROM main.history WHERE imgid = ?1 AND num >= (SELECT history_end " "FROM main.images WHERE id = imgid)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); sqlite3_step(stmt); sqlite3_finalize(stmt); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT IFNULL(MAX(num), -1)+1 FROM main.history WHERE imgid = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); if(sqlite3_step(stmt) == SQLITE_ROW) offs = sqlite3_column_int(stmt, 0); } else { /* replace history stack */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "DELETE FROM main.history WHERE imgid = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); sqlite3_step(stmt); } sqlite3_finalize(stmt); /* delete all items from the temp styles_items, this table is used only to get a ROWNUM of the results */ DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM memory.style_items", NULL, NULL, NULL); /* copy history items from styles onto temp table */ // prepare SQL request char req[2048]; g_strlcpy(req, "INSERT INTO memory.style_items (num, module, operation, op_params, enabled, blendop_params, " "blendop_version, multi_name, multi_priority) SELECT num, module, operation, " "op_params, enabled, blendop_params, blendop_version, multi_name, multi_priority FROM " "main.history WHERE imgid = ?1", sizeof(req)); // Add ops selection if any format: ... and num in (val1, val2) if(ops) { GList *l = ops; int first = 1; g_strlcat(req, " AND num IN (", sizeof(req)); while(l) { unsigned int value = GPOINTER_TO_UINT(l->data); char v[30]; if(!first) g_strlcat(req, ",", sizeof(req)); snprintf(v, sizeof(v), "%u", value); g_strlcat(req, v, sizeof(req)); first = 0; l = g_list_next(l); } g_strlcat(req, ")", sizeof(req)); } DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), req, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); sqlite3_step(stmt); sqlite3_finalize(stmt); /* copy the history items into the history of the dest image */ /* note: rowid starts at 1 while num has to start at 0! */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "INSERT INTO main.history " "(imgid,num,module,operation,op_params,enabled,blendop_params,blendop_" "version,multi_priority,multi_name) SELECT " "?1,?2+rowid-1,module,operation,op_params,enabled,blendop_params,blendop_" "version,multi_priority,multi_name FROM memory.style_items", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, offs); sqlite3_step(stmt); sqlite3_finalize(stmt); if(merge && ops) _dt_history_cleanup_multi_instance(dest_imgid, offs); // we have to copy masks too // what to do with existing masks ? if(merge) { // there's very little chance that we will have same shapes id. // but we may want to handle this case anyway // and it's not trivial at all ! } else { // let's remove all existing shapes DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "DELETE FROM main.mask WHERE imgid = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); sqlite3_step(stmt); sqlite3_finalize(stmt); } // let's copy now g_strlcpy(req, "INSERT INTO main.mask (imgid, formid, form, name, version, points, points_count, source) SELECT " "?1, formid, form, name, version, points, points_count, source FROM main.mask WHERE imgid = ?2", sizeof(req)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), req, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, imgid); sqlite3_step(stmt); sqlite3_finalize(stmt); // always make the whole stack active DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "UPDATE main.images SET history_end = (SELECT MAX(num) + 1 FROM main.history " "WHERE imgid = ?1) WHERE id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, dest_imgid); sqlite3_step(stmt); sqlite3_finalize(stmt); /* if current image in develop reload history */ if(dt_dev_is_current_image(darktable.develop, dest_imgid)) { dt_dev_reload_history_items(darktable.develop); dt_dev_modulegroups_set(darktable.develop, dt_dev_modulegroups_get(darktable.develop)); } /* update xmp file */ dt_image_synch_xmp(dest_imgid); dt_mipmap_cache_remove(darktable.mipmap_cache, dest_imgid); return 0; }
void init_presets (dt_iop_module_so_t *self) { dt_iop_colorzones_params_t p; DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "begin", NULL, NULL, NULL); p.channel = DT_IOP_COLORZONES_h; for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) { p.equalizer_y[DT_IOP_COLORZONES_L][k] = .5f; p.equalizer_y[DT_IOP_COLORZONES_C][k] = .0f; p.equalizer_y[DT_IOP_COLORZONES_h][k] = .5f; p.equalizer_x[DT_IOP_COLORZONES_L][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_C][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_h][k] = k/(DT_IOP_COLORZONES_BANDS-1.); } p.equalizer_y[DT_IOP_COLORZONES_C][0] = p.equalizer_y[DT_IOP_COLORZONES_C][DT_IOP_COLORZONES_BANDS-1] = 0.65; p.equalizer_x[DT_IOP_COLORZONES_C][1] = 3./16.; p.equalizer_x[DT_IOP_COLORZONES_C][2] = 0.50; p.equalizer_x[DT_IOP_COLORZONES_C][3] = 0.51; p.equalizer_x[DT_IOP_COLORZONES_C][4] = 15./16.; dt_gui_presets_add_generic(_("red black white"), self->op, self->version(), &p, sizeof(p), 1); p.channel = DT_IOP_COLORZONES_h; for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) { p.equalizer_y[DT_IOP_COLORZONES_L][k] = .5f; p.equalizer_y[DT_IOP_COLORZONES_C][k] = .0f; p.equalizer_y[DT_IOP_COLORZONES_h][k] = .5f; p.equalizer_x[DT_IOP_COLORZONES_L][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_C][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_h][k] = k/(DT_IOP_COLORZONES_BANDS-1.); } p.equalizer_y[DT_IOP_COLORZONES_C][0] = p.equalizer_y[DT_IOP_COLORZONES_C][DT_IOP_COLORZONES_BANDS-1] = 0.5; p.equalizer_x[DT_IOP_COLORZONES_C][2] = 0.25f; p.equalizer_y[DT_IOP_COLORZONES_C][1] = 0.3f; dt_gui_presets_add_generic(_("black white and skin tones"), self->op, self->version(), &p, sizeof(p), 1); p.channel = DT_IOP_COLORZONES_C; for(int k=0; k<DT_IOP_COLORZONES_BANDS; k++) { p.equalizer_y[DT_IOP_COLORZONES_L][k] = .5f; p.equalizer_y[DT_IOP_COLORZONES_C][k] = .5f; p.equalizer_y[DT_IOP_COLORZONES_h][k] = .5f; p.equalizer_x[DT_IOP_COLORZONES_L][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_C][k] = k/(DT_IOP_COLORZONES_BANDS-1.); p.equalizer_x[DT_IOP_COLORZONES_h][k] = k/(DT_IOP_COLORZONES_BANDS-1.); } for(int k=2; k<DT_IOP_COLORZONES_BANDS; k++) p.equalizer_y[DT_IOP_COLORZONES_C][k] += (k-1.5)/(DT_IOP_COLORZONES_BANDS-2.0) * 0.25; for(int k=3; k<DT_IOP_COLORZONES_BANDS; k++) p.equalizer_y[DT_IOP_COLORZONES_L][k] -= (k-2.5)/(DT_IOP_COLORZONES_BANDS-3.0) * 0.35; dt_gui_presets_add_generic(_("polarizing filter"), self->op, self->version(), &p, sizeof(p), 1); p.channel = 2; p.equalizer_x[0][0] = 0.000000; p.equalizer_y[0][0] = 0.500000; p.equalizer_x[0][1] = 0.200000; p.equalizer_y[0][1] = 0.500000; p.equalizer_x[0][2] = 0.400000; p.equalizer_y[0][2] = 0.500000; p.equalizer_x[0][3] = 0.600000; p.equalizer_y[0][3] = 0.500000; p.equalizer_x[0][4] = 0.800000; p.equalizer_y[0][4] = 0.500000; p.equalizer_x[0][5] = 1.000000; p.equalizer_y[0][5] = 0.500000; p.equalizer_x[1][0] = 0.000000; p.equalizer_y[1][0] = 0.468932; p.equalizer_x[1][1] = 0.120155; p.equalizer_y[1][1] = 0.445975; p.equalizer_x[1][2] = 0.248062; p.equalizer_y[1][2] = 0.468932; p.equalizer_x[1][3] = 0.500000; p.equalizer_y[1][3] = 0.499667; p.equalizer_x[1][4] = 0.748062; p.equalizer_y[1][4] = 0.500000; p.equalizer_x[1][5] = 1.000000; p.equalizer_y[1][5] = 0.468932; p.equalizer_x[2][0] = 0.000000; p.equalizer_y[2][0] = 0.500000; p.equalizer_x[2][1] = 0.200000; p.equalizer_y[2][1] = 0.500000; p.equalizer_x[2][2] = 0.400000; p.equalizer_y[2][2] = 0.500000; p.equalizer_x[2][3] = 0.600000; p.equalizer_y[2][3] = 0.500000; p.equalizer_x[2][4] = 0.800000; p.equalizer_y[2][4] = 0.500000; p.equalizer_x[2][5] = 1.000000; p.equalizer_y[2][5] = 0.500000; dt_gui_presets_add_generic(_("natural skin tones"), self->op, self->version(), &p, sizeof(p), 1); p.channel = 2; p.equalizer_x[0][0] = 0.000000; p.equalizer_y[0][0] = 0.613040; p.equalizer_x[0][1] = 0.245283; p.equalizer_y[0][1] = 0.447962; p.equalizer_x[0][2] = 0.498113; p.equalizer_y[0][2] = 0.529201; p.equalizer_x[0][3] = 0.641509; p.equalizer_y[0][3] = 0.664967; p.equalizer_x[0][4] = 0.879245; p.equalizer_y[0][4] = 0.777294; p.equalizer_x[0][5] = 1.000000; p.equalizer_y[0][5] = 0.613040; p.equalizer_x[1][0] = 0.000000; p.equalizer_y[1][0] = 0.000000; p.equalizer_x[1][1] = 0.200000; p.equalizer_y[1][1] = 0.000000; p.equalizer_x[1][2] = 0.400000; p.equalizer_y[1][2] = 0.000000; p.equalizer_x[1][3] = 0.600000; p.equalizer_y[1][3] = 0.000000; p.equalizer_x[1][4] = 0.800000; p.equalizer_y[1][4] = 0.000000; p.equalizer_x[1][5] = 1.000000; p.equalizer_y[1][5] = 0.000000; p.equalizer_x[2][0] = 0.000000; p.equalizer_y[2][0] = 0.500000; p.equalizer_x[2][1] = 0.200000; p.equalizer_y[2][1] = 0.500000; p.equalizer_x[2][2] = 0.400000; p.equalizer_y[2][2] = 0.500000; p.equalizer_x[2][3] = 0.600000; p.equalizer_y[2][3] = 0.500000; p.equalizer_x[2][4] = 0.800000; p.equalizer_y[2][4] = 0.500000; p.equalizer_x[2][5] = 1.000000; p.equalizer_y[2][5] = 0.500000; dt_gui_presets_add_generic(_("black & white film"), self->op, self->version(), &p, sizeof(p), 1); DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "commit", NULL, NULL, NULL); }
void dt_styles_apply_to_image(const char *name,gboolean duplicate, int32_t imgid) { int id=0; sqlite3_stmt *stmt; int32_t newimgid; if ((id=dt_styles_get_id_by_name(name)) != 0) { /* check if we should make a duplicate before applying style */ if (duplicate) { newimgid = dt_image_duplicate (imgid); if(newimgid != -1) dt_history_copy_and_paste_on_image(imgid, newimgid, FALSE, NULL); } else newimgid = imgid; /* merge onto history stack, let's find history offest in destination image */ int32_t offs = 0; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT MAX(num)+1 FROM history WHERE imgid = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, newimgid); if (sqlite3_step (stmt) == SQLITE_ROW) offs = sqlite3_column_int (stmt, 0); sqlite3_finalize (stmt); /* delete all items from the temp styles_items, this table is used only to get a ROWNUM of the results */ DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM memory.style_items",NULL,NULL,NULL); /* copy history items from styles onto temp table */ DT_DEBUG_SQLITE3_PREPARE_V2 (dt_database_get(darktable.db), "INSERT INTO MEMORY.style_items SELECT * FROM style_items WHERE styleid=?1 ORDER BY multi_priority DESC;", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, id); sqlite3_step (stmt); sqlite3_finalize (stmt); /* copy the style items into the history */ DT_DEBUG_SQLITE3_PREPARE_V2 (dt_database_get(darktable.db), "INSERT INTO history (imgid,num,module,operation,op_params,enabled,blendop_params,blendop_version,multi_priority,multi_name) SELECT ?1,?2+rowid,module,operation,op_params,enabled,blendop_params,blendop_version,multi_priority,multi_name FROM MEMORY.style_items", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, newimgid); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, offs); sqlite3_step (stmt); sqlite3_finalize (stmt); /* add tag */ guint tagid=0; gchar ntag[512]= {0}; g_snprintf(ntag,512,"darktable|style|%s",name); if (dt_tag_new(ntag,&tagid)) dt_tag_attach(tagid,newimgid); /* if current image in develop reload history */ if (dt_dev_is_current_image(darktable.develop, newimgid)) { dt_dev_reload_history_items (darktable.develop); dt_dev_modulegroups_set(darktable.develop, dt_dev_modulegroups_get(darktable.develop)); } /* update xmp file */ dt_image_synch_xmp(newimgid); /* remove old obsolete thumbnails */ dt_mipmap_cache_remove(darktable.mipmap_cache, newimgid); /* if we have created a duplicate, reset collected images */ if (duplicate) dt_control_signal_raise(darktable.signals, DT_SIGNAL_COLLECTION_CHANGED); /* redraw center view to update visible mipmaps */ dt_control_queue_redraw_center(); } }
void dt_colorlabels_remove_labels_selection() { DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM main.color_labels WHERE imgid IN (SELECT imgid FROM main.selected_images)", NULL, NULL, NULL); }
void dt_colorlabels_remove_labels_selection () { DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from color_labels where imgid in (select imgid from selected_images)", NULL, NULL, NULL); }