/** * Queries a database for all entries matching a condition, * then fetches data from them. * * @param trans The transaction this query belongs to. * @param fs The fetchspec to use when fetching data * @param cond The condition to check entries against * @return A resultset with a row for every entry that matched */ s4_resultset_t *_s4_query ( s4_transaction_t *trans, s4_fetchspec_t *fs, s4_condition_t *cond) { check_data_t data; GList *entries; s4_index_t *index; s4_resultset_t *ret = s4_resultset_create (s4_fetchspec_size (fs)); s4_t *s4 = _transaction_get_db (trans); s4_cond_update_key (cond, s4); s4_fetchspec_update_key (s4, fs); if (s4_cond_is_filter (cond) && (s4_cond_get_flags (cond) & S4_COND_PARENT) && s4_cond_get_key (cond) != NULL) { index = _index_get_a (s4, s4_cond_get_key (cond), 0); if (index == NULL) { entries = NULL; } else { if (!_index_lock_shared (index, trans)) goto deadlocked; if (s4_cond_is_monotonic (cond)) { entries = _index_search (index, (index_function_t)s4_cond_get_filter_function (cond), cond); } else { entries = _index_lsearch (index, (index_function_t)s4_cond_get_filter_function (cond), cond); } } } else if (s4_cond_is_filter (cond) && s4_cond_get_key (cond) != NULL && (index = _index_get_b (s4, s4_cond_get_key (cond))) != NULL) { if (!_index_lock_shared (index, trans)) goto deadlocked; if (s4_cond_is_monotonic (cond)) { entries = _index_search (index, (index_function_t)s4_cond_get_filter_function (cond), cond); } else { entries = _index_lsearch (index, (index_function_t)s4_cond_get_filter_function (cond), cond); } } else { GList *indices; indices = _index_get_all_a (s4); for (entries = NULL; indices != NULL; indices = g_list_delete_link (indices, indices)) { if (!_index_lock_shared (indices->data, trans)) goto deadlocked; entries = g_list_concat (entries, _index_lsearch (indices->data, (index_function_t)_everything, NULL)); } } data.s4 = s4; for (; entries != NULL; entries = g_list_delete_link (entries, entries)) { entry_t *entry = entries->data; data.l = entry; if (!_entry_lock_shared (entry, trans)) goto deadlocked; if (entry->size != 0 && !_check_cond (cond, &data)) s4_resultset_add_row (ret, _fetch (s4, entry, fs)); } return ret; deadlocked: _transaction_set_deadlocked (trans); return ret; }
void owl_log_incoming(const owl_message *m) { char *filename, *allfilename, *logpath; const char *from=NULL; char *frombuff=NULL; int len, ch, i, personal; /* figure out if it's a "personal" message or not */ if (owl_message_is_type_zephyr(m)) { if (owl_message_is_personal(m)) { personal = 1; } else { personal = 0; } } else if (owl_message_is_type_jabber(m)) { /* This needs to be fixed to handle groupchat */ const char* msgtype = owl_message_get_attribute_value(m,"jtype"); if (msgtype && !strcmp(msgtype,"groupchat")) { personal = 0; } else { personal = 1; } } else { if (owl_message_is_private(m) || owl_message_is_loginout(m)) { personal = 1; } else { personal = 0; } } if (owl_message_is_type_zephyr(m)) { if (personal) { from=frombuff=short_zuser(owl_message_get_sender(m)); } else { from=frombuff=g_strdup(owl_message_get_class(m)); } } else if (owl_message_is_type_aim(m)) { /* we do not yet handle chat rooms */ char *normalto, *temp; temp = owl_aim_normalize_screenname(owl_message_get_sender(m)); normalto = g_utf8_strdown(temp, -1); from=frombuff=g_strdup_printf("aim:%s", normalto); g_free(normalto); g_free(temp); } else if (owl_message_is_type_loopback(m)) { from=frombuff=g_strdup("loopback"); } else if (owl_message_is_type_jabber(m)) { if (personal) { from=frombuff=g_strdup_printf("jabber:%s",owl_message_get_sender(m)); } else { from=frombuff=g_strdup_printf("jabber:%s",owl_message_get_recipient(m)); } } else { from=frombuff=g_strdup("unknown"); } /* check for malicious sender formats */ len=strlen(frombuff); if (len<1 || len>35) from="weird"; if (strchr(frombuff, '/')) from="weird"; ch=frombuff[0]; if (!g_ascii_isalnum(ch)) from="weird"; for (i=0; i<len; i++) { if (frombuff[i]<'!' || frombuff[i]>='~') from="weird"; } if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird"; if (!personal) { if (strcmp(from, "weird")) { char* temp = g_utf8_strdown(frombuff, -1); if (temp) { g_free(frombuff); from = frombuff = temp; } } } /* create the filename (expanding ~ in path names) */ if (personal) { logpath = owl_util_makepath(owl_global_get_logpath(&g)); filename = g_strdup_printf("%s/%s", logpath, from); allfilename = g_strdup_printf("%s/all", logpath); owl_log_append(m, allfilename); g_free(allfilename); } else { logpath = owl_util_makepath(owl_global_get_classlogpath(&g)); filename = g_strdup_printf("%s/%s", logpath, from); } owl_log_append(m, filename); g_free(filename); if (personal && owl_message_is_type_zephyr(m)) { /* We want to log to all of the CC'd people who were not us, or * the sender, as well. */ char *temp; GList *cc; cc = owl_message_get_cc_without_recipient(m); while (cc != NULL) { temp = short_zuser(cc->data); if (strcasecmp(temp, frombuff) != 0) { filename = g_strdup_printf("%s/%s", logpath, temp); owl_log_append(m, filename); g_free(filename); } g_free(temp); g_free(cc->data); cc = g_list_delete_link(cc, cc); } } g_free(frombuff); g_free(logpath); }
static void load_all_accounts (GncSqlBackend* be) { GncSqlStatement* stmt = NULL; GncSqlResult* result; QofBook* pBook; GList* l_accounts_needing_parents = NULL; GSList* bal_slist; GSList* bal; g_return_if_fail (be != NULL); ENTER (""); pBook = be->book; stmt = gnc_sql_create_select_statement (be, TABLE_NAME); if (stmt == NULL) { LEAVE ("stmt == NULL"); return; } result = gnc_sql_execute_select_statement (be, stmt); gnc_sql_statement_dispose (stmt); if (result != NULL) { GncSqlRow* row = gnc_sql_result_get_first_row (result); gchar* sql; while (row != NULL) { load_single_account (be, row, &l_accounts_needing_parents); row = gnc_sql_result_get_next_row (result); } gnc_sql_result_dispose (result); sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME); gnc_sql_slots_load_for_sql_subquery (be, sql, (BookLookupFn)xaccAccountLookup); g_free (sql); /* While there are items on the list of accounts needing parents, try to see if the parent has now been loaded. Theory says that if items are removed from the front and added to the back if the parent is still not available, then eventually, the list will shrink to size 0. */ if (l_accounts_needing_parents != NULL) { gboolean progress_made = TRUE; Account* root; Account* pParent; GList* elem; while (progress_made) { progress_made = FALSE; for (elem = l_accounts_needing_parents; elem != NULL;) { account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data; pParent = xaccAccountLookup (&s->guid, be->book); if (pParent != NULL) { GList* next_elem; gnc_account_append_child (pParent, s->pAccount); next_elem = g_list_next (elem); l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents, elem); g_free (s); elem = next_elem; progress_made = TRUE; } else { /* Can't be up in the for loop because the 'then' clause reads inside a node freed by g_list_delete_link(). */ elem = g_list_next (elem); } } } /* Any non-ROOT accounts left over must be parented by the root account */ root = gnc_book_get_root_account (pBook); while (l_accounts_needing_parents != NULL) { account_parent_guid_struct* s = (account_parent_guid_struct*) l_accounts_needing_parents->data; if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT) { gnc_account_append_child (root, s->pAccount); } g_free (s); l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents, l_accounts_needing_parents); } } /* Load starting balances */ bal_slist = gnc_sql_get_account_balances_slist (be); for (bal = bal_slist; bal != NULL; bal = bal->next) { acct_balances_t* balances = (acct_balances_t*)bal->data; qof_instance_increase_editlevel (balances->acct); g_object_set (balances->acct, "start-balance", &balances->balance, "start-cleared-balance", &balances->cleared_balance, "start-reconciled-balance", &balances->reconciled_balance, NULL); qof_instance_decrease_editlevel (balances->acct); } if (bal_slist != NULL) { g_slist_free (bal_slist); } } LEAVE (""); }
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_gallery_t *d = (dt_imageio_gallery_t *)sdata; char filename[1024]= {0}; char dirname[1024]= {0}; dt_image_full_path(imgid, dirname, 1024); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { char tmp_dir[1024]; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(tmp_dir, dt_variables_get_result(d->vp), 1024); // 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), 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_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, 1024, "%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[1024], relsubfilename[256]; snprintf(subfilename, 1024, "%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) != 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) != 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; }
static void preferences_themes_setup (EmpathyPreferences *preferences) { EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkComboBox *combo; GtkCellLayout *cell_layout; GtkCellRenderer *renderer; GtkListStore *store; const gchar **themes; GList *adium_themes; gint i; preferences_theme_variants_setup (preferences); combo = GTK_COMBO_BOX (priv->combobox_chat_theme); cell_layout = GTK_CELL_LAYOUT (combo); /* Create the model */ store = gtk_list_store_new (COL_THEME_COUNT, G_TYPE_STRING, /* Display name */ G_TYPE_STRING, /* Theme name */ G_TYPE_BOOLEAN, /* Is an Adium theme */ G_TYPE_STRING, /* Adium theme path */ G_TYPE_HASH_TABLE); /* Adium theme info */ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_THEME_VISIBLE_NAME, GTK_SORT_ASCENDING); /* Fill the model */ themes = empathy_theme_manager_get_themes (); for (i = 0; themes[i]; i += 2) { gtk_list_store_insert_with_values (store, NULL, -1, COL_THEME_VISIBLE_NAME, _(themes[i + 1]), COL_THEME_NAME, themes[i], COL_THEME_IS_ADIUM, FALSE, -1); } adium_themes = empathy_theme_manager_get_adium_themes (); while (adium_themes != NULL) { GHashTable *info; const gchar *name; const gchar *path; info = adium_themes->data; name = tp_asv_get_string (info, "CFBundleName"); path = tp_asv_get_string (info, "path"); if (name != NULL && path != NULL) { gtk_list_store_insert_with_values (store, NULL, -1, COL_THEME_VISIBLE_NAME, name, COL_THEME_NAME, "adium", COL_THEME_IS_ADIUM, TRUE, COL_THEME_ADIUM_PATH, path, COL_THEME_ADIUM_INFO, info, -1); } g_hash_table_unref (info); adium_themes = g_list_delete_link (adium_themes, adium_themes); } /* Add cell renderer */ renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); gtk_cell_layout_set_attributes (cell_layout, renderer, "text", COL_THEME_VISIBLE_NAME, NULL); gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); g_object_unref (store); g_signal_connect (combo, "changed", G_CALLBACK (preferences_theme_changed_cb), preferences); /* Select the theme from the GSetting key and track changes */ preferences_theme_notify_cb (priv->gsettings_chat, EMPATHY_PREFS_CHAT_THEME, preferences); g_signal_connect (priv->gsettings_chat, "changed::" EMPATHY_PREFS_CHAT_THEME, G_CALLBACK (preferences_theme_notify_cb), preferences); g_signal_connect (priv->gsettings_chat, "changed::" EMPATHY_PREFS_CHAT_ADIUM_PATH, G_CALLBACK (preferences_theme_notify_cb), preferences); }
static void test_merge_regions () { /* logarithmically distributed random number of struts (range?) * logarithmically distributed random size of struts (up to screen size???) * uniformly distributed location of center of struts (within screen) * merge all regions that are possible * print stats on problem setup * number of (non-completely-occluded?) struts * percentage of screen covered * length of resulting non-minimal spanning set * length of resulting minimal spanning set * print stats on merged regions: * number boxes merged * number of those merges that were of the form A contains B * number of those merges that were of the form A partially contains B * number of those merges that were of the form A is adjacent to B */ GList* region; GList* compare; int num_contains, num_merged, num_part_contains, num_adjacent; num_contains = num_merged = num_part_contains = num_adjacent = 0; compare = region = get_screen_region (2); g_assert (region); printf ("Merging stats:\n"); printf (" Length of initial list: %d\n", g_list_length (region)); #ifdef PRINT_DEBUG char rect1[RECT_LENGTH], rect2[RECT_LENGTH]; char region_list[(RECT_LENGTH + 2) * g_list_length (region)]; meta_rectangle_region_to_string (region, ", ", region_list); printf (" Initial rectangles: %s\n", region_list); #endif while (compare && compare->next) { MetaRectangle *a = compare->data; GList *other = compare->next; g_assert (a->width > 0 && a->height > 0); while (other) { MetaRectangle *b = other->data; GList *delete_me = NULL; g_assert (b->width > 0 && b->height > 0); #ifdef PRINT_DEBUG printf (" -- Comparing %s to %s --\n", meta_rectangle_to_string (a, rect1), meta_rectangle_to_string (b, rect2)); #endif /* If a contains b, just remove b */ if (meta_rectangle_contains_rect (a, b)) { delete_me = other; num_contains++; num_merged++; } /* If b contains a, just remove a */ else if (meta_rectangle_contains_rect (a, b)) { delete_me = compare; num_contains++; num_merged++; } /* If a and b might be mergeable horizontally */ else if (a->y == b->y && a->height == b->height) { /* If a and b overlap */ if (meta_rectangle_overlap (a, b)) { int new_x = MIN (a->x, b->x); a->width = MAX (a->x + a->width, b->x + b->width) - new_x; a->x = new_x; delete_me = other; num_part_contains++; num_merged++; } /* If a and b are adjacent */ else if (a->x + a->width == b->x || a->x == b->x + b->width) { int new_x = MIN (a->x, b->x); a->width = MAX (a->x + a->width, b->x + b->width) - new_x; a->x = new_x; delete_me = other; num_adjacent++; num_merged++; } } /* If a and b might be mergeable vertically */ else if (a->x == b->x && a->width == b->width) { /* If a and b overlap */ if (meta_rectangle_overlap (a, b)) { int new_y = MIN (a->y, b->y); a->height = MAX (a->y + a->height, b->y + b->height) - new_y; a->y = new_y; delete_me = other; num_part_contains++; num_merged++; } /* If a and b are adjacent */ else if (a->y + a->height == b->y || a->y == b->y + b->height) { int new_y = MIN (a->y, b->y); a->height = MAX (a->y + a->height, b->y + b->height) - new_y; a->y = new_y; delete_me = other; num_adjacent++; num_merged++; } } other = other->next; /* Delete any rectangle in the list that is no longer wanted */ if (delete_me != NULL) { #ifdef PRINT_DEBUG MetaRectangle *bla = delete_me->data; printf (" Deleting rect %s\n", meta_rectangle_to_string (bla, rect1)); #endif /* Deleting the rect we're compare others to is a little tricker */ if (compare == delete_me) { compare = compare->next; other = compare->next; a = compare->data; } /* Okay, we can free it now */ g_free (delete_me->data); region = g_list_delete_link (region, delete_me); } #ifdef PRINT_DEBUG char region_list[(RECT_LENGTH + 2) * g_list_length (region)]; meta_rectangle_region_to_string (region, ", ", region_list); printf (" After comparison, new list is: %s\n", region_list); #endif } compare = compare->next; } printf (" Num rectangles contained in others : %d\n", num_contains); printf (" Num rectangles partially contained in others: %d\n", num_part_contains); printf (" Num rectangles adjacent to others : %d\n", num_adjacent); printf (" Num rectangles merged with others : %d\n", num_merged); #ifdef PRINT_DEBUG char region_list2[(RECT_LENGTH + 2) * g_list_length (region)]; meta_rectangle_region_to_string (region, ", ", region_list2); printf (" Final rectangles: %s\n", region_list2); #endif meta_rectangle_free_spanning_set (region); region = NULL; printf ("%s passed.\n", G_STRFUNC); }
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job) { if(((unsigned int)queue_id) >= DT_JOB_QUEUE_MAX || !job) { dt_control_job_dispose(job); return 1; } job->queue = queue_id; dt_pthread_mutex_lock(&control->queue_mutex); GList **queue = &control->queues[queue_id]; size_t length = control->queue_length[queue_id]; #ifdef __WIN32__ dt_print(DT_DEBUG_CONTROL, "[add_job] %Id | ", length); #else dt_print(DT_DEBUG_CONTROL, "[add_job] %ld | ", length); #endif dt_control_job_print(job); dt_print(DT_DEBUG_CONTROL, "\n"); if(queue_id == DT_JOB_QUEUE_SYSTEM_FG) { // this is a stack with limited size and bubble up and all that stuff job->priority = DT_CONTROL_FG_PRIORITY; // if the job is already in the queue -> move it to the top for(GList *iter = *queue; iter; iter = g_list_next(iter)) { _dt_job_t *other_job = (_dt_job_t *)iter->data; if(dt_control_job_equal(job, other_job)) { dt_print(DT_DEBUG_CONTROL, "[add_job] found job already in queue: "); dt_control_job_print(job); dt_print(DT_DEBUG_CONTROL, "\n"); *queue = g_list_delete_link(*queue, iter); length--; dt_control_job_set_state(job, DT_JOB_STATE_DISCARDED); dt_control_job_dispose(job); job = other_job; break; // there can't be any further copy in the list } } // now we can add the new job to the list *queue = g_list_prepend(*queue, job); length++; // and take care of the maximal queue size if(length > DT_CONTROL_MAX_JOBS) { GList *last = g_list_last(*queue); dt_control_job_set_state((_dt_job_t *)last->data, DT_JOB_STATE_DISCARDED); dt_control_job_dispose((_dt_job_t *)last->data); *queue = g_list_delete_link(*queue, last); length--; } control->queue_length[queue_id] = length; } else { // the rest are FIFOs if(queue_id == DT_JOB_QUEUE_USER_BG || queue_id == DT_JOB_QUEUE_SYSTEM_BG) job->priority = 0; else job->priority = DT_CONTROL_FG_PRIORITY; *queue = g_list_append(*queue, job); control->queue_length[queue_id]++; } dt_control_job_set_state(job, DT_JOB_STATE_QUEUED); dt_pthread_mutex_unlock(&control->queue_mutex); // notify workers dt_pthread_mutex_lock(&control->cond_mutex); pthread_cond_broadcast(&control->cond); dt_pthread_mutex_unlock(&control->cond_mutex); return 0; }
void gtk_text_region_subtract (GtkTextRegion *region, const GtkTextIter *_start, const GtkTextIter *_end) { GList *start_node, *end_node, *node; GtkTextIter sr_start_iter, sr_end_iter; gboolean done; gboolean start_is_outside, end_is_outside; Subregion *sr; GtkTextIter start, end; g_return_if_fail (region != NULL && _start != NULL && _end != NULL); start = *_start; end = *_end; DEBUG (g_print ("---\n")); DEBUG (gtk_text_region_debug_print (region)); DEBUG (g_message ("region_substract (%d, %d)", gtk_text_iter_get_offset (&start), gtk_text_iter_get_offset (&end))); gtk_text_iter_order (&start, &end); /* find bounding subregions */ start_node = find_nearest_subregion (region, &start, NULL, FALSE, FALSE); end_node = find_nearest_subregion (region, &end, start_node, TRUE, FALSE); /* easy case first */ if (start_node == NULL || end_node == NULL || end_node == start_node->prev) return; /* deal with the start point */ start_is_outside = end_is_outside = FALSE; sr = start_node->data; gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); if (gtk_text_iter_in_range (&start, &sr_start_iter, &sr_end_iter) && !gtk_text_iter_equal (&start, &sr_start_iter)) { /* the starting point is inside the first subregion */ if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && !gtk_text_iter_equal (&end, &sr_end_iter)) { /* the ending point is also inside the first subregion: we need to split */ Subregion *new_sr = g_new0 (Subregion, 1); new_sr->end = sr->end; new_sr->start = gtk_text_buffer_create_mark (region->buffer, NULL, &end, TRUE); start_node = g_list_insert_before (start_node, start_node->next, new_sr); sr->end = gtk_text_buffer_create_mark (region->buffer, NULL, &start, FALSE); /* no further processing needed */ DEBUG (g_message ("subregion splitted")); return; } else { /* the ending point is outside, so just move the end of the subregion to the starting point */ gtk_text_buffer_move_mark (region->buffer, sr->end, &start); } } else { /* the starting point is outside (and so to the left) of the first subregion */ DEBUG (g_message ("start is outside")); start_is_outside = TRUE; } /* deal with the end point */ if (start_node != end_node) { sr = end_node->data; gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_start_iter, sr->start); gtk_text_buffer_get_iter_at_mark (region->buffer, &sr_end_iter, sr->end); } if (gtk_text_iter_in_range (&end, &sr_start_iter, &sr_end_iter) && !gtk_text_iter_equal (&end, &sr_end_iter)) { /* ending point is inside, move the start mark */ gtk_text_buffer_move_mark (region->buffer, sr->start, &end); } else { end_is_outside = TRUE; DEBUG (g_message ("end is outside")); } /* finally remove any intermediate subregions */ done = FALSE; node = start_node; while (!done) { if (node == end_node) /* we are done, exit in the next iteration */ done = TRUE; if ((node == start_node && !start_is_outside) || (node == end_node && !end_is_outside)) { /* skip starting or ending node */ node = node->next; } else { GList *l = node->next; sr = node->data; gtk_text_buffer_delete_mark (region->buffer, sr->start); gtk_text_buffer_delete_mark (region->buffer, sr->end); g_free (sr); region->subregions = g_list_delete_link (region->subregions, node); node = l; } } ++region->time_stamp; DEBUG (gtk_text_region_debug_print (region)); /* now get rid of empty subregions */ gtk_text_region_clear_zero_length_subregions (region); DEBUG (gtk_text_region_debug_print (region)); }
void dt_dev_add_history_item(dt_develop_t *dev, dt_iop_module_t *module, gboolean enable) { if(darktable.gui->reset) return; dt_pthread_mutex_lock(&dev->history_mutex); if(dev->gui_attached) { GList *history = g_list_nth (dev->history, dev->history_end); while(history) { GList *next = g_list_next(history); dt_dev_history_item_t *hist = (dt_dev_history_item_t *)(history->data); // printf("removing obsoleted history item: %s\n", hist->module->op); free(hist->params); free(hist->blend_params); free(history->data); dev->history = g_list_delete_link(dev->history, history); history = next; } history = g_list_nth(dev->history, dev->history_end-1); if(!history || module->instance != ((dt_dev_history_item_t *)history->data)->module->instance || module->multi_priority != ((dt_dev_history_item_t *)history->data)->module->multi_priority) { // new operation, push new item // printf("adding new history item %d - %s\n", dev->history_end, module->op); // if(history) printf("because item %d - %s is different operation.\n", dev->history_end-1, ((dt_dev_history_item_t *)history->data)->module->op); dev->history_end++; dt_dev_history_item_t *hist = (dt_dev_history_item_t *)malloc(sizeof(dt_dev_history_item_t)); if (enable) { module->enabled = TRUE; if(module->off) { darktable.gui->reset = 1; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), module->enabled); darktable.gui->reset = 0; } } hist->enabled = module->enabled; hist->module = module; hist->params = malloc(module->params_size); hist->multi_priority = module->multi_priority; snprintf(hist->multi_name,128,"%s",module->multi_name); /* allocate and set hist blend_params */ hist->blend_params = malloc(sizeof(dt_develop_blend_params_t)); memset(hist->blend_params, 0, sizeof(dt_develop_blend_params_t)); memcpy(hist->params, module->params, module->params_size); if(module->flags() & IOP_FLAGS_SUPPORTS_BLENDING) memcpy(hist->blend_params, module->blend_params, sizeof(dt_develop_blend_params_t)); dev->history = g_list_append(dev->history, hist); dev->pipe->changed |= DT_DEV_PIPE_SYNCH; dev->preview_pipe->changed |= DT_DEV_PIPE_SYNCH; // topology remains, as modules are fixed for now. } else { // same operation, change params // printf("changing same history item %d - %s\n", dev->history_end-1, module->op); dt_dev_history_item_t *hist = (dt_dev_history_item_t *)history->data; memcpy(hist->params, module->params, module->params_size); if(module->flags() & IOP_FLAGS_SUPPORTS_BLENDING) memcpy(hist->blend_params, module->blend_params, sizeof(dt_develop_blend_params_t)); // if the user changed stuff and the module is still not enabled, do it: if(!hist->enabled && !module->enabled) { module->enabled = 1; if(module->off) { darktable.gui->reset = 1; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), module->enabled); darktable.gui->reset = 0; } } hist->multi_priority = module->multi_priority; memcpy(hist->multi_name, module->multi_name, sizeof(module->multi_name)); hist->enabled = module->enabled; dev->pipe->changed |= DT_DEV_PIPE_TOP_CHANGED; dev->preview_pipe->changed |= DT_DEV_PIPE_TOP_CHANGED; } } #if 0 { // debug: printf("remaining %d history items:\n", dev->history_end); GList *history = dev->history; int i = 0; while(history) { dt_dev_history_item_t *hist = (dt_dev_history_item_t *)(history->data); printf("%d %s\n", i, hist->module->op); history = g_list_next(history); i++; } } #endif /* invalidate image data*/ dt_similarity_image_dirty(dev->image_storage.id); // invalidate buffers and force redraw of darkroom dt_dev_invalidate_all(dev); dt_pthread_mutex_unlock(&dev->history_mutex); if(dev->gui_attached) { /* signal that history has changed */ dt_control_signal_raise(darktable.signals, DT_SIGNAL_DEVELOP_HISTORY_CHANGE); /* redraw */ dt_control_queue_redraw_center(); } }
static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel) { GList *node; g_return_if_fail(window != NULL); node = g_list_find(activity_list, window); if (actlist_sort == 1) { /* Move the window to the first in the activity list */ if (node != NULL) activity_list = g_list_delete_link(activity_list, node); if (window->data_level != 0) activity_list = g_list_prepend(activity_list, window); statusbar_items_redraw("act"); return; } if (actlist_sort == 2) { if (node != NULL) { if (window->data_level == GPOINTER_TO_INT(oldlevel)) { if (window->hilight_color != 0) statusbar_items_redraw("act"); return; } activity_list = g_list_delete_link(activity_list, node); } if (window->data_level != 0) activity_list = g_list_insert_sorted(activity_list, window, (GCompareFunc) window_level_cmp); statusbar_items_redraw("act"); return; } if (actlist_sort == 3) { if (node != NULL) activity_list = g_list_delete_link(activity_list, node); if (window->data_level != 0) activity_list = g_list_insert_sorted(activity_list, window, (GCompareFunc) window_level_recent_cmp); statusbar_items_redraw("act"); return; } if (node != NULL) { /* already in activity list */ if (window->data_level == 0) { /* remove from activity list */ activity_list = g_list_delete_link(activity_list, node); statusbar_items_redraw("act"); } else if (window->data_level != GPOINTER_TO_INT(oldlevel) || window->hilight_color != 0) { /* different level as last time (or maybe different hilight color?), just redraw it. */ statusbar_items_redraw("act"); } return; } if (window->data_level == 0) return; /* add window to activity list .. */ activity_list = g_list_insert_sorted(activity_list, window, (GCompareFunc) window_refnum_cmp); statusbar_items_redraw("act"); }
void gtk_text_region_add (GtkTextRegion *region, const GtkTextIter *_start, const GtkTextIter *_end) { GList *start_node, *end_node; GtkTextIter start, end; g_return_if_fail (region != NULL && _start != NULL && _end != NULL); start = *_start; end = *_end; DEBUG (g_print ("---\n")); DEBUG (gtk_text_region_debug_print (region)); DEBUG (g_message ("region_add (%d, %d)", gtk_text_iter_get_offset (&start), gtk_text_iter_get_offset (&end))); gtk_text_iter_order (&start, &end); /* don't add zero-length regions */ if (gtk_text_iter_equal (&start, &end)) return; /* find bounding subregions */ start_node = find_nearest_subregion (region, &start, NULL, FALSE, TRUE); end_node = find_nearest_subregion (region, &end, start_node, TRUE, TRUE); if (start_node == NULL || end_node == NULL || end_node == start_node->prev) { /* create the new subregion */ Subregion *sr = g_new0 (Subregion, 1); sr->start = gtk_text_buffer_create_mark (region->buffer, NULL, &start, TRUE); sr->end = gtk_text_buffer_create_mark (region->buffer, NULL, &end, FALSE); if (start_node == NULL) { /* append the new region */ region->subregions = g_list_append (region->subregions, sr); } else if (end_node == NULL) { /* prepend the new region */ region->subregions = g_list_prepend (region->subregions, sr); } else { /* we are in the middle of two subregions */ region->subregions = g_list_insert_before (region->subregions, start_node, sr); } } else { GtkTextIter iter; Subregion *sr = start_node->data; if (start_node != end_node) { /* we need to merge some subregions */ GList *l = start_node->next; Subregion *q; gtk_text_buffer_delete_mark (region->buffer, sr->end); while (l != end_node) { q = l->data; gtk_text_buffer_delete_mark (region->buffer, q->start); gtk_text_buffer_delete_mark (region->buffer, q->end); g_free (q); l = g_list_delete_link (l, l); } q = l->data; gtk_text_buffer_delete_mark (region->buffer, q->start); sr->end = q->end; g_free (q); l = g_list_delete_link (l, l); } /* now move marks if that action expands the region */ gtk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->start); if (gtk_text_iter_compare (&iter, &start) > 0) gtk_text_buffer_move_mark (region->buffer, sr->start, &start); gtk_text_buffer_get_iter_at_mark (region->buffer, &iter, sr->end); if (gtk_text_iter_compare (&iter, &end) < 0) gtk_text_buffer_move_mark (region->buffer, sr->end, &end); } ++region->time_stamp; DEBUG (gtk_text_region_debug_print (region)); }
static gboolean playlist_positions_add_interval (playlist_positions_t *positions, gint start, gint end) { GList *n; interval_t *ival, *prev_ival; /* Invalid interval */ if (start > end || start < 0) { return FALSE; } if (start == end) { playlist_positions_add_atom (positions, start); return TRUE; } /* Merge or add new interval in list */ prev_ival = NULL; for (n = positions->intervals; n; n = g_list_next (n)) { ival = (interval_t *) n->data; if (start > ival->end) { break; } else if (end < ival->start) { continue; } else { /* Previous interval already merged, free it and extend current */ if (prev_ival) { ival->end = prev_ival->end; interval_free (prev_ival); positions->intervals = g_list_remove (positions->intervals, prev_ival); } prev_ival = ival; } } if (prev_ival) { /* extend end of merged interval */ if (end > prev_ival->end) { prev_ival->end = end; } /* extend start of merged interval */ if (start < prev_ival->start) { prev_ival->start = start; } } else { /* Not merged with an existing interval, create a new one */ positions->intervals = g_list_insert_before (positions->intervals, n, interval_new (start, end)); } /* Remove atoms included in the new interval */ for (n = positions->atoms; n; n = g_list_next (n)) { gint curr = GPOINTER_TO_INT (n->data); if (curr <= end) { if (curr >= start) { /* atom in the interval, remove */ positions->atoms = g_list_delete_link (positions->atoms, n); } else { /* atom smaller than interval, done */ break; } } } return TRUE; }
bool optimize_block(GList** instructions, int opt_level) { if(opt_level == 0) // no optimization return true; for(GList *inst = *instructions; inst != NULL; inst = inst->next) { uint32_t *a = (uint32_t*) DATA(inst)->args; // pattern is LD A,HL+; LD (DE),A; INC DE -> LD DE+, HL+ if((*a & 0xffffff) == 0x13122a) { printf("optimizing block @%#x (3)\n", DATA(*instructions)->address); DATA(inst)->op1 = MEM_INC_DE; DATA(inst)->cycles = 6; DATA(inst)->bytes = 3; g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); } //pattern f0 41 e6 03 20 fa -> wait for stat mode 3 if((*a) == 0x03e641f0 && (*(a+1) & 0xffff) == 0xfa20) { printf("optimizing block @%#x (4)\n", DATA(*instructions)->address); DATA(inst)->opcode = HALT; DATA(inst)->op1 = WAIT_STAT3; DATA(inst)->cycles = 0; DATA(inst)->bytes = 6; g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); } //pattern f0 44 fe ?? 20 fa -> wait for ly if((*a & 0x00ffffff) == 0xfe44f0 && (*(a+1) & 0xffff) == 0xfa20) { printf("optimizing block @%#x (5)\n", DATA(*instructions)->address); DATA(inst)->opcode = HALT; DATA(inst)->op1 = WAIT_LY; DATA(inst)->cycles = 0; DATA(inst)->bytes = 6; g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); } //pattern f0 00 f0 00 -> repeated read of jopad register if((*a) == 0x00f000f0) { printf("optimizing block @%#x (6)\n", DATA(*instructions)->address); DATA(inst)->cycles += 3; DATA(inst)->bytes += 2; DATA(inst)->args = DATA(inst->next)->args; g_free(inst->next->data); *instructions = g_list_delete_link(*instructions, inst->next); if(inst->prev) //apply pattern to this instruction again inst = inst->prev; } } int byte_offset = 0; for(GList *inst = *instructions; inst != NULL; inst = inst->next) { byte_offset += DATA(inst)->bytes; if(is_jump_to_start(DATA(inst), byte_offset)) { bool can_optimize1 = true; bool can_optimize2 = true; for(GList *inst2 = *instructions; inst2 != inst; inst2 = inst2->next) { if(!is_const(DATA(inst2), opt_level)) can_optimize1 = false; if(!is_no_mem_access(DATA(inst2), opt_level)) can_optimize2 = false; } if(can_optimize1) { printf("optimizing block @%#x (1)\n", DATA(*instructions)->address); // optimize 2: ... JP <2 // to JP >1 2: HALT 1: ... JP <2 // insert jump target at the position of the old start instruction gb_instruction *jp_target = g_new(gb_instruction, 1); *jp_target = (gb_instruction){JP_TARGET, TARGET_1, NONE, 0, DATA(*instructions)->address, 0, 0, 0, 0}; *instructions = g_list_prepend(*instructions, jp_target); // prepend halt, as the loop cannot change the break condition gb_instruction *halt_inst = g_new(gb_instruction, 1); *halt_inst = (gb_instruction){HALT, NONE, NONE, 0, DATA(*instructions)->address, 1, 1, 1, INST_FLAG_ENDS_BLOCK}; *instructions = g_list_prepend(*instructions, halt_inst); // prepend jump target before halt instruction gb_instruction *jp_target2 = g_new(gb_instruction, 1); *jp_target2 = (gb_instruction){JP_TARGET, TARGET_2, NONE, 0, DATA(*instructions)->address, 0, 0, 0, 0}; *instructions = g_list_prepend(*instructions, jp_target2); // prepend jp, to jump to the old start instruction gb_instruction *jp_inst = g_new(gb_instruction, 1); *jp_inst = (gb_instruction){JP_FWD, NONE, TARGET_1, 0, DATA(*instructions)->address, 0, 0, 0, 0}; *instructions = g_list_prepend(*instructions, jp_inst); // modify jump to point to the halt instruction DATA(inst)->opcode = JP_BWD; DATA(inst)->op2 = TARGET_2; DATA(inst)->flags &= ~INST_FLAG_ENDS_BLOCK; break; } else if(can_optimize2) { if(DATA(*instructions)->address < 0xff00) printf("optimizing block @%#x (2)\n", DATA(*instructions)->address); // insert jump target at the position of the old start instruction gb_instruction *jp_target = g_new(gb_instruction, 1); *jp_target = (gb_instruction){JP_TARGET, TARGET_1, NONE, 0, DATA(*instructions)->address, 0, 0, 0, 0}; *instructions = g_list_prepend(*instructions, jp_target); DATA(inst)->opcode = JP_BWD; DATA(inst)->op2 = TARGET_1; } else { printf("jp to start detected, could not optimize %#x\n", DATA(*instructions)->address); } } } return true; }
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; }
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(); return 0; }
void dt_dev_reload_history_items(dt_develop_t *dev) { dt_dev_pop_history_items(dev, 0); // remove unused history items: GList *history = g_list_nth(dev->history, dev->history_end); while(history) { GList *next = g_list_next(history); dt_dev_history_item_t *hist = (dt_dev_history_item_t *)(history->data); free(hist->params); free(hist->blend_params); free(history->data); dev->history = g_list_delete_link(dev->history, history); history = next; } dt_dev_read_history(dev); //we have to add new module instances first GList *modules = dev->iop; while(modules) { dt_iop_module_t *module = (dt_iop_module_t *)(modules->data); if (module->multi_priority > 0) { if (!dt_iop_is_hidden(module) && !module->expander) { module->gui_init(module); //we search the base iop corresponding GList *mods = g_list_first(dev->iop); dt_iop_module_t *base = NULL; int pos_module = 0; int pos_base = 0; int pos = 0; while (mods) { dt_iop_module_t *mod = (dt_iop_module_t *)(mods->data); if (mod->multi_priority == 0 && mod->instance == module->instance) { base = mod; pos_base = pos; } else if (mod == module) pos_module = pos; mods = g_list_next(mods); pos++; } if (!base) continue; /* add module to right panel */ GtkWidget *expander = dt_iop_gui_get_expander(module); dt_ui_container_add_widget(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER, expander); GValue gv = { 0, { { 0 } } }; g_value_init(&gv,G_TYPE_INT); gtk_container_child_get_property(GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),base->expander,"position",&gv); gtk_box_reorder_child (dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER),expander,g_value_get_int(&gv)+pos_base-pos_module); dt_iop_gui_set_expanded(module, TRUE); dt_iop_gui_update_blending(module); //the pipe need to be reconstruct dev->pipe->changed |= DT_DEV_PIPE_REMOVE; dev->preview_pipe->changed |= DT_DEV_PIPE_REMOVE; } } modules = g_list_next(modules); } dt_dev_pop_history_items(dev, dev->history_end); }
static guint32 book_shell_content_check_state (EShellContent *shell_content) { EBookShellContent *book_shell_content; ESelectionModel *selection_model; EAddressbookModel *model; EAddressbookView *view; gboolean has_email = TRUE; gboolean is_contact_list = TRUE; guint32 state = 0; gint n_selected; struct { EAddressbookModel *model; GList *list; } foreach_data; book_shell_content = E_BOOK_SHELL_CONTENT (shell_content); view = e_book_shell_content_get_current_view (book_shell_content); model = e_addressbook_view_get_model (view); selection_model = e_addressbook_view_get_selection_model (view); n_selected = (selection_model != NULL) ? e_selection_model_selected_count (selection_model) : 0; foreach_data.model = model; foreach_data.list = NULL; if (selection_model != NULL) e_selection_model_foreach ( selection_model, (EForeachFunc) book_shell_content_check_state_foreach, &foreach_data); while (foreach_data.list != NULL) { EContact *contact = E_CONTACT (foreach_data.list->data); GList *email_list; email_list = e_contact_get (contact, E_CONTACT_EMAIL); has_email &= (email_list != NULL); g_list_foreach (email_list, (GFunc) g_free, NULL); g_list_free (email_list); is_contact_list &= (e_contact_get (contact, E_CONTACT_IS_LIST) != NULL); g_object_unref (contact); foreach_data.list = g_list_delete_link ( foreach_data.list, foreach_data.list); } if (n_selected == 1) state |= E_BOOK_SHELL_CONTENT_SELECTION_SINGLE; if (n_selected > 1) state |= E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE; if (n_selected > 0 && has_email) state |= E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL; if (n_selected == 1 && is_contact_list) state |= E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST; if (e_addressbook_model_can_stop (model)) state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY; if (e_addressbook_model_get_editable (model)) state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE; return state; }
int main(int argc, char **argv) { abrt_init(argv); /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif /* Can't keep these strings/structs static: _() doesn't support that */ const char *program_usage_string = _( "\n& [-vbf] [-g GROUP-NAME]... [-c CONFFILE]... [-F FMTFILE] [-A FMTFILE2] -d DIR" "\nor:" "\n& [-v] [-c CONFFILE]... [-d DIR] -t[ID] FILE..." "\nor:" "\n& [-v] [-c CONFFILE]... [-d DIR] -t[ID] -w" "\nor:" "\n& [-v] [-c CONFFILE]... -h DUPHASH" "\n" "\nReports problem to Bugzilla." "\n" "\nThe tool reads DIR. Then it logs in to Bugzilla and tries to find a bug" "\nwith the same abrt_hash:HEXSTRING in 'Whiteboard'." "\n" "\nIf such bug is not found, then a new bug is created. Elements of DIR" "\nare stored in the bug as part of bug description or as attachments," "\ndepending on their type and size." "\n" "\nOtherwise, if such bug is found and it is marked as CLOSED DUPLICATE," "\nthe tool follows the chain of duplicates until it finds a non-DUPLICATE bug." "\nThe tool adds a new comment to found bug." "\n" "\nThe URL to new or modified bug is printed to stdout and recorded in" "\n'reported_to' element." "\n" "\nOption -t uploads FILEs to the already created bug on Bugzilla site." "\nThe bug ID is retrieved from directory specified by -d DIR." "\nIf problem data in DIR was never reported to Bugzilla, upload will fail." "\n" "\nOption -tID uploads FILEs to the bug with specified ID on Bugzilla site." "\n-d DIR is ignored." "\n" "\nOption -w adds bugzilla user to bug's CC list." "\n" "\nIf not specified, CONFFILE defaults to "CONF_DIR"/plugins/bugzilla.conf" "\nIts lines should have 'PARAM = VALUE' format." "\nRecognized string parameters: BugzillaURL, Login, Password, OSRelease." "\nRecognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify." "\nParameters can be overridden via $Bugzilla_PARAM environment variables." "\n" "\nFMTFILE and FMTFILE2 default to "CONF_DIR"/plugins/bugzilla_format.conf" ); enum { OPT_v = 1 << 0, OPT_d = 1 << 1, OPT_c = 1 << 2, OPT_F = 1 << 3, OPT_A = 1 << 4, OPT_t = 1 << 5, OPT_b = 1 << 6, OPT_f = 1 << 7, OPT_w = 1 << 8, OPT_h = 1 << 9, OPT_g = 1 << 10, OPT_D = 1 << 11, }; const char *dump_dir_name = "."; GList *conf_file = NULL; const char *fmt_file = CONF_DIR"/plugins/bugzilla_format.conf"; const char *fmt_file2 = fmt_file; char *abrt_hash = NULL; char *ticket_no = NULL; char *debug_str = NULL; GList *group = NULL; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_STRING( 'd', NULL, &dump_dir_name , "DIR" , _("Problem directory")), OPT_LIST( 'c', NULL, &conf_file , "FILE" , _("Configuration file (may be given many times)")), OPT_STRING( 'F', NULL, &fmt_file , "FILE" , _("Formatting file for initial comment")), OPT_STRING( 'A', NULL, &fmt_file2 , "FILE" , _("Formatting file for duplicates")), OPT_OPTSTRING('t', "ticket", &ticket_no , "ID" , _("Attach FILEs [to bug with this ID]")), OPT_BOOL( 'b', NULL, NULL, _("When creating bug, attach binary files too")), OPT_BOOL( 'f', NULL, NULL, _("Force reporting even if this problem is already reported")), OPT_BOOL( 'w', NULL, NULL, _("Add bugzilla user to CC list [of bug with this ID]")), OPT_STRING( 'h', "duphash", &abrt_hash, "DUPHASH", _("Print BUG_ID which has given DUPHASH")), OPT_LIST( 'g', "group", &group , "GROUP" , _("Restrict access to this group only")), OPT_OPTSTRING('D', "debug", &debug_str , "STR" , _("Debug")), OPT_END() }; unsigned opts = parse_opts(argc, argv, program_options, program_usage_string); argv += optind; export_abrt_envvars(0); map_string_t *settings = new_map_string(); struct bugzilla_struct rhbz = { 0 }; { if (!conf_file) conf_file = g_list_append(conf_file, (char*) CONF_DIR"/plugins/bugzilla.conf"); while (conf_file) { char *fn = (char *)conf_file->data; VERB1 log("Loading settings from '%s'", fn); load_conf_file(fn, settings, /*skip key w/o values:*/ false); VERB3 log("Loaded '%s'", fn); conf_file = g_list_delete_link(conf_file, conf_file); } set_settings(&rhbz, settings); /* WRONG! set_settings() does not copy the strings, it merely sets up pointers * to settings[] dictionary: */ /*free_map_string(settings);*/ } VERB1 log("Initializing XML-RPC library"); xmlrpc_env env; xmlrpc_env_init(&env); xmlrpc_client_setup_global_const(&env); if (env.fault_occurred) abrt_xmlrpc_die(&env); xmlrpc_env_clean(&env); struct abrt_xmlrpc *client; client = abrt_xmlrpc_new_client(rhbz.b_bugzilla_xmlrpc, rhbz.b_ssl_verify); unsigned rhbz_ver = rhbz_version(client); if (abrt_hash) { log(_("Looking for similar problems in bugzilla")); char *hash; if (prefixcmp(abrt_hash, "abrt_hash:")) hash = xasprintf("abrt_hash:%s", abrt_hash); else hash = xstrdup(abrt_hash); /* it's Fedora specific */ xmlrpc_value *all_bugs = rhbz_search_duphash(client, /*product:*/ "Fedora", /*version:*/ NULL, /*component:*/ NULL, hash); free(hash); unsigned all_bugs_size = rhbz_array_size(all_bugs); if (all_bugs_size > 0) { int bug_id = rhbz_get_bug_id_from_array0(all_bugs, rhbz_ver); printf("%i\n", bug_id); } return EXIT_SUCCESS; } if (rhbz.b_login[0] == '\0') { free(rhbz.b_login); rhbz.b_login = ask_bz_login(_("Login is not provided by configuration. Please enter your BZ login:"******"Password is not provided by configuration. Please enter the password for '%s':"), rhbz.b_login); rhbz.b_password = ask_bz_password(question); free(question); } if (opts & OPT_t) { if ((!argv[0] && !(opts & OPT_w)) || (argv[0] && (opts & OPT_w))) show_usage_and_die(program_usage_string, program_options); if (!ticket_no) { struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) xfunc_die(); report_result_t *reported_to = find_in_reported_to(dd, "Bugzilla:"); dd_close(dd); if (!reported_to || !reported_to->url) error_msg_and_die(_("Can't get Bugzilla ID because this problem has not yet been reported to Bugzilla.")); char *url = reported_to->url; reported_to->url = NULL; free_report_result(reported_to); if (prefixcmp(url, rhbz.b_bugzilla_url) != 0) error_msg_and_die(_("This problem has been reported to Bugzilla '%s' which differs from the configured Bugzilla '%s'."), url, rhbz.b_bugzilla_url); ticket_no = strrchr(url, '='); if (!ticket_no) error_msg_and_die(_("Malformed url to Bugzilla '%s'."), url); /* won't ever call free on it - it simplifies the code a lot */ ticket_no = xstrdup(ticket_no + 1); log(_("Using Bugzilla ID '%s'"), ticket_no); } login(client, &rhbz); if (opts & OPT_w) rhbz_mail_to_cc(client, xatoi_positive(ticket_no), rhbz.b_login, /* require mail notify */ 0); else { /* Attach files to existing BZ */ while (*argv) { const char *filename = *argv++; VERB1 log("Attaching file '%s' to bug %s", filename, ticket_no); int fd = open(filename, O_RDONLY); if (fd < 0) { perror_msg("Can't open '%s'", filename); continue; } struct stat st; if (fstat(fd, &st) != 0 || !S_ISREG(st.st_mode)) { error_msg("'%s': not a regular file", filename); close(fd); continue; } rhbz_attach_fd(client, ticket_no, filename, fd, /*flags*/ 0); close(fd); } } log(_("Logging out")); rhbz_logout(client); #if 0 /* enable if you search for leaks (valgrind etc) */ abrt_xmlrpc_free_client(client); #endif return 0; } /* Create new bug in Bugzilla */ if (!(opts & OPT_f)) { struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) xfunc_die(); report_result_t *reported_to = find_in_reported_to(dd, "Bugzilla:"); dd_close(dd); if (reported_to && reported_to->url) { char *msg = xasprintf("This problem was already reported to Bugzilla (see '%s')." " Do you still want to create a new bug?", reported_to->url); int yes = ask_yes_no(msg); free(msg); if (!yes) return 0; } free_report_result(reported_to); } problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name); if (!problem_data) xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */ const char *component = problem_data_get_content_or_die(problem_data, FILENAME_COMPONENT); const char *duphash = problem_data_get_content_or_NULL(problem_data, FILENAME_DUPHASH); //COMPAT, remove after 2.1 release if (!duphash) duphash = problem_data_get_content_or_die(problem_data, "global_uuid"); if (!rhbz.b_product || !*rhbz.b_product) /* if not overridden or empty... */ { free(rhbz.b_product); free(rhbz.b_product_version); map_string_t *osinfo = new_map_string(); problem_data_get_osinfo(problem_data, osinfo); parse_osinfo_for_bz(osinfo, &rhbz.b_product, &rhbz.b_product_version); free_map_string(osinfo); if (!rhbz.b_product) error_msg_and_die(_("Can't determine Bugzilla Product from problem data.")); } if (opts & OPT_D) { GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); struct strbuf *bzcomment_buf = strbuf_new(); generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); char *bzcomment = strbuf_free_nobuf(bzcomment_buf); char *summary = create_summary_string(problem_data, comment_fmt_spec); printf("summary: %s\n" "\n" "%s" , summary, bzcomment ); free(bzcomment); free(summary); exit(0); } login(client, &rhbz); int bug_id = 0; /* If REMOTE_RESULT contains "DUPLICATE 12345", we consider it a dup of 12345 * and won't search on bz server. */ char *remote_result; remote_result = problem_data_get_content_or_NULL(problem_data, FILENAME_REMOTE_RESULT); if (remote_result) { char *cmd = strtok(remote_result, " \n"); char *id = strtok(NULL, " \n"); if (!prefixcmp(cmd, "DUPLICATE")) { errno = 0; char *e; bug_id = strtoul(id, &e, 10); if (errno || id == e || *e != '\0' || bug_id > INT_MAX) { /* error / no digits / illegal trailing chars / too big a number */ bug_id = 0; } } } struct bug_info *bz = NULL; if (!bug_id) { log(_("Checking for duplicates")); int existing_id = -1; int crossver_id = -1; { /* Figure out whether we want to match component * when doing dup search. */ const char *component_substitute = is_in_comma_separated_list(component, rhbz.b_DontMatchComponents) ? NULL : component; /* We don't do dup detection across versions (see below why), * but we do add a note if cross-version potential dup exists. * For that, we search for cross version dups first: */ xmlrpc_value *crossver_bugs = rhbz_search_duphash(client, rhbz.b_product, /*version:*/ NULL, component_substitute, duphash); unsigned crossver_bugs_count = rhbz_array_size(crossver_bugs); VERB3 log("Bugzilla has %i reports with duphash '%s' including cross-version ones", crossver_bugs_count, duphash); if (crossver_bugs_count > 0) crossver_id = rhbz_get_bug_id_from_array0(crossver_bugs, rhbz_ver); xmlrpc_DECREF(crossver_bugs); if (crossver_bugs_count > 0) { /* In dup detection we require match in product *and version*. * Otherwise we sometimes have bugs in e.g. Fedora 17 * considered to be dups of Fedora 16 bugs. * Imagine that F16 is "end-of-lifed" - allowing cross-version * match will make all newly detected crashes DUPed * to a bug in a dead release. */ xmlrpc_value *dup_bugs = rhbz_search_duphash(client, rhbz.b_product, rhbz.b_product_version, component_substitute, duphash); unsigned dup_bugs_count = rhbz_array_size(dup_bugs); VERB3 log("Bugzilla has %i reports with duphash '%s'", dup_bugs_count, duphash); if (dup_bugs_count > 0) existing_id = rhbz_get_bug_id_from_array0(dup_bugs, rhbz_ver); xmlrpc_DECREF(dup_bugs); } } if (existing_id < 0) { /* Create new bug */ log(_("Creating a new bug")); GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file); struct strbuf *bzcomment_buf = strbuf_new(); generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); if (crossver_id >= 0) strbuf_append_strf(bzcomment_buf, "\nPotential duplicate: bug %u\n", crossver_id); char *bzcomment = strbuf_free_nobuf(bzcomment_buf); char *summary = create_summary_string(problem_data, comment_fmt_spec); int new_id = rhbz_new_bug(client, problem_data, rhbz.b_product, rhbz.b_product_version, summary, bzcomment, group ); free(bzcomment); free(summary); if (new_id == -1) { error_msg_and_die(_("Failed to create a new bug.")); } log(_("Adding attachments to bug %i"), new_id); char new_id_str[sizeof(int)*3 + 2]; sprintf(new_id_str, "%i", new_id); attach_files(client, new_id_str, problem_data, comment_fmt_spec); //TODO: free_comment_fmt_spec(comment_fmt_spec); bz = new_bug_info(); bz->bi_status = xstrdup("NEW"); bz->bi_id = new_id; goto log_out; } bug_id = existing_id; } bz = rhbz_bug_info(client, bug_id); log(_("Bug is already reported: %i"), bz->bi_id); /* Follow duplicates */ if ((strcmp(bz->bi_status, "CLOSED") == 0) && (strcmp(bz->bi_resolution, "DUPLICATE") == 0) ) { struct bug_info *origin; origin = rhbz_find_origin_bug_closed_duplicate(client, bz); if (origin) { free_bug_info(bz); bz = origin; } } if (strcmp(bz->bi_status, "CLOSED") != 0) { /* Add user's login to CC if not there already */ if (strcmp(bz->bi_reporter, rhbz.b_login) != 0 && !g_list_find_custom(bz->bi_cc_list, rhbz.b_login, (GCompareFunc)g_strcmp0) ) { log(_("Adding %s to CC list"), rhbz.b_login); rhbz_mail_to_cc(client, bz->bi_id, rhbz.b_login, RHBZ_NOMAIL_NOTIFY); } /* Add comment and bt */ const char *comment = problem_data_get_content_or_NULL(problem_data, FILENAME_COMMENT); if (comment && comment[0]) { GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file2); struct strbuf *bzcomment_buf = strbuf_new(); generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec); char *bzcomment = strbuf_free_nobuf(bzcomment_buf); //TODO: free_comment_fmt_spec(comment_fmt_spec); int dup_comment = is_comment_dup(bz->bi_comments, bzcomment); if (!dup_comment) { log(_("Adding new comment to bug %d"), bz->bi_id); rhbz_add_comment(client, bz->bi_id, bzcomment, 0); free(bzcomment); const char *bt = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE); unsigned rating = 0; const char *rating_str = problem_data_get_content_or_NULL(problem_data, FILENAME_RATING); /* python doesn't have rating file */ if (rating_str) rating = xatou(rating_str); if (bt && rating > bz->bi_best_bt_rating) { char bug_id_str[sizeof(int)*3 + 2]; sprintf(bug_id_str, "%i", bz->bi_id); log(_("Attaching better backtrace")); rhbz_attach_blob(client, bug_id_str, FILENAME_BACKTRACE, bt, strlen(bt), RHBZ_NOMAIL_NOTIFY); } } else { free(bzcomment); log(_("Found the same comment in the bug history, not adding a new one")); } } } log_out: log(_("Logging out")); rhbz_logout(client); log(_("Status: %s%s%s %s/show_bug.cgi?id=%u"), bz->bi_status, bz->bi_resolution ? " " : "", bz->bi_resolution ? bz->bi_resolution : "", rhbz.b_bugzilla_url, bz->bi_id); struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (dd) { char *msg = xasprintf("Bugzilla: URL=%s/show_bug.cgi?id=%u", rhbz.b_bugzilla_url, bz->bi_id); add_reported_to(dd, msg); free(msg); dd_close(dd); } #if 0 /* enable if you search for leaks (valgrind etc) */ free(rhbz.b_product); free(rhbz.b_product_version); problem_data_free(problem_data); free_bug_info(bz); abrt_xmlrpc_free_client(client); #endif return 0; }
void dt_camctl_detect_cameras(const dt_camctl_t *c) { dt_camctl_t *camctl=(dt_camctl_t *)c; dt_pthread_mutex_lock(&camctl->lock); /* reload portdrivers */ if (camctl->gpports) gp_port_info_list_free (camctl->gpports); gp_port_info_list_new( &camctl->gpports ); gp_port_info_list_load( camctl->gpports ); dt_print(DT_DEBUG_CAMCTL,"[camera_control] loaded %d port drivers.\n", gp_port_info_list_count( camctl->gpports ) ); CameraList *available_cameras=NULL; gp_list_new( &available_cameras ); gp_abilities_list_detect (c->gpcams,c->gpports, available_cameras, c->gpcontext ); dt_print(DT_DEBUG_CAMCTL,"[camera_control] %d cameras connected\n",gp_list_count( available_cameras )>0?gp_list_count( available_cameras ):0); for(int i=0; i<gp_list_count( available_cameras ); i++) { dt_camera_t *camera=g_malloc(sizeof(dt_camera_t)); memset( camera,0,sizeof(dt_camera_t)); gp_list_get_name (available_cameras, i, &camera->model); gp_list_get_value (available_cameras, i, &camera->port); dt_pthread_mutex_init(&camera->config_lock, NULL); dt_pthread_mutex_init(&camera->live_view_pixbuf_mutex, NULL); dt_pthread_mutex_init(&camera->live_view_synch, NULL); // if(strcmp(camera->port,"usb:")==0) { g_free(camera); continue; } GList *citem; if( (citem=g_list_find_custom(c->cameras,camera,_compare_camera_by_port)) == NULL || strcmp(((dt_camera_t *)citem->data)->model,camera->model)!=0 ) { if(citem==NULL) { // Newly connected camera if(_camera_initialize(c,camera)==FALSE) { dt_print(DT_DEBUG_CAMCTL,"[camera_control] failed to initialize device %s on port %s, probably causes are: locked by another application, no access to udev etc.\n", camera->model,camera->port); g_free(camera); continue; } // Check if camera has capabililties for being presented to darktable if( camera->can_import==FALSE && camera->can_tether==FALSE ) { dt_print(DT_DEBUG_CAMCTL,"[camera_control] device %s on port %s doesn't support import or tether, skipping device.\n", camera->model,camera->port); g_free(camera); continue; } // Fetch some summary of camera if( gp_camera_get_summary(camera->gpcam, &camera->summary, c->gpcontext) == GP_OK ) { // Remove device property summary: char *eos=strstr(camera->summary.text,"Device Property Summary:\n"); if (eos) eos[0]='\0'; } // Add to camera list camctl->cameras = g_list_append(camctl->cameras,camera); // Notify listeners of connected camera _dispatch_camera_connected(camctl,camera); } } else g_free(camera); } /* check c->cameras in available_cameras */ if( c->cameras && g_list_length(c->cameras)>0) { GList *citem = c->cameras; do { int index=0; dt_camera_t *cam=(dt_camera_t *)citem->data; if (gp_list_find_by_name(available_cameras,&index,cam->model)!= GP_OK) { /* remove camera from cached list.. */ dt_camctl_t *camctl=(dt_camctl_t *)c; dt_camera_t *oldcam = (dt_camera_t *)citem->data; camctl->cameras=citem= g_list_delete_link (c->cameras,citem); g_free(oldcam); } } while ( citem && (citem=g_list_next(citem))!=NULL); } dt_pthread_mutex_unlock(&camctl->lock); }
void dt_capabilities_cleanup() { while(darktable.capabilities) darktable.capabilities = g_list_delete_link(darktable.capabilities, darktable.capabilities); }
static void string_edited (GtkCellRendererText *renderer, gchar *path, gchar *new_text, GladeEditorProperty *eprop) { GladeEPropStringList *eprop_string_list = GLADE_EPROP_STRING_LIST (eprop); GtkTreePath *tree_path = gtk_tree_path_new_from_string (path); GtkTreeIter iter; gboolean dummy; guint index; GladeProperty *property = glade_editor_property_get_property (eprop); GList *string_list = NULL; gtk_tree_model_get_iter (eprop_string_list->model, &iter, tree_path); gtk_tree_model_get (eprop_string_list->model, &iter, COLUMN_INDEX, &index, COLUMN_DUMMY, &dummy, -1); glade_property_get (property, &string_list); if (string_list) string_list = glade_string_list_copy (string_list); if (dummy) { if (new_text && new_text[0] && strcmp (new_text, _("<Type Here>")) != 0) string_list = glade_string_list_append (string_list, new_text, NULL, NULL, eprop_string_list->translatable, NULL); } else if (new_text && new_text[0]) { GladeString *string = g_list_nth_data (string_list, index); g_free (string->string); string->string = g_strdup (new_text); } else { GList *node = g_list_nth (string_list, index); glade_string_free (node->data); string_list = g_list_delete_link (string_list, node); } eprop_string_list->editing_index = index; if (eprop_string_list->pending_string_list) glade_string_list_free (eprop_string_list->pending_string_list); eprop_string_list->pending_string_list = string_list; if (eprop_string_list->update_id == 0) eprop_string_list->update_id = g_idle_add ((GSourceFunc) update_string_list_idle, eprop); gtk_tree_path_free (tree_path); }
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; }
void finalize_store(dt_imageio_module_storage_t *self, void *dd) { dt_imageio_gallery_t *d = (dt_imageio_gallery_t *)dd; char filename[1024]; snprintf(filename, 1024, "%s", d->cached_dirname); char *c = filename + strlen(filename); // also create style/ subdir: sprintf(c, "/style"); g_mkdir_with_parents(filename, 0755); sprintf(c, "/style/style.css"); copy_res("/style/style.css", filename); sprintf(c, "/style/favicon.ico"); copy_res("/style/favicon.ico", filename); sprintf(c, "/style/bullet.gif"); copy_res("/style/bullet.gif", filename); sprintf(c, "/style/close.gif"); copy_res("/style/close.gif", filename); sprintf(c, "/style/closelabel.gif"); copy_res("/style/closelabel.gif", filename); sprintf(c, "/style/donate-button.gif"); copy_res("/style/donate-button.gif", filename); sprintf(c, "/style/download-icon.gif"); copy_res("/style/download-icon.gif", filename); sprintf(c, "/style/image-1.jpg"); copy_res("/style/image-1.jpg", filename); sprintf(c, "/style/lightbox.css"); copy_res("/style/lightbox.css", filename); sprintf(c, "/style/loading.gif"); copy_res("/style/loading.gif", filename); sprintf(c, "/style/nextlabel.gif"); copy_res("/style/nextlabel.gif", filename); sprintf(c, "/style/prevlabel.gif"); copy_res("/style/prevlabel.gif", filename); sprintf(c, "/style/thumb-1.jpg"); copy_res("/style/thumb-1.jpg", filename); // create subdir js for lightbox2 viewer scripts sprintf(c, "/js"); g_mkdir_with_parents(filename, 0755); sprintf(c, "/js/builder.js"); copy_res("/js/builder.js", filename); sprintf(c, "/js/effects.js"); copy_res("/js/effects.js", filename); sprintf(c, "/js/lightbox.js"); copy_res("/js/lightbox.js", filename); sprintf(c, "/js/lightbox-web.js"); copy_res("/js/lightbox-web.js", filename); sprintf(c, "/js/prototype.js"); copy_res("/js/prototype.js", filename); sprintf(c, "/js/scriptaculous.js"); copy_res("/js/scriptaculous.js", filename); sprintf(c, "/index.html"); const char *title = d->title; FILE *f = fopen(filename, "wb"); if(!f) return; fprintf(f, "<!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" " <link rel=\"stylesheet\" href=\"style/lightbox.css\" type=\"text/css\" media=\"screen\" />" " <script type=\"text/javascript\" src=\"js/prototype.js\"></script>\n" " <script type=\"text/javascript\" src=\"js/scriptaculous.js?load=effects,builder\"></script>\n" " <script type=\"text/javascript\" src=\"js/lightbox.js\"></script>\n" " <title>%s</title>\n" " </head>\n" " <body>\n" " <div class=\"title\">%s</div>\n" " <div class=\"page\">\n", title, title); while(d->l) { pair_t *p = (pair_t *)d->l->data; fprintf(f, "%s", p->line); free(p); d->l = g_list_delete_link(d->l, d->l); } fprintf(f, " <p style=\"clear:both;\"></p>\n" " </div>\n" " <div class=\"footer\">\n" " <script language=\"JavaScript\" type=\"text/javascript\">\n" " document.write(\"download all: <em>wget -r -np -nc -k \" + document.documentURI + \"</em>\")\n" " </script><br />\n" " created with darktable "PACKAGE_VERSION"\n" " </div>\n" " </body>\n" "</html>\n" ); fclose(f); }
static __inline__ NmpNetPackInfo * __nmp_net_packet_cached(NmpDefrags *fragments, NmpNetPackInfo *net_pack) { NmpNetPackInfo *np; GList *list; NmpPacketFrags *frags; list = g_list_find_custom( fragments->pl, net_pack->private_from_low_layer, nmp_net_packet_find_frags ); if (list) { frags = (NmpPacketFrags*)list->data; np = nmp_net_packet_enqueue(frags, net_pack); if (np) { nmp_net_packet_release_frags(frags); fragments->pl = g_list_delete_link( fragments->pl, list ); if (np == net_pack) np = NULL; /* always means error occurred */ } return np; } else { if (net_pack->packet_no != 1) { nmp_print( "received a fragmentary packet, drop!" ); return NULL; } if (net_pack->total_packets > MAX_PACKET_FRAGMENTS) { nmp_warning( "too many fragments, drop!" ); return NULL; } frags = nmp_net_packet_new_frags( net_pack->private_from_low_layer, net_pack->total_packets ); if (G_UNLIKELY(!frags)) { nmp_warning( "alloc frags object failed!" ); return NULL; } np = nmp_net_packet_enqueue(frags, net_pack); if (np) { nmp_net_packet_release_frags(frags); if (np == net_pack) np = NULL; } else { fragments->pl = g_list_prepend( fragments->pl, frags ); } return np; } }
gboolean gst_device_monitor_start (GstDeviceMonitor * monitor) { guint cookie, i; GList *pending = NULL, *started = NULL, *removed = NULL; g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); GST_OBJECT_LOCK (monitor); if (monitor->priv->filters->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all " "devices found"); gst_device_monitor_add_filter (monitor, NULL, NULL); GST_OBJECT_LOCK (monitor); } if (monitor->priv->providers->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No providers match the current filters"); return FALSE; } gst_bus_set_flushing (monitor->priv->bus, FALSE); again: cookie = monitor->priv->cookie; g_list_free_full (pending, gst_object_unref); pending = NULL; removed = started; started = NULL; for (i = 0; i < monitor->priv->providers->len; i++) { GstDeviceProvider *provider; GList *find; provider = g_ptr_array_index (monitor->priv->providers, i); find = g_list_find (removed, provider); if (find) { /* this was already started, move to started list */ removed = g_list_remove_link (removed, find); started = g_list_concat (started, find); } else { /* not started, add to pending list */ pending = g_list_append (pending, gst_object_ref (provider)); } } g_list_free_full (removed, gst_object_unref); removed = NULL; while (pending) { GstDeviceProvider *provider = pending->data; if (gst_device_provider_can_monitor (provider)) { GST_OBJECT_UNLOCK (monitor); if (!gst_device_provider_start (provider)) goto start_failed; GST_OBJECT_LOCK (monitor); } started = g_list_prepend (started, provider); pending = g_list_delete_link (pending, pending); if (monitor->priv->cookie != cookie) goto again; } monitor->priv->started = TRUE; GST_OBJECT_UNLOCK (monitor); g_list_free_full (started, gst_object_unref); return TRUE; start_failed: { GST_OBJECT_LOCK (monitor); gst_bus_set_flushing (monitor->priv->bus, TRUE); GST_OBJECT_UNLOCK (monitor); while (started) { GstDeviceProvider *provider = started->data; gst_device_provider_stop (provider); gst_object_unref (provider); started = g_list_delete_link (started, started); } return FALSE; } }
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; }
//End VoxOx static void add_purple_buddies_to_groups(JabberStream *js, const char *jid, const char *alias, GSList *groups) { GSList *buddies, *g2, *l; gchar *my_bare_jid; GList *pool = NULL; buddies = purple_find_buddies(js->gc->account, jid); g2 = groups; if(!groups) { if(!buddies) g2 = g_slist_append(g2, g_strdup(_("Buddies"))); else { g_slist_free(buddies); return; } } my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); while(buddies) { PurpleBuddy *b = buddies->data; PurpleGroup *g = purple_buddy_get_group(b); buddies = g_slist_remove(buddies, b); if((l = g_slist_find_custom(g2, g->name, (GCompareFunc)strcmp))) { const char *servernick; /* Previously stored serverside / buddy-supplied alias */ if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"))) serv_got_alias(js->gc, jid, servernick); /* Alias from our roster retrieval */ if(alias && (!b->alias || strcmp(b->alias, alias))) purple_serv_got_private_alias(js->gc, jid, alias); g_free(l->data); g2 = g_slist_delete_link(g2, l); } else { pool = g_list_prepend(pool, b); } } while(g2) { PurpleGroup *g = purple_find_group(g2->data); PurpleBuddy *b = NULL; if (pool) { b = pool->data; pool = g_list_delete_link(pool, pool); } else { b = purple_buddy_new(js->gc->account, jid, alias); } if(!g) { g = purple_group_new(g2->data); purple_blist_add_group(g, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); purple_blist_alias_buddy(b, alias); /* If we just learned about ourself, then fake our status, * because we won't be receiving a normal presence message * about ourself. */ if(!strcmp(b->name, my_bare_jid)) { PurplePresence *gpresence; PurpleStatus *status; gpresence = purple_account_get_presence(js->gc->account); status = purple_presence_get_active_status(gpresence); jabber_presence_fake_to_self(js, status); } g_free(g2->data); g2 = g_slist_delete_link(g2, g2); } while (pool) { PurpleBuddy *b = pool->data; purple_blist_remove_buddy(b); pool = g_list_delete_link(pool, pool); } g_free(my_bare_jid); g_slist_free(buddies); }
int32_t dt_control_merge_hdr_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 ("merging %d image", "merging %d images", total), total ); const guint *jid = dt_control_backgroundjobs_create(darktable.control, 1, message); float *pixels = NULL; float *weight = NULL; int wd = 0, ht = 0, first_imgid = -1; uint32_t filter = 0; float whitelevel = 0.0f; total ++; while(t) { imgid = (long int)t->data; dt_mipmap_buffer_t buf; dt_mipmap_cache_read_get(darktable.mipmap_cache, &buf, imgid, DT_MIPMAP_FULL, DT_MIPMAP_BLOCKING); // just take a copy. also do it after blocking read, so filters and bpp will make sense. const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); dt_image_t image = *img; dt_image_cache_read_release(darktable.image_cache, img); if(image.filters == 0 || image.bpp != sizeof(uint16_t)) { dt_control_log(_("exposure bracketing only works on raw images")); dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); free(pixels); free(weight); goto error; } filter = dt_image_flipped_filter(img); if(buf.size != DT_MIPMAP_FULL) { dt_control_log(_("failed to get raw buffer from image `%s'"), image.filename); dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); free(pixels); free(weight); goto error; } if(!pixels) { first_imgid = imgid; pixels = (float *)malloc(sizeof(float)*image.width*image.height); weight = (float *)malloc(sizeof(float)*image.width*image.height); memset(pixels, 0x0, sizeof(float)*image.width*image.height); memset(weight, 0x0, sizeof(float)*image.width*image.height); wd = image.width; ht = image.height; } else if(image.width != wd || image.height != ht) { dt_control_log(_("images have to be of same size!")); free(pixels); free(weight); dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); goto error; } // if no valid exif data can be found, assume peleng fisheye at f/16, 8mm, with half of the light lost in the system => f/22 const float eap = image.exif_aperture > 0.0f ? image.exif_aperture : 22.0f; const float efl = image.exif_focal_length > 0.0f ? image.exif_focal_length : 8.0f; const float rad = .5f * efl/eap; const float aperture = M_PI * rad * rad; const float iso = image.exif_iso > 0.0f ? image.exif_iso : 100.0f; const float exp = image.exif_exposure > 0.0f ? image.exif_exposure : 1.0f; const float cal = 100.0f/(aperture*exp*iso); // about proportional to how many photons we can expect from this shot: const float photoncnt = 100.0f*aperture*exp/iso; // stupid, but we don't know the real sensor saturation level: uint16_t saturation = 0; for(int k=0; k<wd*ht; k++) saturation = MAX(saturation, ((uint16_t *)buf.buf)[k]); // seems to be around 64500--64700 for 5dm2 // fprintf(stderr, "saturation: %u\n", saturation); whitelevel = fmaxf(whitelevel, saturation*cal); #ifdef _OPENMP #pragma omp parallel for schedule(static) default(none) shared(buf, pixels, weight, wd, ht, saturation) #endif for(int k=0; k<wd*ht; k++) { const uint16_t in = ((uint16_t *)buf.buf)[k]; // weights based on siggraph 12 poster // zijian zhu, zhengguo li, susanto rahardja, pasi fraenti // 2d denoising factor for high dynamic range imaging float w = envelope(in/(float)saturation) * photoncnt; // in case we are black and drop to zero weight, give it something // just so numerics don't collapse. blown out whites are handled below. if(w < 1e-3f && in < saturation/3) w = 1e-3f; pixels[k] += w * in * cal; weight[k] += w; } t = g_list_delete_link(t, t); /* update backgroundjob ui plate */ fraction+=1.0/total; dt_control_backgroundjobs_progress(darktable.control, jid, fraction); dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); } // normalize by white level to make clipping at 1.0 work as expected (to be sure, scale down one more stop, thus the 0.5): #ifdef _OPENMP #pragma omp parallel for schedule(static) default(none) shared(pixels, wd, ht, weight, whitelevel) #endif for(int k=0; k<wd*ht; k++) { // in case w == 0, all pixels were overexposed (too dark would have been clamped to w >= eps above) if(weight[k] < 1e-3f) pixels[k] = 1.f; // mark as blown out. else // normalize: pixels[k] = fmaxf(0.0f, pixels[k]/(whitelevel*weight[k])); } // output hdr as digital negative with exif data. uint8_t exif[65535]; char pathname[DT_MAX_PATH_LEN]; dt_image_full_path(first_imgid, pathname, DT_MAX_PATH_LEN); const int exif_len = dt_exif_read_blob(exif, pathname, 0, first_imgid); char *c = pathname + strlen(pathname); while(*c != '.' && c > pathname) c--; g_strlcpy(c, "-hdr.dng", sizeof(pathname)-(c-pathname)); dt_imageio_write_dng(pathname, pixels, wd, ht, exif, exif_len, filter, 1.0f); dt_control_backgroundjobs_progress(darktable.control, jid, 1.0f); while(*c != '/' && c > pathname) c--; dt_control_log(_("wrote merged hdr `%s'"), c+1); // import new image gchar *directory = g_path_get_dirname((const gchar *)pathname); dt_film_t film; const int filmid = dt_film_new(&film, directory); dt_image_import(filmid, pathname, TRUE); g_free (directory); free(pixels); free(weight); error: dt_control_backgroundjobs_destroy(darktable.control, jid); return 0; }
bool _openslide_try_generic_tiff(openslide_t *osr, TIFF *tiff, struct _openslide_hash *quickhash1) { GList *layer_list = NULL; int32_t layer_count = 0; int32_t *layers = NULL; int32_t current_layer = 0; if (!TIFFIsTiled(tiff)) { goto FAIL; // not tiled } if (osr) { g_hash_table_insert(osr->properties, g_strdup(OPENSLIDE_PROPERTY_NAME_VENDOR), g_strdup("generic-tiff")); } // accumulate tiled layers current_layer = 0; layer_count = 0; do { if (TIFFIsTiled(tiff)) { // get width uint32_t width; if (!TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width)) { // oh no continue; } // confirm it is either the first image, or reduced-resolution if (current_layer != 0) { uint32_t subfiletype; if (!TIFFGetField(tiff, TIFFTAG_SUBFILETYPE, &subfiletype)) { continue; } if (!(subfiletype & FILETYPE_REDUCEDIMAGE)) { continue; } } // verify that we can read this compression (hard fail if not) uint16_t compression; if (!TIFFGetField(tiff, TIFFTAG_COMPRESSION, &compression)) { g_warning("Can't read compression scheme"); goto FAIL; }; if (!TIFFIsCODECConfigured(compression)) { g_warning("Unsupported TIFF compression: %u", compression); goto FAIL; } // push into list struct layer *l = g_slice_new(struct layer); l->layer_number = current_layer; l->width = width; layer_list = g_list_prepend(layer_list, l); layer_count++; } current_layer++; } while (TIFFReadDirectory(tiff)); // sort tiled layers layer_list = g_list_sort(layer_list, width_compare); // copy layers in, while deleting the list layers = g_new(int32_t, layer_count); for (int i = 0; i < layer_count; i++) { struct layer *l = (struct layer *)layer_list->data; layer_list = g_list_delete_link(layer_list, layer_list); layers[i] = l->layer_number; g_slice_free(struct layer, l); } g_assert(layer_list == NULL); // all set, load up the TIFF-specific ops _openslide_add_tiff_ops(osr, tiff, 0, NULL, layer_count, layers, _openslide_generic_tiff_tilereader, quickhash1); return true; FAIL: // free the layer list for (GList *i = layer_list; i != NULL; i = g_list_delete_link(i, i)) { g_slice_free(struct layer, i->data); } return false; }
static bool bucket_list_iter(const char *key, struct obj_vitals *v, struct bucket_list_info *bli) { struct obj_vitals *vitals; if (bli->delim) { const char *post, *end; char *cpfx; int comp_len; gpointer orig_key, orig_val; post = key + bli->pfx_len; end = strstr(post, bli->delim); comp_len = end ? end - post : 0; if (!comp_len) goto no_component; cpfx = g_strndup(key, bli->pfx_len + comp_len); if (!cpfx) return true; /* stop traversal */ if (g_hash_table_lookup_extended(bli->common_pfx, cpfx, &orig_key, &orig_val)) { free(cpfx); return false; /* continue traversal */ } if (bli->last_comp && (bli->last_comp_len == comp_len) && !memcmp(post, bli->last_comp, comp_len)) { GList *ltmp; struct obj_vitals *vp; --bli->n_keys; ltmp = g_list_last(bli->res); vp = ltmp->data; free(vp->key); free(vp); bli->res = g_list_delete_link(bli->res, ltmp); g_hash_table_insert(bli->common_pfx, cpfx, NULL); free(bli->last_comp); bli->last_comp = NULL; return false; /* continue traversal */ } free(cpfx); bli->last_comp = g_strndup(post, comp_len); bli->last_comp_len = comp_len; no_component: do { ; } while(0); } if (bli->n_keys == bli->maxkeys) { bli->next_key = key; bli->trunc = true; return true; /* stop traversal */ } if (!(vitals = malloc(sizeof(struct obj_vitals)))) return false; memcpy(vitals, v, sizeof(struct obj_vitals)); if (!(vitals->key = strdup(key))) { free(vitals); return false; } bli->res = g_list_append(bli->res, vitals); bli->n_keys++; return false; /* continue traversal */ }