void gui_reset (dt_lib_module_t *self) { // make sure we don't do anything useless: if(!dt_control_running()) return; dt_lib_export_t *d = (dt_lib_export_t *)self->data; gtk_spin_button_set_value(d->width, dt_conf_get_int("plugins/lighttable/export/width")); gtk_spin_button_set_value(d->height, dt_conf_get_int("plugins/lighttable/export/height")); // Set storage gchar *storage_name = dt_conf_get_string("plugins/lighttable/export/storage_name"); int storage_index = dt_imageio_get_index_of_storage(dt_imageio_get_storage_by_name(storage_name)); g_free(storage_name); gtk_combo_box_set_active(d->storage, storage_index); gtk_combo_box_set_active(d->intent, (int)dt_conf_get_int("plugins/lighttable/export/iccintent") + 1); // iccprofile int iccfound = 0; gchar *iccprofile = dt_conf_get_string("plugins/lighttable/export/iccprofile"); if(iccprofile) { GList *prof = d->profiles; while(prof) { dt_lib_export_profile_t *pp = (dt_lib_export_profile_t *)prof->data; if(!strcmp(pp->filename, iccprofile)) { gtk_combo_box_set_active(d->profile, pp->pos); iccfound = 1; } if(iccfound) break; prof = g_list_next(prof); } g_free(iccprofile); } // style // set it to none if the var is not set or the style doesn't exist anymore gboolean rc = FALSE; gchar *style = dt_conf_get_string("plugins/lighttable/export/style"); if (style != NULL) { rc = _combo_box_set_active_text(d->style, style); if (rc == FALSE) gtk_combo_box_set_active(d->style, 0); g_free(style); } else gtk_combo_box_set_active(d->style, 0); if(!iccfound) gtk_combo_box_set_active(d->profile, 0); dt_imageio_module_format_t *mformat = dt_imageio_get_format(); if(mformat) mformat->gui_reset(mformat); dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage(); if(mstorage) mstorage->gui_reset(mstorage); }
void gui_reset (dt_lib_module_t *self) { // make sure we don't do anything useless: if(!dt_control_running()) return; dt_lib_export_t *d = (dt_lib_export_t *)self->data; gtk_spin_button_set_value(d->width, dt_conf_get_int("plugins/lighttable/export/width")); gtk_spin_button_set_value(d->height, dt_conf_get_int("plugins/lighttable/export/height")); // Set storage int k = dt_conf_get_int ("plugins/lighttable/export/storage"); gtk_combo_box_set_active(d->storage, k); gtk_combo_box_set_active(d->intent, (int)dt_conf_get_int("plugins/lighttable/export/iccintent") + 1); int iccfound = 0; gchar *iccprofile = dt_conf_get_string("plugins/lighttable/export/iccprofile"); if(iccprofile) { GList *prof = d->profiles; while(prof) { dt_lib_export_profile_t *pp = (dt_lib_export_profile_t *)prof->data; if(!strcmp(pp->filename, iccprofile)) { gtk_combo_box_set_active(d->profile, pp->pos); iccfound = 1; } if(iccfound) break; prof = g_list_next(prof); } g_free(iccprofile); } if(!iccfound) gtk_combo_box_set_active(d->profile, 0); dt_imageio_module_format_t *mformat = dt_imageio_get_format(); if(mformat) mformat->gui_reset(mformat); dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage(); if(mstorage) mstorage->gui_reset(mstorage); }
void* get_params (dt_lib_module_t *self, int *size) { // concat storage and format, size is max + header dt_imageio_module_format_t *mformat = dt_imageio_get_format(); dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage(); if(!mformat || !mstorage) return NULL; int32_t fsize = 0, ssize = 0; // size will be only as large as to remove random pointers from params (stored at the end). dt_imageio_module_data_t *fdata = mformat->get_params(mformat, &fsize); void *sdata = mstorage->get_params(mstorage, &ssize); // we allow null pointers (plugin not ready for export in current state), and just dont copy back the settings later: if(!sdata) ssize = 0; if(!fdata) fsize = 0; if(fdata) { // clean up format global params (need to set all bytes to reliably detect which preset is active). // we happen to want to set it all to 0 memset(fdata, 0, sizeof(dt_imageio_module_data_t)); } // FIXME: also the web preset has to be applied twice to be known as preset! (other dimension magic going on here?) // TODO: get this stuff from gui and not from conf, so it will be sanity-checked (you can never delete an insane preset)? // also store icc profile/intent here. int32_t iccintent = dt_conf_get_int("plugins/lighttable/export/iccintent"); int32_t max_width = dt_conf_get_int ("plugins/lighttable/export/width"); int32_t max_height = dt_conf_get_int ("plugins/lighttable/export/height"); gchar *iccprofile = dt_conf_get_string("plugins/lighttable/export/iccprofile"); gchar *style = dt_conf_get_string("plugins/lighttable/export/style"); if (fdata) { strncpy(fdata->style, style, 128); } if(!iccprofile) { iccprofile = (char *)g_malloc(1); iccprofile[0] = '\0'; } char *fname = mformat->plugin_name, *sname = mstorage->plugin_name; int32_t fname_len = strlen(fname), sname_len = strlen(sname); *size = fname_len + sname_len + 2 + 2*sizeof(int32_t) + fsize + ssize + 3*sizeof(int32_t) + strlen(iccprofile) + 1; char *params = (char *)malloc(*size); memset(params, 0, *size); int pos = 0; memcpy(params+pos, &max_width, sizeof(int32_t)); pos += sizeof(int32_t); memcpy(params+pos, &max_height, sizeof(int32_t)); pos += sizeof(int32_t); memcpy(params+pos, &iccintent, sizeof(int32_t)); pos += sizeof(int32_t); memcpy(params+pos, iccprofile, strlen(iccprofile)+1); pos += strlen(iccprofile) + 1; memcpy(params+pos, fname, fname_len+1); pos += fname_len+1; memcpy(params+pos, sname, sname_len+1); pos += sname_len+1; memcpy(params+pos, &fsize, sizeof(int32_t)); pos += sizeof(int32_t); memcpy(params+pos, &ssize, sizeof(int32_t)); pos += sizeof(int32_t); if(fdata != NULL) // otherwise fsize == 0, but clang doesn't like it ... { memcpy(params+pos, fdata, fsize); pos += fsize; } if(sdata != NULL) // see above { memcpy(params+pos, sdata, ssize); pos += ssize; } g_assert(pos == *size); g_free(iccprofile); g_free(style); if(fdata) mformat->free_params(mformat, fdata); if(sdata) mstorage->free_params(mstorage, sdata); return params; }
int32_t dt_control_export_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; const int total = g_list_length(t); int size = 0; dt_imageio_module_format_t *mformat = dt_imageio_get_format(); g_assert(mformat); dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage(); g_assert(mstorage); // Get max dimensions... uint32_t w,h,fw,fh,sw,sh; fw=fh=sw=sh=0; mstorage->dimension(mstorage, &sw,&sh); mformat->dimension(mformat, &fw,&fh); if( sw==0 || fw==0) w=sw>fw?sw:fw; else w=sw<fw?sw:fw; if( sh==0 || fh==0) h=sh>fh?sh:fh; else h=sh<fh?sh:fh; // get shared storage param struct (global sequence counter, one picasa connection etc) dt_imageio_module_data_t *sdata = mstorage->get_params(mstorage, &size); if(sdata == NULL) { dt_control_log(_("failed to get parameters from storage module, aborting export..")); return 1; } dt_control_log(ngettext ("exporting %d image..", "exporting %d images..", total), total); char message[512]= {0}; snprintf(message, 512, ngettext ("exporting %d image to %s", "exporting %d images to %s", total), total, mstorage->name() ); /* create a cancellable bgjob ui template */ const guint *jid = dt_control_backgroundjobs_create(darktable.control, 0, message ); dt_control_backgroundjobs_set_cancellable(darktable.control, jid, job); const dt_control_t *control = darktable.control; double fraction=0; #ifdef _OPENMP // limit this to num threads = num full buffers - 1 (keep one for darkroom mode) // use min of user request and mipmap cache entries const int full_entries = dt_conf_get_int ("parallel_export"); // GCC won't accept that this variable is used in a macro, considers // it set but not used, which makes for instance Fedora break. const __attribute__((__unused__)) int num_threads = MAX(1, MIN(full_entries, 8)); #if !defined(__SUNOS__) #pragma omp parallel default(none) private(imgid, size) shared(control, fraction, w, h, stderr, mformat, mstorage, t, sdata, job, jid, darktable) num_threads(num_threads) if(num_threads > 1) #else #pragma omp parallel private(imgid, size) shared(control, fraction, w, h, mformat, mstorage, t, sdata, job, jid, darktable) num_threads(num_threads) if(num_threads > 1) #endif { #endif // get a thread-safe fdata struct (one jpeg struct per thread etc): dt_imageio_module_data_t *fdata = mformat->get_params(mformat, &size); fdata->max_width = dt_conf_get_int ("plugins/lighttable/export/width"); fdata->max_height = dt_conf_get_int ("plugins/lighttable/export/height"); fdata->max_width = (w!=0 && fdata->max_width >w)?w:fdata->max_width; fdata->max_height = (h!=0 && fdata->max_height >h)?h:fdata->max_height; int num = 0; // Invariant: the tagid for 'darktable|changed' will not change while this function runs. Is this a sensible assumption? guint tagid = 0; dt_tag_new("darktable|changed",&tagid); while(t && dt_control_job_get_state(job) != DT_JOB_STATE_CANCELLED) { #ifdef _OPENMP #pragma omp critical #endif { if(!t) imgid = 0; else { imgid = (long int)t->data; t = g_list_delete_link(t, t); num = total - g_list_length(t); } } // remove 'changed' tag from image dt_tag_detach(tagid, imgid); // check if image still exists: char imgfilename[DT_MAX_PATH_LEN]; const dt_image_t *image = dt_image_cache_read_get(darktable.image_cache, (int32_t)imgid); if(image) { dt_image_full_path(image->id, imgfilename, DT_MAX_PATH_LEN); if(!g_file_test(imgfilename, G_FILE_TEST_IS_REGULAR)) { dt_control_log(_("image `%s' is currently unavailable"), image->filename); fprintf(stderr, _("image `%s' is currently unavailable"), imgfilename); // dt_image_remove(imgid); dt_image_cache_read_release(darktable.image_cache, image); } else { dt_image_cache_read_release(darktable.image_cache, image); mstorage->store(sdata, imgid, mformat, fdata, num, total); } } #ifdef _OPENMP #pragma omp critical #endif { fraction+=1.0/total; dt_control_backgroundjobs_progress(control, jid, fraction); } } #ifdef _OPENMP #pragma omp barrier #pragma omp master #endif { dt_control_backgroundjobs_destroy(control, jid); if(mstorage->finalize_store) mstorage->finalize_store(mstorage, sdata); mstorage->free_params(mstorage, sdata); } // all threads free their fdata mformat->free_params (mformat, fdata); #ifdef _OPENMP } #endif return 0; }