Example #1
0
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);
  }
}
Example #2
0
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);
}
Example #3
0
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"));
}
Example #4
0
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"));

}
Example #5
0
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);
}
Example #6
0
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;
}
Example #7
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);  

}
Example #8
0
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);
}
Example #9
0
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);
}
Example #10
0
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;
}
Example #11
0
/* 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);

}
Example #12
0
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;
}
Example #13
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);
}
Example #14
0
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;
}
Example #15
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);
}
Example #16
0
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();
  }
}
Example #17
0
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);
}
Example #18
0
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);
}