dt_imageio_module_storage_t *dt_imageio_get_storage() { dt_imageio_t *iio = darktable.imageio; gchar *storage_name = dt_conf_get_string("plugins/lighttable/export/storage_name"); dt_imageio_module_storage_t *storage = dt_imageio_get_storage_by_name(storage_name); g_free(storage_name); // if the storage from the config isn't available default to disk, if that's not available either just use the first we have if(!storage) storage = dt_imageio_get_storage_by_name("disk"); if(!storage) storage = iio->plugins_storage->data; return storage; }
static void export_button_clicked (GtkWidget *widget, gpointer user_data) { char style[128]; // Let's get the max dimension restriction if any... // TODO: pass the relevant values directly, not using the conf ... int max_width = dt_conf_get_int ("plugins/lighttable/export/width"); int max_height = dt_conf_get_int ("plugins/lighttable/export/height"); char *format_name = dt_conf_get_string("plugins/lighttable/export/format_name"); char *storage_name = dt_conf_get_string("plugins/lighttable/export/storage_name"); int format_index = dt_imageio_get_index_of_format(dt_imageio_get_format_by_name(format_name)); int storage_index = dt_imageio_get_index_of_storage(dt_imageio_get_storage_by_name(storage_name)); g_free(format_name); g_free(storage_name); gboolean high_quality = dt_conf_get_bool("plugins/lighttable/export/high_quality_processing"); char* tmp = dt_conf_get_string("plugins/lighttable/export/style"); if (tmp) { g_strlcpy(style, tmp, sizeof(style)); g_free(tmp); } int imgid = dt_view_get_image_to_act_on(); GList *list = NULL; if (imgid != -1) list = g_list_append (list, GINT_TO_POINTER(imgid)); else list = dt_collection_get_selected(darktable.collection, -1); dt_control_export(list, max_width, max_height, format_index, storage_index, high_quality,style); }
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); }
static int get_storage_params(lua_State *L) { const char * storage_name = luaL_checkstring(L,-1); dt_imageio_module_storage_t *storage_module = dt_imageio_get_storage_by_name(storage_name); dt_imageio_module_data_t *fdata = storage_module->get_params(storage_module); if(!fdata) { // facebook does that if it hasn't been authenticated yet lua_pushnil(L); return 1; } luaA_push_typeid(L,storage_module->parameter_lua_type,fdata); storage_module->free_params(storage_module,fdata); return 1; }
static void _update_formats_combobox(dt_lib_export_t *d) { // Clear format combo box gtk_list_store_clear( GTK_LIST_STORE(gtk_combo_box_get_model(d->format) ) ); // Get current selected storage gchar *storage_name = dt_conf_get_string("plugins/lighttable/export/storage_name"); dt_imageio_module_storage_t *storage = dt_imageio_get_storage_by_name(storage_name); g_free(storage_name); // Add supported formats to combobox GList *it = darktable.imageio->plugins_format; while(it) { dt_imageio_module_format_t *format = (dt_imageio_module_format_t *)it->data; if( storage->supported( storage, format ) ) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(d->format), format->name()); it = g_list_next(it); } }
static void _get_max_output_dimension(dt_lib_export_t *d,uint32_t *width, uint32_t *height) { gchar *storage_name = dt_conf_get_string("plugins/lighttable/export/storage_name"); dt_imageio_module_storage_t *storage = dt_imageio_get_storage_by_name(storage_name); g_free(storage_name); char *format_name = dt_conf_get_string("plugins/lighttable/export/format_name"); dt_imageio_module_format_t *format = dt_imageio_get_format_by_name(format_name); g_free(format_name); if( storage && format ) { uint32_t fw,fh,sw,sh; fw=fh=sw=sh=0; // We are all equals!!! storage->dimension(storage, &sw,&sh); format->dimension(format, &fw,&fh); if( sw==0 || fw==0) *width=sw>fw?sw:fw; else *width=sw<fw?sw:fw; if( sh==0 || fh==0) *height=sh>fh?sh:fh; else *height=sh<fh?sh:fh; } }
int main(int argc, char *arg[]) { bindtextdomain (GETTEXT_PACKAGE, DARKTABLE_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &arg); // parse command line arguments char *image_filename = NULL; char *xmp_filename = NULL; char *output_filename = NULL; int file_counter = 0; int width = 0, height = 0, bpp = 0; gboolean verbose = FALSE, high_quality = TRUE; for(int k=1; k<argc; k++) { if(arg[k][0] == '-') { if(!strcmp(arg[k], "--help")) { usage(arg[0]); exit(1); } else if(!strcmp(arg[k], "--version")) { printf("this is darktable-cli\ncopyright (c) 2012-2013 johannes hanika, tobias ellinghaus\n"); exit(1); } else if(!strcmp(arg[k], "--width")) { k++; width = MAX(atoi(arg[k]), 0); } else if(!strcmp(arg[k], "--height")) { k++; height = MAX(atoi(arg[k]), 0); } else if(!strcmp(arg[k], "--bpp")) { k++; bpp = MAX(atoi(arg[k]), 0); fprintf(stderr, "%s %d\n", _("TODO: sorry, due to api restrictions we currently cannot set the bpp to"), bpp); } else if(!strcmp(arg[k], "--hq")) { k++; gchar *str = g_ascii_strup(arg[k], -1); if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE")) high_quality = FALSE; else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE")) high_quality = TRUE; else { fprintf(stderr, "%s: %s\n", _("Unknown option for --hq"), arg[k]); usage(arg[0]); exit(1); } g_free(str); } else if(!strcmp(arg[k], "-v") || !strcmp(arg[k], "--verbose")) { verbose = TRUE; } } else { if(file_counter == 0) image_filename = arg[k]; else if(file_counter == 1) xmp_filename = arg[k]; else if(file_counter == 2) output_filename = arg[k]; file_counter++; } } if(file_counter < 2 || file_counter > 3) { usage(arg[0]); exit(1); } else if(file_counter == 2) { // no xmp file given output_filename = xmp_filename; xmp_filename = NULL; } // the output file already exists, so there will be a sequence number added if(g_file_test(output_filename, G_FILE_TEST_EXISTS)) { fprintf(stderr, "%s\n", _("output file already exists, it will get renamed")); } char *m_arg[] = {"darktable-cli", "--library", ":memory:", NULL}; // init dt without gui: if(dt_init(3, m_arg, 0)) exit(1); dt_film_t film; int id = 0; int filmid = 0; gchar *directory = g_path_get_dirname(image_filename); filmid = dt_film_new(&film, directory); id = dt_image_import(filmid, image_filename, TRUE); if(!id) { fprintf(stderr, _("error: can't open file %s"), image_filename); fprintf(stderr, "\n"); exit(1); } g_free(directory); // attach xmp, if requested: if(xmp_filename) { const dt_image_t *cimg = dt_image_cache_read_get(darktable.image_cache, id); dt_image_t *image = dt_image_cache_write_get(darktable.image_cache, cimg); dt_exif_xmp_read(image, xmp_filename, 1); // don't write new xmp: dt_image_cache_write_release(darktable.image_cache, image, DT_IMAGE_CACHE_RELAXED); dt_image_cache_read_release(darktable.image_cache, image); } // print the history stack if(verbose) { gchar *history = dt_history_get_items_as_string(id); if(history) printf("%s\n", history); else printf("[%s]\n", _("empty history stack")); } // try to find out the export format from the output_filename char *ext = output_filename + strlen(output_filename); while(ext > output_filename && *ext != '.') ext--; *ext = '\0'; ext++; if(!strcmp(ext, "jpg")) ext = "jpeg"; // init the export data structures int size = 0, dat_size = 0; dt_imageio_module_format_t *format; dt_imageio_module_storage_t *storage; dt_imageio_module_data_t *sdata, *fdata; storage = dt_imageio_get_storage_by_name("disk"); // only exporting to disk makes sense if(storage == NULL) { fprintf(stderr, "%s\n", _("cannot find disk storage module. please check your installation, something seems to be broken.")); exit(1); } sdata = storage->get_params(storage, &size); if(sdata == NULL) { fprintf(stderr, "%s\n", _("failed to get parameters from storage module, aborting export ...")); exit(1); } // and now for the really ugly hacks. don't tell your children about this one or they won't sleep at night any longer ... g_strlcpy((char*)sdata, output_filename, DT_MAX_PATH_LEN); // all is good now, the last line didn't happen. format = dt_imageio_get_format_by_name(ext); if(format == NULL) { fprintf(stderr, _("unknown extension '.%s'"), ext); fprintf(stderr, "\n"); exit(1); } fdata = format->get_params(format, &dat_size); if(fdata == NULL) { fprintf(stderr, "%s\n", _("failed to get parameters from format module, aborting export ...")); exit(1); } uint32_t w,h,fw,fh,sw,sh; fw=fh=sw=sh=0; storage->dimension(storage, &sw, &sh); format->dimension(format, &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; fdata->max_width = width; fdata->max_height = 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; fdata->style[0] = '\0'; //TODO: add a callback to set the bpp without going through the config storage->store(storage,sdata, id, format, fdata, 1, 1, high_quality); // cleanup time if(storage->finalize_store) storage->finalize_store(storage, sdata); storage->free_params(storage, sdata); format->free_params(format, fdata); dt_cleanup(); }
int set_params (dt_lib_module_t *self, const void *params, int size) { dt_lib_export_t *d = (dt_lib_export_t *)self->data; // apply these stored presets again (parse blob) const char *buf = (const char* )params; const int max_width = *(const int *)buf; buf += sizeof(int32_t); const int max_height = *(const int *)buf; buf += sizeof(int32_t); const int iccintent = *(const int *)buf; buf += sizeof(int32_t); const char *iccprofile = buf; buf += strlen(iccprofile) + 1; // reverse these by setting the gui, not the conf vars! gtk_combo_box_set_active (d->intent, iccintent + 1); if(!strcmp(iccprofile, "image")) { gtk_combo_box_set_active(d->profile, 0); } else { 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); break; } prof = g_list_next(prof); } } // parse both names to '\0' const char *fname = buf; buf += strlen(fname) + 1; const char *sname = buf; buf += strlen(sname) + 1; // get module by name and fail if not there. dt_imageio_module_format_t *fmod = dt_imageio_get_format_by_name(fname); dt_imageio_module_storage_t *smod = dt_imageio_get_storage_by_name(sname); if(!fmod || !smod) return 1; const int fsize = *(const int *)buf; buf += sizeof(int32_t); const int ssize = *(const int *)buf; buf += sizeof(int32_t); if(size != strlen(fname) + strlen(sname) + 2 + 2*sizeof(int32_t) + fsize + ssize + 3*sizeof(int32_t) + strlen(iccprofile) + 1) return 1; const dt_imageio_module_data_t *fdata = (const dt_imageio_module_data_t *)buf; _combo_box_set_active_text(d->style, fdata->style); buf += fsize; const void *sdata = buf; // switch modules set_storage_by_name(d, sname); set_format_by_name(d, fname); // set dimensions after switching, to have new range ready. gtk_spin_button_set_value(d->width, max_width); gtk_spin_button_set_value(d->height, max_height); // propagate to modules int res = 0; if(ssize) res += smod->set_params(smod, sdata, ssize); if(fsize) res += fmod->set_params(fmod, fdata, fsize); return res; }
int main(int argc, char *arg[]) { bindtextdomain(GETTEXT_PACKAGE, DARKTABLE_LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); if(!gtk_parse_args(&argc, &arg)) exit(1); // parse command line arguments char *input_filename = NULL; char *xmp_filename = NULL; char *output_filename = NULL; int file_counter = 0; int width = 0, height = 0, bpp = 0; gboolean verbose = FALSE, high_quality = TRUE, upscale = FALSE; int k; for(k = 1; k < argc; k++) { if(arg[k][0] == '-') { if(!strcmp(arg[k], "--help")) { usage(arg[0]); exit(1); } else if(!strcmp(arg[k], "--version")) { printf("this is darktable-cli %s\ncopyright (c) 2012-2016 johannes hanika, tobias ellinghaus\n", darktable_package_version); exit(1); } else if(!strcmp(arg[k], "--width") && argc > k + 1) { k++; width = MAX(atoi(arg[k]), 0); } else if(!strcmp(arg[k], "--height") && argc > k + 1) { k++; height = MAX(atoi(arg[k]), 0); } else if(!strcmp(arg[k], "--bpp") && argc > k + 1) { k++; bpp = MAX(atoi(arg[k]), 0); fprintf(stderr, "%s %d\n", _("TODO: sorry, due to API restrictions we currently cannot set the BPP to"), bpp); } else if(!strcmp(arg[k], "--hq") && argc > k + 1) { k++; gchar *str = g_ascii_strup(arg[k], -1); if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE")) high_quality = FALSE; else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE")) high_quality = TRUE; else { fprintf(stderr, "%s: %s\n", _("unknown option for --hq"), arg[k]); usage(arg[0]); exit(1); } g_free(str); } else if(!strcmp(arg[k], "--upscale") && argc > k + 1) { k++; gchar *str = g_ascii_strup(arg[k], -1); if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE")) upscale = FALSE; else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE")) upscale= TRUE; else { fprintf(stderr, "%s: %s\n", _("unknown option for --upscale"), arg[k]); usage(arg[0]); exit(1); } g_free(str); } else if(!strcmp(arg[k], "-v") || !strcmp(arg[k], "--verbose")) { verbose = TRUE; } else if(!strcmp(arg[k], "--core")) { // everything from here on should be passed to the core k++; break; } } else { if(file_counter == 0) input_filename = arg[k]; else if(file_counter == 1) xmp_filename = arg[k]; else if(file_counter == 2) output_filename = arg[k]; file_counter++; } } int m_argc = 0; char **m_arg = malloc((5 + argc - k + 1) * sizeof(char *)); m_arg[m_argc++] = "darktable-cli"; m_arg[m_argc++] = "--library"; m_arg[m_argc++] = ":memory:"; m_arg[m_argc++] = "--conf"; m_arg[m_argc++] = "write_sidecar_files=FALSE"; for(; k < argc; k++) m_arg[m_argc++] = arg[k]; m_arg[m_argc] = NULL; if(file_counter < 2 || file_counter > 3) { usage(arg[0]); free(m_arg); exit(1); } else if(file_counter == 2) { // no xmp file given output_filename = xmp_filename; xmp_filename = NULL; } if(g_file_test(output_filename, G_FILE_TEST_IS_DIR)) { fprintf(stderr, _("error: output file is a directory. please specify file name")); fprintf(stderr, "\n"); free(m_arg); exit(1); } // the output file already exists, so there will be a sequence number added if(g_file_test(output_filename, G_FILE_TEST_EXISTS)) { fprintf(stderr, "%s\n", _("output file already exists, it will get renamed")); } // init dt without gui: if(dt_init(m_argc, m_arg, 0, NULL)) { free(m_arg); exit(1); } GList *id_list = NULL; if(g_file_test(input_filename, G_FILE_TEST_IS_DIR)) { int filmid = dt_film_import(input_filename); if(!filmid) { fprintf(stderr, _("error: can't open folder %s"), input_filename); fprintf(stderr, "\n"); free(m_arg); exit(1); } id_list = dt_film_get_image_ids(filmid); } else { dt_film_t film; int id = 0; int filmid = 0; gchar *directory = g_path_get_dirname(input_filename); filmid = dt_film_new(&film, directory); id = dt_image_import(filmid, input_filename, TRUE); if(!id) { fprintf(stderr, _("error: can't open file %s"), input_filename); fprintf(stderr, "\n"); free(m_arg); exit(1); } g_free(directory); id_list = g_list_append(id_list, GINT_TO_POINTER(id)); } int total = g_list_length(id_list); if(total == 0) { fprintf(stderr, _("no images to export, aborting\n")); free(m_arg); exit(1); } // attach xmp, if requested: if(xmp_filename) { for(GList *iter = id_list; iter; iter = g_list_next(iter)) { int id = GPOINTER_TO_INT(iter->data); dt_image_t *image = dt_image_cache_get(darktable.image_cache, id, 'w'); dt_exif_xmp_read(image, xmp_filename, 1); // don't write new xmp: dt_image_cache_write_release(darktable.image_cache, image, DT_IMAGE_CACHE_RELAXED); } } // print the history stack. only look at the first image and assume all got the same processing applied if(verbose) { int id = GPOINTER_TO_INT(id_list->data); gchar *history = dt_history_get_items_as_string(id); if(history) printf("%s\n", history); else printf("[%s]\n", _("empty history stack")); } // try to find out the export format from the output_filename char *ext = output_filename + strlen(output_filename); while(ext > output_filename && *ext != '.') ext--; *ext = '\0'; ext++; if(!strcmp(ext, "jpg")) ext = "jpeg"; if(!strcmp(ext, "tif")) ext = "tiff"; // init the export data structures dt_imageio_module_format_t *format; dt_imageio_module_storage_t *storage; dt_imageio_module_data_t *sdata, *fdata; storage = dt_imageio_get_storage_by_name("disk"); // only exporting to disk makes sense if(storage == NULL) { fprintf( stderr, "%s\n", _("cannot find disk storage module. please check your installation, something seems to be broken.")); free(m_arg); exit(1); } sdata = storage->get_params(storage); if(sdata == NULL) { fprintf(stderr, "%s\n", _("failed to get parameters from storage module, aborting export ...")); free(m_arg); exit(1); } // and now for the really ugly hacks. don't tell your children about this one or they won't sleep at night // any longer ... g_strlcpy((char *)sdata, output_filename, DT_MAX_PATH_FOR_PARAMS); // all is good now, the last line didn't happen. format = dt_imageio_get_format_by_name(ext); if(format == NULL) { fprintf(stderr, _("unknown extension '.%s'"), ext); fprintf(stderr, "\n"); free(m_arg); exit(1); } fdata = format->get_params(format); if(fdata == NULL) { fprintf(stderr, "%s\n", _("failed to get parameters from format module, aborting export ...")); free(m_arg); exit(1); } uint32_t w, h, fw, fh, sw, sh; fw = fh = sw = sh = 0; storage->dimension(storage, sdata, &sw, &sh); format->dimension(format, fdata, &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; fdata->max_width = width; fdata->max_height = 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; fdata->style[0] = '\0'; fdata->style_append = 0; if(storage->initialize_store) { storage->initialize_store(storage, sdata, &format, &fdata, &id_list, high_quality, upscale); format->set_params(format, fdata, format->params_size(format)); storage->set_params(storage, sdata, storage->params_size(storage)); } // TODO: add a callback to set the bpp without going through the config int num = 1; for(GList *iter = id_list; iter; iter = g_list_next(iter), num++) { int id = GPOINTER_TO_INT(iter->data); storage->store(storage, sdata, id, format, fdata, num, total, high_quality, upscale); } // cleanup time if(storage->finalize_store) storage->finalize_store(storage, sdata); storage->free_params(storage, sdata); format->free_params(format, fdata); g_list_free(id_list); dt_cleanup(); free(m_arg); }