static int write_image(lua_State *L) { /* check that param 1 is a module_format_t */ lua_getmetatable(L,1); lua_getfield(L,-1,"__module_type"); if(strcmp(lua_tostring(L,-1),"format")) { return luaL_argerror(L,1,"not a format description"); } lua_pop(L,1); lua_getfield(L,-1,"__luaA_Type"); luaA_Type format_type = luaL_checkint(L,-1); lua_pop(L,1); lua_getfield(L,-1,"__associated_object"); dt_imageio_module_format_t * format = lua_touserdata(L,-1); lua_pop(L,2); dt_imageio_module_data_t* fdata = format->get_params(format); luaA_to_typeid(L,format_type,fdata,1); /* check that param 2 is an image */ dt_lua_image_t imgid; luaA_to(L,dt_lua_image_t,&imgid,2); /* check that param 3 is a string (filename) */ const char * filename = luaL_checkstring(L,3); gboolean high_quality = dt_conf_get_bool("plugins/lighttable/export/high_quality_processing"); lua_pushboolean(L,dt_imageio_export(imgid,filename,format,fdata,high_quality)); format->free_params(format,fdata); return 1; }
static int write_image(lua_State *L) { /* check that param 1 is a module_format_t */ luaL_argcheck(L,dt_lua_isa(L,1,dt_imageio_module_format_t),-1,"dt_imageio_module_format_t expected"); lua_getmetatable(L,1); lua_getfield(L,-1,"__luaA_Type"); luaA_Type format_type = luaL_checkint(L,-1); lua_pop(L,1); lua_getfield(L,-1,"__associated_object"); dt_imageio_module_format_t * format = lua_touserdata(L,-1); lua_pop(L,2); dt_imageio_module_data_t* fdata = format->get_params(format); luaA_to_type(L,format_type,fdata,1); /* check that param 2 is an image */ dt_lua_image_t imgid; luaA_to(L,dt_lua_image_t,&imgid,2); /* check that param 3 is a string (filename) */ const char * filename = luaL_checkstring(L,3); dt_lua_unlock(false); gboolean high_quality = dt_conf_get_bool("plugins/lighttable/export/high_quality_processing"); gboolean result = dt_imageio_export(imgid,filename,format,fdata,high_quality,FALSE,NULL,NULL); dt_lua_lock(); lua_pushboolean(L,result); format->free_params(format,fdata); return 1; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent) { dt_imageio_email_t *d = (dt_imageio_email_t *)sdata; _email_attachment_t *attachment = (_email_attachment_t *)g_malloc(sizeof(_email_attachment_t)); attachment->imgid = imgid; /* construct a temporary file name */ char tmpdir[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(tmpdir, sizeof(tmpdir)); char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); gchar *filename = g_path_get_basename(dirname); g_strlcpy(dirname, filename, sizeof(dirname)); dt_image_path_append_version(imgid, dirname, sizeof(dirname)); gchar *end = g_strrstr(dirname, ".") + 1; if(end) *end = '\0'; g_strlcat(dirname, format->extension(fdata), sizeof(dirname)); // set exported filename attachment->file = g_build_filename(tmpdir, dirname, (char *)NULL); if(dt_imageio_export(imgid, attachment->file, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_email] could not export to file: `%s'!\n", attachment->file); dt_control_log(_("could not export to file `%s'!"), attachment->file); g_free(attachment); g_free(filename); return 1; } char *trunc = attachment->file + strlen(attachment->file) - 32; if(trunc < attachment->file) trunc = attachment->file; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); #ifdef _OPENMP // store can be called in parallel, so synch access to shared memory #pragma omp critical #endif d->images = g_list_append(d->images, attachment); g_free(filename); return 0; }
static int store_wrapper(struct dt_imageio_module_storage_t *self,struct dt_imageio_module_data_t *self_data, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { /* construct a temporary file name */ char tmpdir[DT_MAX_PATH_LEN]= {0}; gboolean from_cache = FALSE; dt_loc_get_tmp_dir (tmpdir,DT_MAX_PATH_LEN); char dirname[DT_MAX_PATH_LEN]; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN, &from_cache); const gchar * filename = g_path_get_basename( dirname ); gchar * end = g_strrstr( filename,".")+1; g_strlcpy( end, format->extension(fdata), sizeof(dirname)-(end-dirname)); gchar* complete_name = g_build_filename( tmpdir, filename, (char *)NULL ); if(dt_imageio_export(imgid, complete_name, format, fdata, high_quality) != 0) { fprintf(stderr, "[%s] could not export to file: `%s'!\n", self->name(self),complete_name); g_free(complete_name); return 1; } lua_storage_t *d = (lua_storage_t*) self_data; d->imgids = g_list_prepend(d->imgids,(void*)(intptr_t)imgid); d->file_names = g_list_prepend(d->file_names,complete_name); lua_State *L =darktable.lua_state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"store"); if(lua_isnil(L,-1)) { lua_pop(L,3); return 1; } luaA_push_typeid(L,self->parameter_lua_type,self_data); luaA_push(L,dt_lua_image_t,&imgid); luaA_push_typeid(L,format->parameter_lua_type,fdata); lua_pushstring(L,complete_name); lua_pushnumber(L,num); lua_pushnumber(L,total); lua_pushboolean(L,high_quality); lua_pushlightuserdata(L,self_data); lua_gettable(L,LUA_REGISTRYINDEX); dt_lua_do_chunk(L,8,1); int result = lua_toboolean(L,-1); lua_pop(L,2); return result; }
int store (dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { dt_imageio_email_t *d = (dt_imageio_email_t *)sdata; _email_attachment_t *attachment = ( _email_attachment_t *)g_malloc(sizeof(_email_attachment_t)); attachment->imgid = imgid; /* construct a temporary file name */ char tmpdir[4096]= {0}; dt_loc_get_tmp_dir (tmpdir,4096); char dirname[4096]; dt_image_full_path(imgid, dirname, 1024); const gchar * filename = g_path_get_basename( dirname ); gchar * end = g_strrstr( filename,".")+1; g_strlcpy( end, format->extension(fdata), sizeof(dirname)-(end-dirname)); attachment->file = g_build_filename( tmpdir, filename, (char *)NULL ); if(dt_imageio_export(imgid, attachment->file, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_email] could not export to file: `%s'!\n", attachment->file); dt_control_log(_("could not export to file `%s'!"), attachment->file); g_free(attachment); return 1; } char *trunc = attachment->file + strlen(attachment->file) - 32; if(trunc < attachment->file) trunc = attachment->file; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); #ifdef _OPENMP // store can be called in parallel, so synch access to shared memory #pragma omp critical #endif d->images = g_list_append( d->images, attachment ); return 0; }
int store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata; char filename[DT_MAX_PATH_LEN]= {0}; char dirname[DT_MAX_PATH_LEN]= {0}; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN); int fail = 0; // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if ( g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename))[0]=='/' || (d->filename+strlen(d->filename))[0]=='\\') ) snprintf (d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "_$(SEQUENCE)"); } gchar* fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, DT_MAX_PATH_LEN); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(filename, dt_variables_get_result(d->vp), DT_MAX_PATH_LEN); g_strlcpy(dirname, filename, DT_MAX_PATH_LEN); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c>dirname && *c != '/'; c--); if(*c == '/') { if(c > dirname) // /.../.../foo c[0] = '\0'; else // /foo c[1] = '\0'; } else if(c == dirname) // foo { c[0] = '.'; c[1] = '\0'; } if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); fail = 1; goto failed; } if(g_access(dirname, W_OK) != 0) { fprintf(stderr, "[imageio_storage_disk] could not write to directory: `%s'!\n", dirname); dt_control_log(_("could not write to directory `%s'!"), dirname); fail = 1; goto failed; } c = filename + strlen(filename); // remove everything after the last '.'. this destroys any file name with dots in it since $(FILE_NAME) already comes without the original extension. // for(; c>filename && *c != '.' && *c != '/' ; c--); // if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c,".%s",ext); /* prevent overwrite of files */ int seq=1; failed: if (!fail && g_file_test (filename,G_FILE_TEST_EXISTS)) { do { sprintf(c,"_%.2d.%s",seq,ext); seq++; } while (g_file_test (filename,G_FILE_TEST_EXISTS)); } } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); if(fail) return 1; /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_disk] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } /* now write xmp into that container, if possible */ if((format->flags() & FORMAT_FLAGS_SUPPORT_XMP) && dt_exif_xmp_attach(imgid, filename) != 0) { fprintf(stderr, "[imageio_storage_disk] could not attach xmp data to file: `%s'!\n", filename); // don't report that one to gui, as some formats (pfm, ppm, exr) just don't support // writing xmp via exiv2, so it might not be to worry. return 1; } printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); return 0; }
int store (dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { gint result=1; dt_storage_flickr_params_t *p=(dt_storage_flickr_params_t *)sdata; flickcurl_upload_status *photo_status; gint tags=0; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[4096]= {0}; dt_loc_get_tmp_dir (fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); char *caption = NULL; char *description = NULL; gint fd=g_mkstemp(fname); fprintf(stderr,"tempfile: %s\n",fname); if(fd==-1) { dt_control_log("failed to create temporary image for flickr export"); return 1; } close(fd); const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); // If title is not existing, then use the filename without extension. If not, then use title instead GList *title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); if(title != NULL) { caption = g_strdup(title->data); g_list_free_full(title, &g_free); } else { caption = g_path_get_basename(img->filename); (g_strrstr(caption,"."))[0]='\0'; // chop extension... } GList *desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { description = desc->data; } dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_flickr] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } #ifdef _OPENMP #pragma omp critical #endif { //TODO: Check if this could be done in threads, so we enhance export time by using // upload time for one image to export another image to disk. // Upload image // Do we export tags? if( p->export_tags == TRUE ) tags = imgid; photo_status = _flickr_api_upload_photo( p, fname, caption, description, tags ); } if( !photo_status ) { result=0; goto cleanup; } // int fail = 0; // A photoset is only created if we have an album title set if( p->flickr_api->current_album == NULL && p->flickr_api->new_album == TRUE) { char *photoset_id; photoset_id = _flickr_api_create_photoset(p->flickr_api, photo_status->photoid); if( photoset_id == NULL) { dt_control_log("failed to create flickr album"); // fail = 1; } else { // p->flickr_api->new_album = FALSE; p->flickr_api->current_album = flickcurl_photosets_getInfo(p->flickr_api->fc,photoset_id); } } // if(fail) return 1; // TODO: What to do if photoset creation fails? // Add to gallery, if needed if (p->flickr_api->current_album != NULL && p->flickr_api->new_album != TRUE) { flickcurl_photosets_addPhoto (p->flickr_api->fc, p->flickr_api->current_album->id, photo_status->photoid); // TODO: Check for errors adding photo to gallery } else { if (p->flickr_api->current_album != NULL && p->flickr_api->new_album == TRUE) { p->flickr_api->new_album = FALSE; } } cleanup: // And remove from filesystem.. unlink( fname ); g_free( caption ); if(desc) g_list_free_full(desc, &g_free); if (result) { //this makes sense only if the export was successful dt_control_log(_("%d/%d exported to flickr webalbum"), num, total ); } return result; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale) { dt_imageio_gallery_t *d = (dt_imageio_gallery_t *)sdata; char filename[PATH_MAX] = { 0 }; char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { char tmp_dir[PATH_MAX] = { 0 }; d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); gchar *result_tmp_dir = dt_variables_get_result(d->vp); g_strlcpy(tmp_dir, result_tmp_dir, sizeof(tmp_dir)); g_free(result_tmp_dir); // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if(g_file_test(tmp_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename + strlen(d->filename) - 1)[0] == '/' || (d->filename + strlen(d->filename) - 1)[0] == '\\')) snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "/$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "_$(SEQUENCE)"); } gchar *fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, sizeof(d->filename)); g_free(fixed_path); dt_variables_expand(d->vp, d->filename, TRUE); gchar *result_filename = dt_variables_get_result(d->vp); g_strlcpy(filename, result_filename, sizeof(filename)); g_free(result_filename); g_strlcpy(dirname, filename, sizeof(dirname)); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c > dirname && *c != '/'; c--) ; if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_gallery] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); return 1; } // store away dir. snprintf(d->cached_dirname, sizeof(d->cached_dirname), "%s", dirname); c = filename + strlen(filename); for(; c > filename && *c != '.' && *c != '/'; c--) ; if(c <= filename || *c == '/') c = filename + strlen(filename); sprintf(c, ".%s", ext); // save image to list, in order: pair_t *pair = malloc(sizeof(pair_t)); char *title = NULL, *description = NULL; GList *res_title, *res_desc; res_title = dt_metadata_get(imgid, "Xmp.dc.title", NULL); if(res_title) { title = res_title->data; } res_desc = dt_metadata_get(imgid, "Xmp.dc.description", NULL); if(res_desc) { description = res_desc->data; } char relfilename[PATH_MAX] = { 0 }, relthumbfilename[PATH_MAX] = { 0 }; c = filename + strlen(filename); for(; c > filename && *c != '/'; c--) ; if(*c == '/') c++; if(c <= filename) c = filename; snprintf(relfilename, sizeof(relfilename), "%s", c); snprintf(relthumbfilename, sizeof(relthumbfilename), "%s", relfilename); c = relthumbfilename + strlen(relthumbfilename); for(; c > relthumbfilename && *c != '.'; c--) ; if(c <= relthumbfilename) c = relthumbfilename + strlen(relthumbfilename); sprintf(c, "-thumb.%s", ext); char subfilename[PATH_MAX] = { 0 }, relsubfilename[PATH_MAX] = { 0 }; snprintf(subfilename, sizeof(subfilename), "%s", d->cached_dirname); char *sc = subfilename + strlen(subfilename); sprintf(sc, "/img_%d.html", num); snprintf(relsubfilename, sizeof(relsubfilename), "img_%d.html", num); snprintf(pair->line, sizeof(pair->line), "\n" " <div><a class=\"dia\" rel=\"lightbox[viewer]\" title=\"%s - %s\" " "href=\"%s\"><span></span><img src=\"%s\" alt=\"img%d\" class=\"img\"/></a>\n" " <h1>%s</h1>\n" " %s</div>\n", title ? title : relfilename, description ? description : " ", relfilename, relthumbfilename, num, title ? title : " ", description ? description : " "); char next[PATH_MAX] = { 0 }; snprintf(next, sizeof(next), "img_%d.html", (num) % total + 1); char prev[PATH_MAX] = { 0 }; snprintf(prev, sizeof(prev), "img_%d.html", (num == 1) ? total : num - 1); pair->pos = num; if(res_title) g_list_free_full(res_title, &g_free); if(res_desc) g_list_free_full(res_desc, &g_free); d->l = g_list_insert_sorted(d->l, pair, (GCompareFunc)sort_pos); } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality, upscale, FALSE, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } /* also export thumbnail: */ // write with reduced resolution: const int max_width = fdata->max_width; const int max_height = fdata->max_height; fdata->max_width = 200; fdata->max_height = 200; // alter filename with -thumb: char *c = filename + strlen(filename); for(; c > filename && *c != '.' && *c != '/'; c--) ; if(c <= filename || *c == '/') c = filename + strlen(filename); const char *ext = format->extension(fdata); sprintf(c, "-thumb.%s", ext); if(dt_imageio_export(imgid, filename, format, fdata, FALSE, TRUE, FALSE, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } // restore for next image: fdata->max_width = max_width; fdata->max_height = max_height; printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); return 0; }
/* this actually does the work */ int store(dt_imageio_module_storage_t *self, struct dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { gint result = 1; dt_storage_facebook_param_t *p = (dt_storage_facebook_param_t*)sdata; const char *ext = format->extension(fdata); char fname[4096]= {0}; dt_loc_get_tmp_dir(fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); gint fd=g_mkstemp(fname); if(fd==-1) { dt_control_log("failed to create temporary image for facebook export"); return 1; } close(fd); //get metadata const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); char *caption = NULL; GList *title = NULL; GList *desc = NULL; title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); if(title != NULL) { caption = title->data; } if (caption == NULL) { desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { caption = desc->data; } } dt_image_cache_read_release(darktable.image_cache, img); //facebook doesn't allow pictures bigger than FB_IMAGE_MAX_SIZExFB_IMAGE_MAX_SIZE px if (fdata->max_height == 0 || fdata->max_height > FB_IMAGE_MAX_SIZE) fdata->max_height = FB_IMAGE_MAX_SIZE; if (fdata->max_width == 0 || fdata->max_width > FB_IMAGE_MAX_SIZE) fdata->max_width = FB_IMAGE_MAX_SIZE; if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { g_printerr("[facebook] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } if (p->facebook_ctx->album_id == NULL) { if (p->facebook_ctx->album_title == NULL) { dt_control_log(_("unable to create album, no title provided")); result = 0; goto cleanup; } const gchar *album_id = fb_create_album(p->facebook_ctx, p->facebook_ctx->album_title, p->facebook_ctx->album_summary, p->facebook_ctx->album_permission); if (album_id == NULL) { dt_control_log(_("unable to create album")); result = 0; goto cleanup; } p->facebook_ctx->album_id = g_strdup(album_id); } const char *photoid = fb_upload_photo_to_album(p->facebook_ctx, p->facebook_ctx->album_id, fname, caption); if (photoid == NULL) { dt_control_log(_("unable to export photo to webalbum")); result = 0; goto cleanup; } cleanup: unlink( fname ); g_free( caption ); if(desc) { //no need to free desc->data as caption points to it g_list_free(desc); } if (result) { //this makes sense only if the export was successful dt_control_log(_("%d/%d exported to facebook webalbum"), num, total ); } return 0; }
static int store_wrapper(struct dt_imageio_module_storage_t *self, struct dt_imageio_module_data_t *self_data, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale) { /* construct a temporary file name */ char tmpdir[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_loc_get_tmp_dir(tmpdir, sizeof(tmpdir)); char dirname[PATH_MAX] = { 0 }; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); dt_image_path_append_version(imgid, dirname, sizeof(dirname)); gchar *filename = g_path_get_basename(dirname); gchar *end = g_strrstr(filename, ".") + 1; g_strlcpy(end, format->extension(fdata), sizeof(dirname) - (end - dirname)); gchar *complete_name = g_build_filename(tmpdir, filename, (char *)NULL); if(dt_imageio_export(imgid, complete_name, format, fdata, high_quality, upscale, FALSE, self, self_data, num, total) != 0) { fprintf(stderr, "[%s] could not export to file: `%s'!\n", self->name(self), complete_name); g_free(complete_name); g_free(filename); return 1; } lua_storage_t *d = (lua_storage_t *)self_data; dt_lua_lock(); lua_State *L = darktable.lua_state.state; push_lua_data(L,d); dt_lua_goto_subtable(L,"files"); luaA_push(L, dt_lua_image_t, &(imgid)); lua_pushstring(L, complete_name); lua_settable(L, -3); lua_pop(L,1); lua_getfield(L, LUA_REGISTRYINDEX, "dt_lua_storages"); lua_getfield(L, -1, self->plugin_name); lua_getfield(L, -1, "store"); if(lua_isnil(L, -1)) { lua_pop(L, 3); dt_lua_unlock(); g_free(filename); return 0; } luaA_push_type(L, self->parameter_lua_type, self_data); luaA_push(L, dt_lua_image_t, &imgid); luaA_push_type(L, format->parameter_lua_type, fdata); lua_pushstring(L, complete_name); lua_pushnumber(L, num); lua_pushnumber(L, total); lua_pushboolean(L, high_quality); push_lua_data(L,d); dt_lua_goto_subtable(L,"extra"); dt_lua_treated_pcall(L,8,0); lua_pop(L, 2); dt_lua_unlock(); g_free(filename); return false; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale) { dt_imageio_latex_t *d = (dt_imageio_latex_t *)sdata; char filename[PATH_MAX] = { 0 }; char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { // if filenamepattern is a directory just add ${FILE_NAME} as default.. if(g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename + strlen(d->filename))[0] == '/' || (d->filename + strlen(d->filename))[0] == '\\')) snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "_$(SEQUENCE)"); } gchar *fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, sizeof(d->filename)); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); gchar *result_filename = dt_variables_get_result(d->vp); g_strlcpy(filename, result_filename, sizeof(filename)); g_free(result_filename); g_strlcpy(dirname, filename, sizeof(dirname)); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c > dirname && *c != '/'; c--) ; if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_latex] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); return 1; } // store away dir. snprintf(d->cached_dirname, sizeof(d->cached_dirname), "%s", dirname); c = filename + strlen(filename); // for(; c>filename && *c != '.' && *c != '/' ; c--); // if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c, ".%s", ext); // save image to list, in order: pair_t *pair = malloc(sizeof(pair_t)); #if 0 // let's see if we actually want titles and such to be exported: char *title = NULL, *description = NULL, *tags = NULL; GList *res_title, *res_desc, *res_subj; res_title = dt_metadata_get(imgid, "Xmp.dc.title", NULL); if(res_title) { title = res_title->data; } res_desc = dt_metadata_get(imgid, "Xmp.dc.description", NULL); if(res_desc) { description = res_desc->data; } res_subj = dt_metadata_get(imgid, "Xmp.dc.subject", NULL); if(res_subj) { // don't show the internal tags (darktable|...) res_subj = g_list_first(res_subj); GList *iter = res_subj; while(iter) { GList *next = g_list_next(iter); if(g_str_has_prefix(iter->data, "darktable|")) { g_free(iter->data); res_subj = g_list_delete_link(res_subj, iter); } iter = next; } tags = dt_util_glist_to_str(", ", res_subj); g_list_free_full(res_subj, g_free); } #endif char relfilename[PATH_MAX] = { 0 }; c = filename + strlen(filename); for(; c > filename && *c != '/'; c--) ; if(*c == '/') c++; if(c <= filename) c = filename; snprintf(relfilename, sizeof(relfilename), "%s", c); snprintf(pair->line, sizeof(pair->line), "\\begin{minipage}{\\imgwidth}%%\n" "\\drawtrimcorners%%\n" "\\vskip0pt plus 1filll\n" "\\begin{minipage}{\\imgwidth}%%\n" " \\hfil\\includegraphics[width=\\imgwidth,height=\\imgheight,keepaspectratio]{%s}\\hfil\n" " %% put text under image here\n" "\\end{minipage}\n" "\\end{minipage}\n" "\\newpage\n\n", relfilename); pair->pos = num; // g_list_free_full(res_title, &g_free); // g_list_free_full(res_desc, &g_free); // g_list_free_full(res_subj, &g_free); // g_free(tags); d->l = g_list_insert_sorted(d->l, pair, (GCompareFunc)sort_pos); } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* export image to file */ dt_imageio_export(imgid, filename, format, fdata, high_quality, upscale, FALSE, self, sdata, num, total); printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); return 0; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent) { dt_storage_piwigo_gui_data_t *ui = self->gui_data; gint result = 0; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(fname, sizeof(fname)); g_strlcat(fname, "/darktable.XXXXXX.", sizeof(fname)); g_strlcat(fname, ext, sizeof(fname)); char *caption = NULL; char *description = NULL; char *author = NULL; gint fd = g_mkstemp(fname); if(fd == -1) { dt_control_log("failed to create temporary image for piwigo export"); fprintf(stderr, "failed to create tempfile: %s\n", fname); return 1; } close(fd); const dt_image_t *img = dt_image_cache_get(darktable.image_cache, imgid, 'r'); // If title is not existing, then use the filename without extension. If not, then use title instead GList *title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); if(title != NULL) { caption = g_strdup(title->data); g_list_free_full(title, &g_free); } else { caption = g_path_get_basename(img->filename); (g_strrstr(caption, "."))[0] = '\0'; // chop extension... } GList *desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { description = g_strdup(desc->data); g_list_free_full(desc, &g_free); } dt_image_cache_read_release(darktable.image_cache, img); GList *auth = dt_metadata_get(img->id, "Xmp.dc.creator", NULL); if(auth != NULL) { author = g_strdup(auth->data); g_list_free_full(auth, &g_free); } if(dt_imageio_export(imgid, fname, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_piwigo] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 1; goto cleanup; } dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { gboolean status = TRUE; dt_storage_piwigo_params_t *p = (dt_storage_piwigo_params_t *)sdata; if(p->export_tags) { GList *tags_list = dt_tag_get_list(imgid); if(p->tags) g_free(p->tags); p->tags = dt_util_glist_to_str(",", tags_list); g_list_free_full(tags_list, g_free); } if(p->new_album) { status = _piwigo_api_create_new_album(p); if(!status) dt_control_log(_("cannot create a new piwigo album!")); } if(status) { status = _piwigo_api_upload_photo(p, fname, author, caption, description); if(!status) { fprintf(stderr, "[imageio_storage_piwigo] could not upload to piwigo!\n"); dt_control_log(_("could not upload to piwigo!")); result = 1; } else if (p->new_album) { // we do not want to create more albums when multiple upload p->new_album = FALSE; _piwigo_refresh_albums(ui, p->album); } } } dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); cleanup: // And remove from filesystem.. g_unlink(fname); g_free(caption); g_free(description); g_free(author); if(!result) { // this makes sense only if the export was successful dt_control_log(ngettext("%d/%d exported to piwigo webalbum", "%d/%d exported to piwigo webalbum", num), num, total); } return result; }
/* this actually does the work */ int store(dt_imageio_module_storage_t *self, struct dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent) { dt_storage_gphoto_gui_data_t *ui = self->gui_data; gint result = 1; dt_gphoto_context_t *ctx = (dt_gphoto_context_t *)sdata; const char *ext = format->extension(fdata); char fname[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(fname, sizeof(fname)); g_strlcat(fname, "/darktable.XXXXXX.", sizeof(fname)); g_strlcat(fname, ext, sizeof(fname)); gint fd = g_mkstemp(fname); if(fd == -1) { dt_control_log("failed to create temporary image for google photos export"); return 1; } close(fd); // get metadata const dt_image_t *img = dt_image_cache_get(darktable.image_cache, imgid, 'r'); char *title = NULL; char *summary = NULL; GList *meta_title = NULL; title = g_path_get_basename(img->filename); (g_strrstr(title, "."))[0] = '\0'; // Chop extension... meta_title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); summary = meta_title != NULL ? meta_title->data : ""; dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { g_printerr("[gphoto] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } if(!*(ctx->album_id)) { if(ctx->album_title == NULL) { dt_control_log(_("unable to create album, no title provided")); result = 0; goto cleanup; } const gchar *album_id = gphoto_create_album(ui, ctx, ctx->album_title); if(album_id == NULL) { dt_control_log(_("unable to create album")); result = 0; goto cleanup; } g_snprintf(ctx->album_id, sizeof(ctx->album_id), "%s", album_id); } const char *photoid = gphoto_upload_photo_to_album(ctx, ctx->album_id, fname, title, summary, imgid); if(photoid == NULL) { dt_control_log(_("unable to export to google photos album")); result = 0; goto cleanup; } cleanup: g_unlink(fname); g_free(title); g_list_free_full(meta_title, &g_free); if(result) { // this makes sense only if the export was successful dt_control_log(ngettext("%d/%d exported to google photos album", "%d/%d exported to google photos album", num), num, total); } return 0; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent) { dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata; char filename[PATH_MAX] = { 0 }; char input_dir[PATH_MAX] = { 0 }; char pattern[DT_MAX_PATH_FOR_PARAMS]; g_strlcpy(pattern, d->filename, sizeof(pattern)); gboolean from_cache = FALSE; dt_image_full_path(imgid, input_dir, sizeof(input_dir), &from_cache); int fail = 0; // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { try_again: // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(pattern, "$")) { snprintf(pattern + strlen(pattern), sizeof(pattern) - strlen(pattern), "_$(SEQUENCE)"); } gchar *fixed_path = dt_util_fix_path(pattern); g_strlcpy(pattern, fixed_path, sizeof(pattern)); g_free(fixed_path); d->vp->filename = input_dir; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; gchar *result_filename = dt_variables_expand(d->vp, pattern, TRUE); g_strlcpy(filename, result_filename, sizeof(filename)); g_free(result_filename); // if filenamepattern is a directory just add ${FILE_NAME} as default.. // this can happen if the filename component of the pattern is an empty variable char last_char = *(filename + strlen(filename) - 1); if(last_char == '/' || last_char == '\\') { // add to the end of the original pattern without caring about a // potentially added "_$(SEQUENCE)" if (snprintf(pattern, sizeof(pattern), "%s" G_DIR_SEPARATOR_S "$(FILE_NAME)", d->filename) < sizeof(pattern)) goto try_again; } char *output_dir = g_path_get_dirname(filename); if(g_mkdir_with_parents(output_dir, 0755)) { fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", output_dir); dt_control_log(_("could not create directory `%s'!"), output_dir); fail = 1; goto failed; } if(g_access(output_dir, W_OK | X_OK) != 0) { fprintf(stderr, "[imageio_storage_disk] could not write to directory: `%s'!\n", output_dir); dt_control_log(_("could not write to directory `%s'!"), output_dir); fail = 1; goto failed; } const char *ext = format->extension(fdata); char *c = filename + strlen(filename); size_t filename_free_space = sizeof(filename) - (c - filename); snprintf(c, filename_free_space, ".%s", ext); /* prevent overwrite of files */ failed: g_free(output_dir); if(!fail && !d->overwrite) { int seq = 1; while(g_file_test(filename, G_FILE_TEST_EXISTS)) { snprintf(c, filename_free_space, "_%.2d.%s", seq, ext); seq++; } } } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); if(fail) return 1; /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality, upscale, TRUE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_disk] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } printf("[export_job] exported to `%s'\n", filename); dt_control_log(ngettext("%d/%d exported to `%s'", "%d/%d exported to `%s'", num), num, total, filename); return 0; }
int store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { gint tags = 0; int result=1; dt_storage_picasa_params_t *p=(dt_storage_picasa_params_t *)sdata; int fail = 0; #ifdef _OPENMP // synch parallel store #pragma omp critical #endif if( p->picasa_api->current_album == NULL ) if( _picasa_api_create_album( p->picasa_api ) != 201 ) { dt_control_log("failed to create picasa album"); fail = 1; } if(fail) return 1; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[4096]= {0}; dt_loc_get_tmp_dir (fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); char *caption="a image"; char *description=""; char *mime="image/jpeg"; // Ok, maybe a dt_imageio_export_to_buffer would suit here !? gint fd=g_mkstemp(fname); fprintf(stderr,"tempfile: %s\n",fname); if(fd==-1) { dt_control_log("failed to create temporary image for picasa export"); return 1; } close(fd); const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); caption = g_path_get_basename( img->filename ); (g_strrstr(caption,"."))[0]='\0'; // Shop extension... GList *desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { description = desc->data; } dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_picasa] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 1; goto cleanup; } // Open the temp file and read image to memory GMappedFile *imgfile = g_mapped_file_new(fname,FALSE,NULL); int size = g_mapped_file_get_length( imgfile ); gchar *data =g_mapped_file_get_contents( imgfile ); #ifdef _OPENMP #pragma omp critical #endif { // Fetch the attached tags of image id if exported.. if( p->export_tags == TRUE ) tags = imgid; // Upload image to picasa if( _picasa_api_upload_photo( p->picasa_api, mime , data, size , caption, description, tags ) == 201 ) result=0; } // Unreference the memorymapped file... g_mapped_file_unref( imgfile ); // And remove from filesystem.. unlink( fname ); cleanup: g_free( caption ); if(desc) { g_free(desc->data); g_list_free(desc); } if(!result) dt_control_log(_("%d/%d exported to picasa webalbum"), num, total ); return result; }
int store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { dt_imageio_gallery_t *d = (dt_imageio_gallery_t *)sdata; char filename[DT_MAX_PATH_LEN]= {0}; char dirname[DT_MAX_PATH_LEN]= {0}; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { char tmp_dir[DT_MAX_PATH_LEN]; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(tmp_dir, dt_variables_get_result(d->vp), DT_MAX_PATH_LEN); // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if ( g_file_test(tmp_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename)-1)[0]=='/' || (d->filename+strlen(d->filename)-1)[0]=='\\') ) snprintf (d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "/$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "_$(SEQUENCE)"); } gchar* fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, DT_MAX_PATH_LEN); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(filename, dt_variables_get_result(d->vp), DT_MAX_PATH_LEN); g_strlcpy(dirname, filename, DT_MAX_PATH_LEN); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c>dirname && *c != '/'; c--); if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_gallery] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); return 1; } // store away dir. snprintf(d->cached_dirname, DT_MAX_PATH_LEN, "%s", dirname); c = filename + strlen(filename); for(; c>filename && *c != '.' && *c != '/' ; c--); if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c,".%s",ext); // save image to list, in order: pair_t *pair = malloc(sizeof(pair_t)); char *title = NULL, *description = NULL, *tags = NULL; GList *res; res = dt_metadata_get(imgid, "Xmp.dc.title", NULL); if(res) { title = res->data; g_list_free(res); } res = dt_metadata_get(imgid, "Xmp.dc.description", NULL); if(res) { description = res->data; g_list_free(res); } unsigned int count = 0; res = dt_metadata_get(imgid, "Xmp.dc.subject", &count); if(res) { // don't show the internal tags (darktable|...) res = g_list_first(res); GList *iter = res; while(iter) { GList *next = g_list_next(iter); if(g_str_has_prefix(iter->data, "darktable|")) { g_free(iter->data); res = g_list_delete_link(res, iter); count--; } iter = next; } tags = dt_util_glist_to_str(", ", res, count); } char relfilename[256], relthumbfilename[256]; c = filename + strlen(filename); for(; c>filename && *c != '/' ; c--); if(*c == '/') c++; if(c <= filename) c = filename; snprintf(relfilename, 256, "%s", c); snprintf(relthumbfilename, 256, "%s", relfilename); c = relthumbfilename + strlen(relthumbfilename); for(; c>relthumbfilename && *c != '.'; c--); if(c <= relthumbfilename) c = relthumbfilename + strlen(relthumbfilename); sprintf(c, "-thumb.%s", ext); char subfilename[DT_MAX_PATH_LEN], relsubfilename[256]; snprintf(subfilename, DT_MAX_PATH_LEN, "%s", d->cached_dirname); char* sc = subfilename + strlen(subfilename); sprintf(sc, "/img_%d.html", num); sprintf(relsubfilename, "img_%d.html", num); snprintf(pair->line, 4096, "\n" " <div><a class=\"dia\" rel=\"lightbox[viewer]\" title=\"%s - %s\" href=\"%s\"><span></span><img src=\"%s\" alt=\"img%d\" class=\"img\"/></a>\n" " <h1>%s</h1>\n" " %s<br/><span class=\"tags\">%s</span></div>\n", title?title:relfilename, description?description:" ", relfilename, relthumbfilename, num, title?title:" ", description?description:" ", tags?tags:" "); char next[256]; sprintf(next, "img_%d.html", (num)%total+1); char prev[256]; sprintf(prev, "img_%d.html", (num==1)?total:num-1); /* Becomes unecessary with the Lightbox image viewer overlay FILE* subfile = fopen(subfilename, "wb"); fprintf(subfile, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" " <head>\n" " <meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n" " <link rel=\"shortcut icon\" href=\"style/favicon.ico\" />\n" " <link rel=\"stylesheet\" href=\"style/style.css\" type=\"text/css\" />\n" " <title>%s</title>\n" " </head>\n" " <body>\n" " <div class=\"title\"><a href=\"index.html\">%s</a></div>\n" " <div class=\"page\">\n" " <div style=\"width: 692px; max-width: 692px; height: 10px;\">\n" " <a style=\"float: left;\" href=\"%s\"><h1>prev</h1></a>\n" " <a style=\"float: right;\"href=\"%s\"><h1>next</h1></a>\n" " </div>\n" " <a href=\"%s\"><img src=\"%s\" width=\"692\" class=\"img\"/></a>\n" " %s<br/><span class=\"tags\">%s</span></div>\n" " <p style=\"clear:both;\"></p>\n" " </div>\n" " <div class=\"footer\">\n" " created with darktable "PACKAGE_VERSION"\n" " </div>\n" " </body>\n" "</html>\n", relfilename, title?title:relfilename, prev, next, relfilename, relfilename, description?description:" ", tags?tags:" "); fclose(subfile); */ pair->pos = num; g_free(title); g_free(description); g_free(tags); d->l = g_list_insert_sorted(d->l, pair, (GCompareFunc)sort_pos); } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } /* also export thumbnail: */ // write with reduced resolution: const int max_width = fdata->max_width; const int max_height = fdata->max_height; fdata->max_width = 200; fdata->max_height = 200; // alter filename with -thumb: char *c = filename + strlen(filename); for(; c>filename && *c != '.' && *c != '/' ; c--); if(c <= filename || *c=='/') c = filename + strlen(filename); const char *ext = format->extension(fdata); sprintf(c,"-thumb.%s",ext); if(dt_imageio_export(imgid, filename, format, fdata, FALSE) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } // restore for next image: fdata->max_width = max_width; fdata->max_height = max_height; printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); return 0; }
int store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total) { dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata; char filename[1024]= {0}; char dirname[1024]= {0}; dt_image_full_path(imgid, dirname, 1024); int fail = 0; // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if ( g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename))[0]=='/' || (d->filename+strlen(d->filename))[0]=='\\') ) snprintf (d->filename+strlen(d->filename), 1024-strlen(d->filename), "$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename+strlen(d->filename), 1024-strlen(d->filename), "_$(SEQUENCE)"); } gchar* fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, 1024); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(filename, dt_variables_get_result(d->vp), 1024); g_strlcpy(dirname, filename, 1024); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c>dirname && *c != '/'; c--); if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); fail = 1; goto failed; } c = filename + strlen(filename); for(; c>filename && *c != '.' && *c != '/' ; c--); if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c,".%s",ext); /* prevent overwrite of files */ int seq=1; failed: if (!fail && g_file_test (filename,G_FILE_TEST_EXISTS)) { do { sprintf(c,"_%.2d.%s",seq,ext); seq++; } while (g_file_test (filename,G_FILE_TEST_EXISTS)); } } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); if(fail) return 1; /* export image to file */ dt_imageio_export(imgid, filename, format, fdata); /* now write xmp into that container, if possible */ dt_exif_xmp_attach(imgid, filename); printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); return 0; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale) { dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata; char filename[PATH_MAX] = { 0 }; char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); int fail = 0; // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if(g_file_test(d->filename, G_FILE_TEST_IS_DIR) || ((d->filename + strlen(d->filename))[0] == '/' || (d->filename + strlen(d->filename))[0] == '\\')) snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "_$(SEQUENCE)"); } gchar *fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, sizeof(d->filename)); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); gchar *result_filename = dt_variables_get_result(d->vp); g_strlcpy(filename, result_filename, sizeof(filename)); g_free(result_filename); g_strlcpy(dirname, filename, sizeof(dirname)); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c > dirname && *c != '/'; c--) ; if(*c == '/') { if(c > dirname) // /.../.../foo c[0] = '\0'; else // /foo c[1] = '\0'; } else if(c == dirname) // foo { c[0] = '.'; c[1] = '\0'; } if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); fail = 1; goto failed; } if(g_access(dirname, W_OK | X_OK) != 0) { fprintf(stderr, "[imageio_storage_disk] could not write to directory: `%s'!\n", dirname); dt_control_log(_("could not write to directory `%s'!"), dirname); fail = 1; goto failed; } c = filename + strlen(filename); // remove everything after the last '.'. this destroys any file name with dots in it since $(FILE_NAME) // already comes without the original extension. // for(; c>filename && *c != '.' && *c != '/' ; c--); // if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c, ".%s", ext); /* prevent overwrite of files */ failed: if(!d->overwrite) { int seq = 1; if(!fail && g_file_test(filename, G_FILE_TEST_EXISTS)) { do { sprintf(c, "_%.2d.%s", seq, ext); seq++; } while(g_file_test(filename, G_FILE_TEST_EXISTS)); } } } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); if(fail) return 1; /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality, upscale, TRUE, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_disk] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); return 0; }