static void tip_process(TipModelArgs *args, TipModelControls *controls) { const GwyTipModelPreset *preset; GwyDataField *dfield; GwyDataField *sfield; GQuark quark; gchar label[64]; gint xres, yres; gdouble xstep, ystep, min, max, zrange; gdouble params[2]; preset = gwy_tip_model_get_preset(args->type); g_return_if_fail(preset); tip_model_dialog_update_values(controls, args); /* estimate x and y size */ dfield = controls->tip; quark = gwy_app_get_data_key_for_id(args->object.id); sfield = GWY_DATA_FIELD(gwy_container_get_object(args->object.data, quark)); gwy_data_field_set_xreal(dfield, gwy_data_field_get_xmeasure(sfield) *gwy_data_field_get_xres(dfield)); gwy_data_field_set_yreal(dfield, gwy_data_field_get_ymeasure(sfield) *gwy_data_field_get_yres(dfield)); params[0] = args->nsides; params[1] = args->angle*G_PI/180; gwy_data_field_get_min_max(sfield, &min, &max); zrange = max - min; preset->guess(sfield, zrange, args->radius, params, &xres, &yres); /* process tip */ /* FIXME: this must be solved within guess functions */ xres = CLAMP(xres, 20, 1000); yres = CLAMP(yres, 20, 1000); g_snprintf(label, sizeof(label), _("Tip resolution: %d × %d pixels"), xres, yres); gtk_label_set_text(GTK_LABEL(controls->labsize), label); xstep = gwy_data_field_get_xmeasure(dfield); ystep = gwy_data_field_get_ymeasure(dfield); gwy_data_field_resample(dfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_set_xreal(dfield, xstep*xres); gwy_data_field_set_yreal(dfield, ystep*yres); preset->func(dfield, zrange, args->radius, args->theta*G_PI/180, params); tip_update(controls, args); }
static gboolean prepare_fields(GwyDataField *tipfield, GwyDataField *surface, gint xres, gint yres) { gint xoldres, yoldres; /*set real sizes corresponding to actual data*/ gwy_data_field_set_xreal(tipfield, gwy_data_field_get_xmeasure(surface) *gwy_data_field_get_xres(tipfield)); gwy_data_field_set_yreal(tipfield, gwy_data_field_get_ymeasure(surface) *gwy_data_field_get_yres(tipfield)); /*if user has changed tip size, change it*/ if ((xres != gwy_data_field_get_xres(tipfield)) || (yres != gwy_data_field_get_yres(tipfield))) { xoldres = gwy_data_field_get_xres(tipfield); yoldres = gwy_data_field_get_yres(tipfield); gwy_data_field_resample(tipfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_set_xreal(tipfield, gwy_data_field_get_xreal(tipfield) /xoldres*xres); gwy_data_field_set_yreal(tipfield, gwy_data_field_get_yreal(tipfield) /yoldres*yres); gwy_data_field_clear(tipfield); return FALSE; } return TRUE; }
static void crop_result(GwyDataField *result, GwyDataField *dfield1, GwyDataField *dfield2, GwyOrientation orientation, gint px1, gint py1, gint px2, gint py2) { if (orientation == GWY_ORIENTATION_HORIZONTAL) { gint top = MAX(MAX(py1, py2), 0); gint bot = MIN(MIN(dfield1->yres + py1, dfield2->yres + py2), result->yres); gdouble yreal = (bot - top)*gwy_data_field_get_ymeasure(result); g_return_if_fail(bot > top); gwy_data_field_resize(result, 0, top, result->xres, bot); gwy_data_field_set_yreal(result, yreal); } else { gint left = MAX(MAX(px1, px2), 0); gint right = MIN(MIN(dfield1->xres + px1, dfield2->xres + px2), result->xres); gdouble xreal = (right - left)*gwy_data_field_get_xmeasure(result); g_return_if_fail(right > left); gwy_data_field_resize(result, left, 0, right, result->yres); gwy_data_field_set_xreal(result, xreal); } }
static void immerse_detail_cb(GwyDataChooser *chooser, ImmerseControls *controls) { GwyDataField *dfield, *ifield; GwyContainer *data; GQuark quark; GwyAppDataId *object; object = &controls->args->detail; gwy_data_chooser_get_active_id(chooser, object); gwy_debug("data: %d %d", object->datano, object->id); data = gwy_app_data_browser_get(object->datano); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), GTK_RESPONSE_OK, data != NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), RESPONSE_ESTIMATE, data != NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), RESPONSE_REFINE, data != NULL); if (data) { quark = gwy_app_get_data_key_for_id(object->id); dfield = gwy_container_get_object(data, quark); quark = gwy_app_get_data_key_for_id(controls->args->image.id); data = gwy_app_data_browser_get(controls->args->image.datano); ifield = gwy_container_get_object(data, quark); controls->xmax = (gwy_data_field_get_xreal(ifield) - gwy_data_field_get_xreal(dfield) + gwy_data_field_get_xmeasure(ifield)/2.0); controls->ymax = (gwy_data_field_get_yreal(ifield) - gwy_data_field_get_yreal(dfield) + gwy_data_field_get_ymeasure(ifield)/2.0); } immerse_update_detail_pixbuf(controls); immerse_clamp_detail_offset(controls, controls->args->xpos, controls->args->ypos); if (GTK_WIDGET_DRAWABLE(controls->view)) gtk_widget_queue_draw(controls->view); }
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); }
/* XXX: This replicates straighten_path.c */ static GwyXY* rescale_points(GwySelection *selection, GwyDataField *dfield, gboolean realsquare, gdouble *pdx, gdouble *pdy, gdouble *pqx, gdouble *pqy) { gdouble dx, dy, qx, qy, h; GwyXY *points; guint n, i; dx = gwy_data_field_get_xmeasure(dfield); dy = gwy_data_field_get_ymeasure(dfield); h = MIN(dx, dy); if (realsquare) { qx = h/dx; qy = h/dy; dx = dy = h; } else qx = qy = 1.0; n = gwy_selection_get_data(selection, NULL); points = g_new(GwyXY, n); for (i = 0; i < n; i++) { gdouble xy[2]; gwy_selection_get_object(selection, i, xy); points[i].x = xy[0]/dx; points[i].y = xy[1]/dy; } *pdx = dx; *pdy = dy; *pqx = qx; *pqy = qy; return points; }
static void prof_dialog(ProfArgs *args, GwyContainer *data, GwyDataField *dfield, gint id) { GtkWidget *hbox, *hbox2, *vbox, *label; GwyDataChooser *chooser; GtkTable *table; GtkDialog *dialog; GwyGraph *graph; GwyGraphArea *area; ProfControls controls; gint response; gint row; controls.args = args; controls.psdffield = prof_psdf(dfield, args); controls.modfield = prof_sqrt(controls.psdffield); controls.hx = gwy_data_field_get_xmeasure(dfield)/(2*G_PI); controls.hy = gwy_data_field_get_xmeasure(dfield)/(2*G_PI); controls.dialog = gtk_dialog_new_with_buttons(_("Radial PSDF Section"), NULL, 0, GTK_STOCK_CLEAR, RESPONSE_CLEAR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); dialog = GTK_DIALOG(controls.dialog); gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK); gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_OK, FALSE); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 4); controls.mydata = gwy_container_new(); gwy_container_set_object_by_name(controls.mydata, "/0/data", controls.modfield); g_object_unref(controls.modfield); gwy_container_set_string_by_name(controls.mydata, "/0/base/palette", g_strdup("DFit")); gwy_container_set_enum_by_name(controls.mydata, "/0/base/range-type", GWY_LAYER_BASIC_RANGE_AUTO); gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE, GWY_DATA_ITEM_REAL_SQUARE, 0); controls.view = create_preview(controls.mydata, 0, PREVIEW_SIZE, FALSE); controls.selection = create_vector_layer(GWY_DATA_VIEW(controls.view), 0, "Point", TRUE); gwy_selection_set_max_objects(controls.selection, NLINES); g_object_set(gwy_data_view_get_top_layer(GWY_DATA_VIEW(controls.view)), "draw-as-vector", TRUE, NULL); g_signal_connect_swapped(controls.selection, "changed", G_CALLBACK(prof_selection_changed), &controls); gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4); vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 4); controls.gmodel = gwy_graph_model_new(); g_object_set(controls.gmodel, "title", _("PSDF Section"), "axis-label-bottom", "k", "axis-label-left", "W", NULL); init_graph_model_units(controls.gmodel, controls.psdffield); controls.line = gwy_data_line_new(1, 1.0, FALSE); controls.graph = gwy_graph_new(controls.gmodel); graph = GWY_GRAPH(controls.graph); gtk_widget_set_size_request(controls.graph, GRAPH_WIDTH, -1); gwy_graph_set_axis_visible(graph, GTK_POS_LEFT, FALSE); gwy_graph_set_axis_visible(graph, GTK_POS_RIGHT, FALSE); gwy_graph_set_axis_visible(graph, GTK_POS_TOP, FALSE); gwy_graph_set_axis_visible(graph, GTK_POS_BOTTOM, FALSE); gwy_graph_enable_user_input(graph, FALSE); area = GWY_GRAPH_AREA(gwy_graph_get_area(graph)); gwy_graph_area_enable_user_input(area, FALSE); gtk_box_pack_start(GTK_BOX(vbox), controls.graph, TRUE, TRUE, 0); table = GTK_TABLE(gtk_table_new(4, 4, FALSE)); gtk_table_set_row_spacings(table, 2); gtk_table_set_col_spacings(table, 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(table), FALSE, FALSE, 0); row = 0; controls.resolution = gtk_adjustment_new(controls.args->resolution, MIN_RESOLUTION, MAX_RESOLUTION, 1, 10, 0); gwy_table_attach_hscale(GTK_WIDGET(table), row, _("_Fix res.:"), NULL, controls.resolution, GWY_HSCALE_CHECK | GWY_HSCALE_SQRT); g_signal_connect_swapped(controls.resolution, "value-changed", G_CALLBACK(prof_resolution_changed), &controls); controls.fixres = gwy_table_hscale_get_check(controls.resolution); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.fixres), controls.args->fixres); g_signal_connect_swapped(controls.fixres, "toggled", G_CALLBACK(prof_fixres_changed), &controls); gwy_table_hscale_set_sensitive(controls.resolution, controls.args->fixres); row++; controls.separate = gtk_check_button_new_with_mnemonic(_("_Separate curves")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.separate), args->separate); gtk_table_attach(table, controls.separate, 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); g_signal_connect_swapped(controls.separate, "toggled", G_CALLBACK(prof_separate_changed), &controls); row++; hbox2 = gtk_hbox_new(FALSE, 6); gtk_table_attach(table, hbox2, 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); label = gtk_label_new_with_mnemonic(_("_Interpolation type:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.interpolation = gwy_enum_combo_box_new(gwy_interpolation_type_get_enum(), -1, G_CALLBACK(prof_interpolation_changed), &controls, controls.args->interpolation, TRUE); gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.interpolation); gtk_box_pack_end(GTK_BOX(hbox2), controls.interpolation, FALSE, FALSE, 0); row++; controls.target_hbox = hbox2 = gtk_hbox_new(FALSE, 6); gtk_widget_set_sensitive(hbox2, !args->separate); gtk_table_attach(GTK_TABLE(table), hbox2, 0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); label = gtk_label_new_with_mnemonic(_("Target _graph:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.target_graph = gwy_data_chooser_new_graphs(); chooser = GWY_DATA_CHOOSER(controls.target_graph); gwy_data_chooser_set_none(chooser, _("New graph")); gwy_data_chooser_set_active(chooser, NULL, -1); gwy_data_chooser_set_filter(chooser, filter_target_graphs, &controls, NULL); gwy_data_chooser_set_active_id(chooser, &args->target_graph); gwy_data_chooser_get_active_id(chooser, &args->target_graph); gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.target_graph); gtk_box_pack_end(GTK_BOX(hbox2), controls.target_graph, FALSE, FALSE, 0); g_signal_connect_swapped(controls.target_graph, "changed", G_CALLBACK(target_graph_changed), &controls); row++; gtk_widget_show_all(controls.dialog); do { response = gtk_dialog_run(dialog); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(controls.dialog); case GTK_RESPONSE_NONE: goto finalize; break; case GTK_RESPONSE_OK: break; case RESPONSE_CLEAR: gwy_selection_clear(controls.selection); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); gtk_widget_destroy(controls.dialog); prof_execute(&controls, data); finalize: g_object_unref(controls.psdffield); g_object_unref(controls.mydata); g_object_unref(controls.gmodel); g_object_unref(controls.line); }
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 immerse_search(ImmerseControls *controls, gint search_type) { GwyDataField *dfield, *dfieldsub, *ifield, *iarea; gdouble wr, hr, xpos, ypos, deltax, deltay; gint w, h, xfrom, xto, yfrom, yto, ixres, iyres, col, row; GwyContainer *data; GQuark quark; data = gwy_app_data_browser_get(controls->args->detail.datano); quark = gwy_app_get_data_key_for_id(controls->args->detail.id); dfield = gwy_container_get_object(data, quark); data = gwy_app_data_browser_get(controls->args->image.datano); quark = gwy_app_get_data_key_for_id(controls->args->image.id); ifield = gwy_container_get_object(data, quark); ixres = gwy_data_field_get_xres(ifield); iyres = gwy_data_field_get_yres(ifield); wr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xmeasure(ifield); hr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_ymeasure(ifield); if (wr*hr < 6.0) { g_warning("Detail image is too small for correlation"); return; } w = GWY_ROUND(MAX(wr, 1.0)); h = GWY_ROUND(MAX(hr, 1.0)); gwy_debug("w: %d, h: %d", w, h); g_assert(w <= ixres && h <= iyres); if (search_type == RESPONSE_REFINE) { xfrom = gwy_data_field_rtoj(ifield, controls->args->xpos); yfrom = gwy_data_field_rtoi(ifield, controls->args->ypos); /* Calculate the area we will search the detail in */ deltax = improve_search_window(w, ixres); deltay = improve_search_window(h, iyres); gwy_debug("deltax: %g, deltay: %g", deltax, deltay); xto = MIN(xfrom + w + deltax, ixres); yto = MIN(yfrom + h + deltay, iyres); xfrom = MAX(xfrom - deltax, 0); yfrom = MAX(yfrom - deltay, 0); } else { xfrom = yfrom = 0; xto = ixres; yto = iyres; } gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); /* Cut out only the interesting part from the image data field */ if (xfrom == 0 && yfrom == 0 && xto == ixres && yto == iyres) iarea = g_object_ref(ifield); else iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); dfieldsub = gwy_data_field_new_resampled(dfield, w, h, GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfieldsub, &col, &row); gwy_debug("[c] col: %d, row: %d", col, row); col += xfrom; row += yfrom; xpos = gwy_data_field_jtor(dfieldsub, col + 0.5); ypos = gwy_data_field_itor(dfieldsub, row + 0.5); g_object_unref(iarea); g_object_unref(dfieldsub); gwy_debug("[C] col: %d, row: %d", col, row); /* Upsample and refine */ xfrom = MAX(col - 1, 0); yfrom = MAX(row - 1, 0); xto = MIN(col + w + 1, ixres); yto = MIN(row + h + 1, iyres); gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); wr = gwy_data_field_get_xreal(iarea)/gwy_data_field_get_xmeasure(dfield); hr = gwy_data_field_get_yreal(iarea)/gwy_data_field_get_ymeasure(dfield); gwy_data_field_resample(iarea, GWY_ROUND(wr), GWY_ROUND(hr), GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfield, &col, &row); gwy_debug("[U] col: %d, row: %d", col, row); xpos = gwy_data_field_jtor(dfield, col + 0.5) + gwy_data_field_jtor(ifield, xfrom); ypos = gwy_data_field_itor(dfield, row + 0.5) + gwy_data_field_itor(ifield, yfrom); g_object_unref(iarea); immerse_clamp_detail_offset(controls, xpos, ypos); }
static void put_fields(GwyDataField *dfield1, GwyDataField *dfield2, GwyDataField *result, GwyDataField *outsidemask, GwyMergeBoundaryType boundary, gint px1, gint py1, gint px2, gint py2) { GwyRectangle res_rect; GwyCoord f1_pos; GwyCoord f2_pos; gint w1, w2, h1, h2; gdouble xreal, yreal; gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres); gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres); gwy_debug("result %dx%d", result->xres, result->yres); gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2); gwy_data_field_fill(result, MIN(gwy_data_field_get_min(dfield1), gwy_data_field_get_min(dfield2))); w1 = gwy_data_field_get_xres(dfield1); h1 = gwy_data_field_get_yres(dfield1); w2 = gwy_data_field_get_xres(dfield2); h2 = gwy_data_field_get_yres(dfield2); if (boundary == GWY_MERGE_BOUNDARY_SECOND) { gwy_data_field_area_copy(dfield1, result, 0, 0, w1, h1, px1, py1); gwy_data_field_area_copy(dfield2, result, 0, 0, w2, h2, px2, py2); } else { gwy_data_field_area_copy(dfield2, result, 0, 0, w2, h2, px2, py2); gwy_data_field_area_copy(dfield1, result, 0, 0, w1, h1, px1, py1); } if (outsidemask) { gwy_data_field_fill(outsidemask, 1.0); gwy_data_field_area_clear(outsidemask, px1, py1, w1, h1); gwy_data_field_area_clear(outsidemask, px2, py2, w2, h2); } /* adjust boundary to be as smooth as possible */ if (boundary == GWY_MERGE_BOUNDARY_AVERAGE || boundary == GWY_MERGE_BOUNDARY_INTERPOLATE) { if (px1 < px2) { res_rect.x = px2; res_rect.width = px1 + w1 - px2; } else { res_rect.x = px1; res_rect.width = px2 + w2 - px1; } if (py1 < py2) { res_rect.y = py2; res_rect.height = py1 + h1 - py2; } else { res_rect.y = py1; res_rect.height = py2 + h2 - py1; } res_rect.height = MIN(res_rect.height, MIN(h1, h2)); res_rect.width = MIN(res_rect.width, MIN(w1, w2)); /* This is where the result rectangle is positioned in the fields, * not where the fields themselves are placed! */ f1_pos.x = res_rect.x - px1; f1_pos.y = res_rect.y - py1; f2_pos.x = res_rect.x - px2; f2_pos.y = res_rect.y - py2; merge_boundary(dfield1, dfield2, result, res_rect, f1_pos, f2_pos, boundary); } /* Use the pixels sizes of field 1 -- they must be identical. */ xreal = result->xres * gwy_data_field_get_xmeasure(dfield1); yreal = result->yres * gwy_data_field_get_ymeasure(dfield1); gwy_data_field_set_xreal(result, xreal); gwy_data_field_set_yreal(result, yreal); if (outsidemask) { gwy_data_field_set_xreal(outsidemask, xreal); gwy_data_field_set_yreal(outsidemask, yreal); } }
static void copy_field_to_surface(GwyDataField *field, GwySurface *surface, GwyDataField *mask, GwyMaskingType masking) { gdouble dx = gwy_data_field_get_xmeasure(field), dy = gwy_data_field_get_ymeasure(field); gdouble xoff = 0.5*dx + field->xoff, yoff = 0.5*dy + field->yoff; Surface *priv = surface->priv; guint xres, yres, i, j, n, k; const gdouble *m = NULL, *d; xres = field->xres; yres = field->yres; n = xres*yres; d = field->data; if (mask && masking == GWY_MASK_INCLUDE) { m = mask->data; j = 0; for (k = 0; k < n; k++) { if (m[k] > 0.0) j++; } n = j; } else if (mask && masking == GWY_MASK_EXCLUDE) { m = mask->data; j = 0; for (k = 0; k < n; k++) { if (m[k] <= 0.0) j++; } n = j; } if (surface->n != n) { free_data(surface); surface->n = n; alloc_data(surface); } k = 0; for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { if (!mask || masking == GWY_MASK_IGNORE || (masking == GWY_MASK_INCLUDE && m[i*xres + j] > 0.0) || (masking == GWY_MASK_EXCLUDE && m[i*xres + j] <= 0.0)) { surface->data[k].x = dx*j + xoff; surface->data[k].y = dy*i + yoff; surface->data[k].z = d[i*xres + j]; k++; } } } gwy_data_field_copy_units_to_surface(field, surface); gwy_surface_invalidate(surface); if (n == xres*yres) { priv->cached_ranges = TRUE; priv->min.x = xoff; priv->min.y = yoff; priv->max.x = dx*(xres - 1) + xoff; priv->max.y = dy*(yres - 1) + yoff; } gwy_data_field_get_min_max(field, &priv->min.z, &priv->max.z); }
static gboolean sdfile_export_text(G_GNUC_UNUSED GwyContainer *data, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { enum { SCALE = 65535 }; static const gchar header_format[] = "aBCR-0.0\n" "ManufacID = Gwyddion\n" "CreateDate = %02u%02u%04u%02u%02u\n" "ModDate = %02u%02u%04u%02u%02u\n" "NumPoints = %d\n" "NumProfiles = %d\n" "Xscale = %e\n" "Yscale = %e\n" "Zscale = %e\n" "Zresolution = -1\n" /* FIXME: Dunno */ "Compression = 0\n" "DataType = %d\n" "CheckType = 0\n" "NumDataSet = 1\n" "NanPresent = 0\n" "*\n"; GwyDataField *dfield; const gdouble *d; gint xres, yres, i; const struct tm *ttm; gchar buf[24]; time_t t; FILE *fh; gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (!(fh = g_fopen(filename, "w"))) { err_OPEN_WRITE(error); return FALSE; } d = gwy_data_field_get_data_const(dfield); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); /* We do not keep date information, just use the current time */ time(&t); ttm = localtime(&t); fprintf(fh, header_format, ttm->tm_mday, ttm->tm_mon, ttm->tm_year, ttm->tm_hour, ttm->tm_min, ttm->tm_mday, ttm->tm_mon, ttm->tm_year, ttm->tm_hour, ttm->tm_min, xres, yres, gwy_data_field_get_xmeasure(dfield), gwy_data_field_get_ymeasure(dfield), 1.0, SDF_FLOAT); for (i = 0; i < xres*yres; i++) { g_ascii_formatd(buf, sizeof(buf), "%g", d[i]); fputs(buf, fh); fputc('\n', fh); } fclose(fh); return TRUE; }