static void poly_level_do(GwyContainer *data, GwyDataField *dfield, GwyDataField *mfield, GQuark quark, gint oldid, const PolyLevelArgs *args) { GwyDataField *bg = NULL; gint newid; gwy_app_undo_qcheckpointv(data, 1, &quark); if (args->do_extract) bg = gwy_data_field_new_alike(dfield, TRUE); if (mfield && args->masking != GWY_MASK_IGNORE) poly_level_do_with_mask(dfield, mfield, dfield, bg, args); else if (args->independent) poly_level_do_independent(dfield, dfield, bg, args->col_degree, args->row_degree); else poly_level_do_maximum(dfield, dfield, bg, args->max_degree); if (!args->do_extract) return; newid = gwy_app_data_browser_add_data_field(bg, data, TRUE); g_object_unref(bg); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); }
static void psdflp(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *lpsdf; PSDFLPArgs args; gboolean ok; gint id, newid; g_return_if_fail(run & PSDFLP_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield); psdflp_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = psdflp_dialog(&args); psdflp_save_args(gwy_app_settings_get(), &args); if (!ok) return; } lpsdf = gwy_data_field_new(1, 1, 1.0, 1.0, FALSE); psdflp_do(&args, dfield, lpsdf); newid = gwy_app_data_browser_add_data_field(lpsdf, data, TRUE); g_object_unref(lpsdf); gwy_app_set_data_field_title(data, newid, "Log-phi PSDF"); gwy_app_channel_log_add_proc(data, id, newid); }
static void mask_extract(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GwySIUnit *siunit; gint oldid, newid; g_return_if_fail(run & MASKOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_MASK_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield); dfield = gwy_data_field_duplicate(dfield); gwy_data_field_clamp(dfield, 0.0, 1.0); /* Other functions should set the units correctly, but do not trust them */ siunit = gwy_si_unit_new(""); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); g_object_unref(dfield); gwy_app_set_data_field_title(data, newid, _("Mask")); gwy_app_channel_log_add_proc(data, oldid, newid); }
static void dwt(GwyContainer *data, GwyRunType run) { GtkWidget *dialog; GwyDataField *dfield; GwyDataLine *wtcoefs; DWTArgs args; gboolean ok; gint xsize, ysize, newsize, newid, oldid, i; g_return_if_fail(run & DWT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield); xsize = gwy_data_field_get_xres(dfield); ysize = gwy_data_field_get_yres(dfield); if (xsize != ysize) { dialog = gtk_message_dialog_new (gwy_app_find_window_for_channel(data, oldid), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("%s: Data must be square."), "DWT"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } for (newsize = 1, i = xsize-1; i; i >>= 1, newsize <<= 1) ; dwt_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = dwt_dialog(&args, xsize, newsize); dwt_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfield = gwy_data_field_new_resampled(dfield, newsize, newsize, args.interp); gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield)); wtcoefs = GWY_DATA_LINE(gwy_data_line_new(10, 10, TRUE)); wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet); gwy_data_field_dwt(dfield, wtcoefs, 1, 4); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); g_object_unref(dfield); gwy_app_set_data_field_title(data, newid, _("DWT")); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_PALETTE, 0); g_object_unref(wtcoefs); }
static void create_merged_field(GwyContainer *data, gint id1, GwyDataField *dfield1, GwyDataField *dfield2, gint px1, gint py1, gint px2, gint py2, GwyMergeBoundaryType boundary, GwyMergeDirectionType dir, gboolean create_mask, gboolean crop_to_rectangle) { GwyDataField *result, *outsidemask = NULL; gint newxres, newyres, newid; gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres); gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres); gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2); result = gwy_data_field_new_alike(dfield1, FALSE); newxres = MAX(dfield1->xres + px1, dfield2->xres + px2); newyres = MAX(dfield1->yres + py1, dfield2->yres + py2); gwy_data_field_resample(result, newxres, newyres, GWY_INTERPOLATION_NONE); if (create_mask && !crop_to_rectangle) { outsidemask = gwy_data_field_new_alike(result, FALSE); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(outsidemask), NULL); } put_fields(dfield1, dfield2, result, outsidemask, boundary, px1, py1, px2, py2); if (crop_to_rectangle) { GwyOrientation orientation = GWY_ORIENTATION_HORIZONTAL; if (dir == GWY_MERGE_DIRECTION_UP || dir == GWY_MERGE_DIRECTION_DOWN) orientation = GWY_ORIENTATION_VERTICAL; crop_result(result, dfield1, dfield2, orientation, px1, py1, px2, py2); } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0); newid = gwy_app_data_browser_add_data_field(result, data, TRUE); gwy_app_set_data_field_title(data, newid, _("Merged images")); gwy_app_sync_data_items(data, data, id1, newid, FALSE, GWY_DATA_ITEM_PALETTE, GWY_DATA_ITEM_MASK_COLOR, GWY_DATA_ITEM_RANGE, 0); if (outsidemask) { if (gwy_data_field_get_max(outsidemask) > 0.0) { GQuark quark = gwy_app_get_mask_key_for_id(newid); gwy_container_set_object(data, quark, outsidemask); } g_object_unref(outsidemask); } gwy_app_channel_log_add_proc(data, -1, newid); g_object_unref(result); }
static void tip_model_do(TipModelArgs *args, TipModelControls *controls) { gint newid; newid = gwy_app_data_browser_add_data_field(controls->tip, args->object.data, TRUE); g_object_unref(controls->tip); gwy_app_sync_data_items(args->object.data, args->object.data, args->object.id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(args->object.data, newid, _("Modelled tip")); controls->tipdone = TRUE; }
static void presentation_extract(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GQuark quark; gint oldid, newid; g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_ID, &oldid, GWY_APP_SHOW_FIELD_KEY, &quark, GWY_APP_SHOW_FIELD, &dfield, 0); g_return_if_fail(dfield && quark); dfield = gwy_data_field_duplicate(dfield); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); g_object_unref(dfield); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, NULL); gwy_app_channel_log_add_proc(data, oldid, newid); }
static void immerse_do(ImmerseArgs *args) { GwyDataField *resampled, *image, *detail, *result; GwyContainer *data; gint newid; gint kxres, kyres; gint x, y, w, h; gdouble iavg, davg; GQuark quark; data = gwy_app_data_browser_get(args->image.datano); quark = gwy_app_get_data_key_for_id(args->image.id); image = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); data = gwy_app_data_browser_get(args->detail.datano); quark = gwy_app_get_data_key_for_id(args->detail.id); detail = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); davg = gwy_data_field_get_avg(detail); kxres = gwy_data_field_get_xres(detail); kyres = gwy_data_field_get_yres(detail); switch (args->sampling) { case GWY_IMMERSE_SAMPLING_DOWN: result = gwy_data_field_duplicate(image); x = gwy_data_field_rtoj(image, args->xpos); y = gwy_data_field_rtoi(image, args->ypos); w = GWY_ROUND(gwy_data_field_get_xreal(detail) /gwy_data_field_get_xmeasure(image)); h = GWY_ROUND(gwy_data_field_get_yreal(detail) /gwy_data_field_get_ymeasure(image)); w = MAX(w, 1); h = MAX(h, 1); gwy_debug("w: %d, h: %d", w, h); resampled = gwy_data_field_new_resampled(detail, w, h, GWY_INTERPOLATION_LINEAR); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, w, h); gwy_data_field_add(resampled, iavg - davg); } gwy_data_field_area_copy(resampled, result, 0, 0, w, h, x, y); g_object_unref(resampled); break; case GWY_IMMERSE_SAMPLING_UP: w = GWY_ROUND(gwy_data_field_get_xreal(image) /gwy_data_field_get_xmeasure(detail)); h = GWY_ROUND(gwy_data_field_get_yreal(image) /gwy_data_field_get_ymeasure(detail)); gwy_debug("w: %d, h: %d", w, h); result = gwy_data_field_new_resampled(image, w, h, GWY_INTERPOLATION_LINEAR); x = gwy_data_field_rtoj(result, args->xpos); y = gwy_data_field_rtoi(result, args->ypos); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, kxres, kyres); gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); gwy_data_field_area_add(result, x, y, kxres, kyres, iavg - davg); } else gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); break; default: g_return_if_reached(); break; } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0); newid = gwy_app_data_browser_add_data_field(result, data, TRUE); gwy_app_set_data_field_title(data, newid, _("Immersed detail")); g_object_unref(result); gwy_app_channel_log_add_proc(data, args->image.id, newid); }
static void sphrev(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *background = NULL; Sphrev1DArgs args; gint oldid, newid; GQuark dquark; gdouble xr, yr; gboolean ok = TRUE; g_return_if_fail(run & SPHREV_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield && dquark); sphrev_load_args(gwy_app_settings_get(), &args); /* FIXME: this is bogus for non-square pixels anyway */ xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield); yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield); args.pixelsize = hypot(xr, yr); args.valform = gwy_data_field_get_value_format_xy(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); gwy_debug("pixelsize = %g, vf = (%g, %d, %s)", args.pixelsize, args.valform->magnitude, args.valform->precision, args.valform->units); if (run == GWY_RUN_INTERACTIVE) { ok = sphrev_dialog(&args); sphrev_save_args(gwy_app_settings_get(), &args); } gwy_si_unit_value_format_free(args.valform); if (!ok) return; gwy_app_undo_qcheckpointv(data, 1, &dquark); switch (args.direction) { case SPHREV_HORIZONTAL: background = sphrev_horizontal(&args, dfield); break; case SPHREV_VERTICAL: background = sphrev_vertical(&args, dfield); break; case SPHREV_BOTH: { GwyDataField *tmp; background = sphrev_horizontal(&args, dfield); tmp = sphrev_vertical(&args, dfield); gwy_data_field_sum_fields(background, background, tmp); g_object_unref(tmp); gwy_data_field_multiply(background, 0.5); } break; default: g_assert_not_reached(); break; } gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (!args.do_extract) { g_object_unref(background); return; } newid = gwy_app_data_browser_add_data_field(background, data, TRUE); g_object_unref(background); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); }
static void median(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *background = NULL; MedianBgArgs args; gint oldid, newid; GQuark dquark; gdouble xr, yr; gboolean ok = TRUE; g_return_if_fail(run & MEDIANBG_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield && dquark); median_load_args(gwy_app_settings_get(), &args); /* FIXME: this is bogus for non-square pixels anyway */ xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield); yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield); args.pixelsize = hypot(xr, yr); args.valform = gwy_data_field_get_value_format_xy(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); gwy_debug("pixelsize = %g, vf = (%g, %d, %s)", args.pixelsize, args.valform->magnitude, args.valform->precision, args.valform->units); if (run == GWY_RUN_INTERACTIVE) { ok = median_dialog(&args); median_save_args(gwy_app_settings_get(), &args); } gwy_si_unit_value_format_free(args.valform); if (!ok) return; gwy_app_wait_start(gwy_app_find_window_for_channel(data, oldid), _("Median-leveling...")); background = median_background(GWY_ROUND(args.size), dfield); gwy_app_wait_finish(); if (!background) return; gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); gwy_app_channel_log_add_proc(data, oldid, oldid); if (!args.do_extract) { g_object_unref(background); return; } newid = gwy_app_data_browser_add_data_field(background, data, TRUE); g_object_unref(background); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); gwy_app_channel_log_add(data, oldid, newid, NULL, NULL); }
static void run_noninteractive(NoiseSynthArgs *args, const GwyDimensionArgs *dimsargs, GwyContainer *data, GwyDataField *dfield, gint oldid, GQuark quark) { GwySIUnit *siunit; gboolean replace = dimsargs->replace && dfield; gboolean add = dimsargs->add && dfield; gint newid; if (args->randomize) args->seed = g_random_int() & 0x7fffffff; if (replace) { /* Always take a reference so that we can always unref. */ g_object_ref(dfield); gwy_app_undo_qcheckpointv(data, 1, &quark); if (!add) gwy_data_field_clear(dfield); gwy_app_channel_log_add_proc(data, oldid, oldid); } else { if (add) dfield = gwy_data_field_duplicate(dfield); else { gdouble mag = pow10(dimsargs->xypow10) * dimsargs->measure; dfield = gwy_data_field_new(dimsargs->xres, dimsargs->yres, mag*dimsargs->xres, mag*dimsargs->yres, TRUE); siunit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string(siunit, dimsargs->xyunits); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_set_from_string(siunit, dimsargs->zunits); } } noise_synth_do(args, dimsargs, dfield); if (replace) gwy_data_field_data_changed(dfield); else { if (data) { newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); if (oldid != -1) gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); } else { newid = 0; data = gwy_container_new(); gwy_container_set_object(data, gwy_app_get_data_key_for_id(newid), dfield); gwy_app_data_browser_add(data); gwy_app_data_browser_reset_visibility(data, GWY_VISIBILITY_RESET_SHOW_ALL); g_object_unref(data); } gwy_app_set_data_field_title(data, newid, _("Generated")); gwy_app_channel_log_add_proc(data, add ? oldid : -1, newid); } g_object_unref(dfield); }
static void level_grains_do(const LevelGrainsArgs *args, GwyContainer *data, GQuark dquark, gint id, GwyDataField *dfield, GwyDataField *mfield) { GwyDataField *buffer, *background, *invmask; gdouble error, cor, maxerr, lastfrac, frac, starterr; gdouble *heights, *bgdata; gint *grains; gboolean cancelled = FALSE; gint i, xres, yres, ngrains; xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); if (!ngrains) { g_free(grains); return; } heights = g_new(gdouble, ngrains+1); gwy_data_field_grains_get_values(dfield, heights, ngrains, grains, args->base); heights[0] = 0.0; background = gwy_data_field_new_alike(dfield, FALSE); bgdata = gwy_data_field_get_data(background); for (i = 0; i < xres*yres; i++) bgdata[i] = -heights[grains[i]]; invmask = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(invmask, -1.0); gwy_data_field_add(invmask, 1.0); maxerr = gwy_data_field_get_rms(dfield)/1.0e4; gwy_app_wait_start(gwy_app_find_window_for_channel(data, id), _("Laplace interpolation...")); g_free(heights); g_free(grains); buffer = gwy_data_field_new_alike(background, TRUE); gwy_data_field_correct_average(background, invmask); cor = 0.2; error = 0.0; lastfrac = 0.0; starterr = 0.0; for (i = 0; i < 5000; i++) { gwy_data_field_correct_laplace_iteration(background, invmask, buffer, cor, &error); if (error < maxerr) break; if (!i) starterr = error; frac = log(error/starterr)/log(maxerr/starterr); if ((i/(gdouble)(5000)) > frac) frac = i/(gdouble)(5000); if (lastfrac > frac) frac = lastfrac; if (!gwy_app_wait_set_fraction(frac)) { cancelled = TRUE; break; } lastfrac = frac; } gwy_app_wait_finish(); if (!cancelled) { gwy_data_field_invert(background, FALSE, FALSE, TRUE); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (args->do_extract) { gint newid; newid = gwy_app_data_browser_add_data_field(background, data, TRUE); gwy_app_sync_data_items(data, data, id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); } } g_object_unref(buffer); g_object_unref(invmask); g_object_unref(background); }
static gboolean xydenoise_do(XYdenoiseArgs *args) { GwyContainer *data; GwyDataField *dfieldx, *rx, *ix, *dfieldy, *ry, *iy, *result, *iresult; gint i, newid, xres, yres; gdouble *rxdata, *rydata, *ixdata, *iydata; GwyWindowingType window = GWY_WINDOWING_NONE; GwyInterpolationType interp = GWY_INTERPOLATION_LINEAR; GQuark quark; data = gwy_app_data_browser_get(args->op1.datano); gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->op1.id), _("Initializing...")); quark = gwy_app_get_data_key_for_id(args->op1.id); dfieldx = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); data = gwy_app_data_browser_get(args->op2.datano); quark = gwy_app_get_data_key_for_id(args->op2.id); dfieldy = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); xres = gwy_data_field_get_xres(dfieldx); yres = gwy_data_field_get_yres(dfieldy); result = gwy_data_field_new_alike(dfieldx, TRUE); iresult = gwy_data_field_new_alike(dfieldx, TRUE); rx = gwy_data_field_new_alike(dfieldx, TRUE); ix = gwy_data_field_new_alike(dfieldx, TRUE); ry = gwy_data_field_new_alike(dfieldx, TRUE); iy = gwy_data_field_new_alike(dfieldx, TRUE); gwy_app_wait_set_fraction(0.1); gwy_app_wait_set_message(_("Computing forward FFTs...")); gwy_data_field_2dfft(dfieldx, NULL, rx, ix, window, GWY_TRANSFORM_DIRECTION_FORWARD, interp, FALSE, 0); gwy_data_field_2dfft(dfieldy, NULL, ry, iy, window, GWY_TRANSFORM_DIRECTION_FORWARD, interp, FALSE, 0); rxdata = gwy_data_field_get_data(rx); rydata = gwy_data_field_get_data(ry); ixdata = gwy_data_field_get_data(ix); iydata = gwy_data_field_get_data(iy); gwy_app_wait_set_fraction(0.3); gwy_app_wait_set_message(_("Computing image...")); for (i = 0; i < xres*yres; i++) { gdouble xmodule = sqrt(rxdata[i]*rxdata[i] + ixdata[i]*ixdata[i]); gdouble xphase = atan2(ixdata[i],rxdata[i]); gdouble ymodule = sqrt(rydata[i]*rydata[i] + iydata[i]*iydata[i]); /*gdouble yphase = atan2(iydata[i],rydata[i]);*/ rxdata[i] = MIN(xmodule, ymodule)*cos(xphase); ixdata[i] = MIN(xmodule, ymodule)*sin(xphase); } gwy_app_wait_set_fraction(0.7); gwy_app_wait_set_message(_("Computing backward FFT...")); gwy_data_field_2dfft(rx, ix, result, iresult, window, GWY_TRANSFORM_DIRECTION_BACKWARD, interp, FALSE, 0); gwy_app_wait_set_fraction(0.9); data = gwy_app_data_browser_get(args->op1.datano); newid = gwy_app_data_browser_add_data_field(result, data, TRUE); gwy_app_sync_data_items(data, data, args->op1.id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Denoised")); gwy_app_channel_log_add_proc(data, -1, newid); gwy_app_wait_finish(); g_object_unref(result); g_object_unref(iresult); g_object_unref(rx); g_object_unref(ix); g_object_unref(ry); g_object_unref(iy); return TRUE; }
static void dwt_denoise(GwyContainer *data, GwyRunType run) { GtkWidget *dialog; GwyDataField *dfield; GwyDataLine *wtcoefs; DWTDenoiseArgs args; gboolean ok; gint xsize, ysize, newsize; gint oldid, newid; g_return_if_fail(run & DWT_DENOISE_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield); xsize = gwy_data_field_get_xres(dfield); ysize = gwy_data_field_get_yres(dfield); if (xsize != ysize) { dialog = gtk_message_dialog_new (GTK_WINDOW(gwy_app_data_window_get_current()), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("%s: Data must be square."), _("DWT Denoise")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } dwt_denoise_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = dwt_denoise_dialog(&args); dwt_denoise_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfield = gwy_data_field_duplicate(dfield); newsize = gwy_fft_find_nice_size(xsize); gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield)); gwy_data_field_resample(dfield, newsize, newsize, GWY_INTERPOLATION_BILINEAR); wtcoefs = gwy_data_line_new(10, 10, TRUE); wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet); gwy_data_field_dwt_denoise(dfield, wtcoefs, TRUE, 20, args.method); if (args.preserve) gwy_data_field_resample(dfield, xsize, ysize, args.interp); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); gwy_app_copy_data_items(data, data, oldid, newid, GWY_DATA_ITEM_GRADIENT, GWY_DATA_ITEM_MASK_COLOR, 0); g_object_unref(dfield); gwy_app_set_data_field_title(data, newid, _("DWT denoised")); g_object_unref(wtcoefs); }
static void cwt(GwyContainer *data, GwyRunType run) { GtkWidget *dialog; GwyDataField *dfield; CWTArgs args; gboolean ok; gint xsize, ysize; gint newsize; gint oldid, newid; g_return_if_fail(run & CWT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield); xsize = gwy_data_field_get_xres(dfield); ysize = gwy_data_field_get_yres(dfield); if (xsize != ysize) { dialog = gtk_message_dialog_new (gwy_app_find_window_for_channel(data, oldid), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("%s: Data must be square."), "CWT"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } cwt_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = cwt_dialog(&args); cwt_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfield = gwy_data_field_duplicate(dfield); newsize = gwy_fft_find_nice_size(xsize); gwy_data_field_resample(dfield, newsize, newsize, args.interp); gwy_data_field_cwt(dfield, args.interp, args.scale, args.wavelet); if (args.preserve) gwy_data_field_resample(dfield, xsize, ysize, args.interp); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, GWY_DATA_ITEM_MASK_COLOR, 0); g_object_unref(dfield); gwy_app_set_data_field_title(data, newid, _("CWT")); }
static void scale(GwyContainer *data, GwyRunType run) { GwyDataField *dfields[3]; GQuark quark; gint oldid, newid; ScaleArgs args; gboolean ok; g_return_if_fail(run & SCALE_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0, GWY_APP_MASK_FIELD, dfields + 1, GWY_APP_SHOW_FIELD, dfields + 2, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfields[0]); scale_load_args(gwy_app_settings_get(), &args); args.org_xres = gwy_data_field_get_xres(dfields[0]); args.org_yres = gwy_data_field_get_yres(dfields[0]); args.xres = ROUND(args.ratio*args.org_xres); if (args.proportional) args.aspectratio = 1.0; args.yres = ROUND(args.aspectratio*args.ratio*args.org_yres); if (run == GWY_RUN_INTERACTIVE) { ok = scale_dialog(&args); scale_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfields[0] = gwy_data_field_new_resampled(dfields[0], ROUND(args.xres), ROUND(args.yres), args.interp); if (dfields[1]) { dfields[1] = gwy_data_field_new_resampled(dfields[1], ROUND(args.xres), ROUND(args.yres), args.interp); } if (dfields[2]) { dfields[2] = gwy_data_field_new_resampled(dfields[2], ROUND(args.xres), ROUND(args.yres), args.interp); } newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE); g_object_unref(dfields[0]); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, GWY_DATA_ITEM_RANGE, GWY_DATA_ITEM_MASK_COLOR, 0); if (dfields[1]) { quark = gwy_app_get_mask_key_for_id(newid); gwy_container_set_object(data, quark, dfields[1]); g_object_unref(dfields[1]); } if (dfields[2]) { quark = gwy_app_get_show_key_for_id(newid); gwy_container_set_object(data, quark, dfields[2]); g_object_unref(dfields[2]); } gwy_app_set_data_field_title(data, newid, _("Scaled Data")); }
static void rotate(GwyContainer *data, GwyRunType run) { GwyDataField *dfields[3]; GQuark quark; gint oldid, newid; RotateArgs args; gboolean ok; g_return_if_fail(run & ROTATE_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0, GWY_APP_MASK_FIELD, dfields + 1, GWY_APP_SHOW_FIELD, dfields + 2, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfields[0]); rotate_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = rotate_dialog(&args, data); rotate_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfields[0] = gwy_data_field_duplicate(dfields[0]); rotate_datafield(dfields[0], &args); if (dfields[1]) { GwyInterpolationType interp = args.interp; dfields[1] = gwy_data_field_duplicate(dfields[1]); args.interp = GWY_INTERPOLATION_ROUND; rotate_datafield(dfields[1], &args); args.interp = interp; } if (dfields[2]) { dfields[2] = gwy_data_field_duplicate(dfields[2]); rotate_datafield(dfields[2], &args); } newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE); g_object_unref(dfields[0]); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, GWY_DATA_ITEM_RANGE, GWY_DATA_ITEM_MASK_COLOR, 0); if (dfields[1]) { quark = gwy_app_get_mask_key_for_id(newid); gwy_container_set_object(data, quark, dfields[1]); g_object_unref(dfields[1]); } if (dfields[2]) { quark = gwy_app_get_show_key_for_id(newid); gwy_container_set_object(data, quark, dfields[2]); g_object_unref(dfields[2]); } gwy_app_set_data_field_title(data, newid, _("Rotated Data")); gwy_app_channel_log_add_proc(data, oldid, newid); }
static void deposit_dialog(DepositArgs *args, GwyContainer *data, GwyDataField *dfield, gint id) { GtkWidget *dialog, *table, *hbox, *label, *pivot; DepositControls controls; gint response; GwyPixmapLayer *layer; gint row, newid; GwyDataField *rfield; controls.args = args; dialog = gtk_dialog_new_with_buttons(_("Deposit spherical particles"), NULL, 0, NULL); gtk_dialog_add_action_widget(GTK_DIALOG(dialog), gwy_stock_like_button_new(_("_Start"), GTK_STOCK_EXECUTE), RESPONSE_PREVIEW); gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Reset"), RESPONSE_RESET); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); controls.dialog = dialog; hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 4); controls.mydata = gwy_container_duplicate_by_prefix(data, "/0/data/", "/0/base/palette", "/0/base/range-type", "/0/base/", NULL); gwy_container_set_object_by_name(controls.mydata, "/0/data", gwy_data_field_duplicate(dfield)); controls.old_dfield = gwy_data_field_duplicate(dfield); controls.view = gwy_data_view_new(controls.mydata); layer = gwy_layer_basic_new(); g_object_set(layer, "data-key", "/0/data", "gradient-key", "/0/base/palette", "range-type-key", "/0/base/range-type", "min-max-key", "/0/base", NULL); gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data"); gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer); gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE); gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4); table = gtk_table_new(10, 4, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 4); row = 0; gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Deposition parameters:")), 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; table_attach_threshold(table, &row, _("_Size"), &controls.size, args->size, &controls); pivot = gwy_table_hscale_get_scale(controls.size); controls.value_size = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.value_size), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.value_size, 2, 3, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(controls.size, "value-changed", G_CALLBACK(update_threshold_size), &controls); gwy_widget_sync_sensitivity(pivot, controls.value_size); controls.format_size = gwy_data_field_get_value_format_z(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); label = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_label_set_markup(GTK_LABEL(label), controls.format_size->units); gtk_table_attach(GTK_TABLE(table), label, 3, 4, row, row+1, GTK_FILL, 0, 0, 0); gwy_widget_sync_sensitivity(pivot, label); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; /* table_attach_threshold(table, &row, _("_Distribution width"), &controls.width, args->width, &controls); pivot = gwy_table_hscale_get_scale(controls.width); controls.value_width = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.value_width), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.value_width, 2, 3, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(controls.width, "value-changed", G_CALLBACK(update_threshold_width), &controls); gwy_widget_sync_sensitivity(pivot, controls.value_width); controls.format_width = gwy_data_field_get_value_format_z(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); label = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_label_set_markup(GTK_LABEL(label), controls.format_width->units); gtk_table_attach(GTK_TABLE(table), label, 3, 4, row, row+1, GTK_FILL, 0, 0, 0); gwy_widget_sync_sensitivity(pivot, label); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; */ table_attach_threshold(table, &row, _("_Coverage:"), &controls.coverage, args->coverage, &controls); table_attach_threshold(table, &row, _("_Revise after settle"), &controls.revise, args->revise, &controls); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); deposit_invalidate(&controls); update_threshold_size(&controls); //update_threshold_width(&controls); /* finished initializing, allow instant updates */ controls.in_init = FALSE; /* show initial preview if instant updates are on */ gtk_widget_show_all(dialog); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: deposit_dialog_update_values(&controls, args); gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: g_object_unref(controls.mydata); gwy_si_unit_value_format_free(controls.format_size); //gwy_si_unit_value_format_free(controls.format_width); return; break; case GTK_RESPONSE_OK: break; case RESPONSE_RESET: *args = deposit_defaults; deposit_dialog_update_controls(&controls, args); controls.in_init = TRUE; preview(&controls, args); controls.in_init = FALSE; break; case RESPONSE_PREVIEW: deposit_dialog_update_values(&controls, args); preview(&controls, args); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); deposit_dialog_update_values(&controls, args); gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE, GWY_DATA_ITEM_MASK_COLOR, 0); gtk_widget_destroy(dialog); gwy_si_unit_value_format_free(controls.format_size); //gwy_si_unit_value_format_free(controls.format_width); if (args->computed) { rfield = gwy_container_get_object_by_name(controls.mydata, "/0/data"); newid = gwy_app_data_browser_add_data_field(rfield, data, TRUE); gwy_app_sync_data_items(data, data, id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, GWY_DATA_ITEM_MASK_COLOR, GWY_DATA_ITEM_REAL_SQUARE, GWY_DATA_ITEM_SELECTIONS, 0); gwy_app_set_data_field_title(data, newid, _("Particles")); g_object_unref(controls.mydata); } }
static void maskcor_do(MaskcorArgs *args) { enum { WORK_PER_UPDATE = 50000000 }; GwyDataField *dfield, *kernel, *retfield, *score; GwyContainer *data, *kerneldata; GwyComputationState *state; GQuark quark; gint newid, work, wpi; kerneldata = gwy_app_data_browser_get(args->kernel.datano); quark = gwy_app_get_data_key_for_id(args->kernel.id); kernel = GWY_DATA_FIELD(gwy_container_get_object(kerneldata, quark)); data = gwy_app_data_browser_get(args->data.datano); quark = gwy_app_get_data_key_for_id(args->data.id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); retfield = gwy_data_field_new_alike(dfield, FALSE); /* FIXME */ if (args->method == GWY_CORRELATION_NORMAL) { gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->data.id), _("Initializing...")); state = gwy_data_field_correlate_init(dfield, kernel, retfield); gwy_app_wait_set_message(_("Correlating...")); work = 0; wpi = gwy_data_field_get_xres(kernel)*gwy_data_field_get_yres(kernel); wpi = MIN(wpi, WORK_PER_UPDATE); do { gwy_data_field_correlate_iteration(state); work += wpi; if (work > WORK_PER_UPDATE) { work -= WORK_PER_UPDATE; if (!gwy_app_wait_set_fraction(state->fraction)) { gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); g_object_unref(retfield); return; } } } while (state->state != GWY_COMPUTATION_STATE_FINISHED); gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); } else gwy_data_field_correlate(dfield, kernel, retfield, args->method); /* score - do new data with score */ if (args->result == GWY_MASKCOR_SCORE) { score = gwy_data_field_duplicate(retfield); newid = gwy_app_data_browser_add_data_field(score, data, TRUE); gwy_app_sync_data_items(data, data, args->data.id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Correlation score")); g_object_unref(score); gwy_app_channel_log_add_proc(data, args->data.id, newid); } else { /* add mask */ quark = gwy_app_get_mask_key_for_id(args->data.id); gwy_app_undo_qcheckpointv(data, 1, &quark); if (args->result == GWY_MASKCOR_OBJECTS) plot_correlated(retfield, gwy_data_field_get_xres(kernel), gwy_data_field_get_yres(kernel), args->threshold); else if (args->result == GWY_MASKCOR_MAXIMA) gwy_data_field_threshold(retfield, args->threshold, 0.0, 1.0); gwy_container_set_object(data, quark, retfield); gwy_app_channel_log_add_proc(data, args->data.id, args->data.id); } g_object_unref(retfield); }