static void modify_channel_for_preview(GwyContainer *data, gint id, gboolean plane_level, gboolean row_level) { GwyDataField *field; gdouble a, bx, by; if (!plane_level && !row_level) return; if (!gwy_container_gis_object(data, gwy_app_get_data_key_for_id(id), &field) || !GWY_IS_DATA_FIELD(field)) return; if (plane_level) { gwy_data_field_fit_plane(field, &a, &bx, &by); gwy_data_field_plane_level(field, a, bx, by); } if (row_level) { guint xres = gwy_data_field_get_xres(field); guint yres = gwy_data_field_get_yres(field); gdouble *row = gwy_data_field_get_data(field); gdouble *diffs = g_new(gdouble, xres); guint i, j; for (i = 1; i < yres; i++) { gdouble *prev = row; gdouble median; row += xres; for (j = 0; j < xres; j++) diffs[j] = prev[j] - row[j]; median = gwy_math_median(xres, diffs); for (j = 0; j < xres; j++) row[j] += median; } g_free(diffs); } }
static void tilt(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GQuark quark; TiltArgs args; gboolean ok; g_return_if_fail(run & TILT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &quark, 0); g_return_if_fail(dfield); tilt_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = tilt_dialog(&args, dfield); tilt_save_args(gwy_app_settings_get(), &args); if (!ok) return; } gwy_app_undo_qcheckpointv(data, 1, &quark); { /* Use negative values since the module says `Tilt', * not `Remove tilt' */ double bx = -args.dx*gwy_data_field_get_xmeasure(dfield); double by = -args.dy*gwy_data_field_get_ymeasure(dfield); double c = -0.5*(bx*gwy_data_field_get_xres(dfield) + by*gwy_data_field_get_yres(dfield)); gwy_data_field_plane_level(dfield, c, bx, by); } gwy_data_field_data_changed(dfield); }
static void do_level(GwyContainer *data, GwyRunType run, LevelMethod level_type, const gchar *dialog_title) { GwyDataField *dfield; GwyDataField *mfield; LevelArgs args; gdouble c, bx, by; GQuark quark; gint id; g_return_if_fail(run & LEVEL_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &quark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield && quark); load_args(gwy_app_settings_get(), &args); if (run != GWY_RUN_IMMEDIATE && mfield) { gboolean ok = level_dialog(&args, dialog_title); save_args(gwy_app_settings_get(), &args); if (!ok) return; } if (args.masking == GWY_MASK_IGNORE) mfield = NULL; if (mfield) { if (args.masking == GWY_MASK_EXCLUDE) { mfield = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(mfield, -1.0); gwy_data_field_add(mfield, 1.0); } else g_object_ref(mfield); } gwy_app_undo_qcheckpoint(data, quark, NULL); if (mfield) gwy_data_field_area_fit_plane(dfield, mfield, 0, 0, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), &c, &bx, &by); else gwy_data_field_fit_plane(dfield, &c, &bx, &by); switch (level_type) { case LEVEL_SUBTRACT: c = -0.5*(bx*gwy_data_field_get_xres(dfield) + by*gwy_data_field_get_yres(dfield)); gwy_data_field_plane_level(dfield, c, bx, by); break; case LEVEL_ROTATE: bx = gwy_data_field_rtoj(dfield, bx); by = gwy_data_field_rtoi(dfield, by); gwy_data_field_plane_rotate(dfield, atan2(bx, 1), atan2(by, 1), GWY_INTERPOLATION_LINEAR); gwy_debug("b = %g, alpha = %g deg, c = %g, beta = %g deg", bx, 180/G_PI*atan2(bx, 1), by, 180/G_PI*atan2(by, 1)); break; default: g_assert_not_reached(); break; } gwy_app_channel_log_add_proc(data, id, id); gwy_data_field_data_changed(dfield); gwy_object_unref(mfield); }