Example #1
0
static void
merge_do_none(MergeArgs *args)
{
    GwyDataField *dfield1, *dfield2;
    gint xres1, xres2, yres1, yres2;
    gint px1, py1, px2, py2;
    GwyContainer *data1, *data2;
    GQuark quark;

    data1 = gwy_app_data_browser_get(args->op1.datano);
    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfield1 = GWY_DATA_FIELD(gwy_container_get_object(data1, quark));

    data2 = gwy_app_data_browser_get(args->op2.datano);
    quark = gwy_app_get_data_key_for_id(args->op2.id);
    dfield2 = GWY_DATA_FIELD(gwy_container_get_object(data2, quark));

    xres1 = gwy_data_field_get_xres(dfield1);
    xres2 = gwy_data_field_get_xres(dfield2);
    yres1 = gwy_data_field_get_yres(dfield1);
    yres2 = gwy_data_field_get_yres(dfield2);

    if (args->direction == GWY_MERGE_DIRECTION_UP) {
        px1 = px2 = 0;
        py1 = yres2;
        py2 = 0;
    }
    else if (args->direction == GWY_MERGE_DIRECTION_DOWN) {
        px1 = px2 = 0;
        py1 = 0;
        py2 = yres1;
    }
    else if (args->direction == GWY_MERGE_DIRECTION_LEFT) {
        py1 = py2 = 0;
        px1 = xres2;
        px2 = 0;
    }
    else if (args->direction == GWY_MERGE_DIRECTION_RIGHT) {
        py1 = py2 = 0;
        px1 = 0;
        px2 = xres1;
    }
    else {
        g_assert_not_reached();
    }

    create_merged_field(data1, args->op1.id,
                        dfield1, dfield2,
                        px1, py1, px2, py2,
                        args->boundary, args->direction,
                        args->create_mask, args->crop_to_rectangle);
}
Example #2
0
static gboolean
immerse_data_filter(GwyContainer *data,
                    gint id,
                    gpointer user_data)
{
    GwyAppDataId *object = (GwyAppDataId*)user_data;
    GwyDataField *image, *detail;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    detail = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(object->datano);
    quark = gwy_app_get_data_key_for_id(object->id);
    image = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    /* It does not make sense to immerse itself */
    if (detail == image)
        return FALSE;

    if (gwy_data_field_check_compatibility(image, detail,
                                           GWY_DATA_COMPATIBILITY_LATERAL
                                           | GWY_DATA_COMPATIBILITY_VALUE))
        return FALSE;

    if (gwy_data_field_get_xreal(image) < gwy_data_field_get_xreal(detail)
        || gwy_data_field_get_xreal(image) < gwy_data_field_get_xreal(detail))
        return FALSE;

    return TRUE;
}
Example #3
0
static gboolean
xydenoise_data_filter(GwyContainer *data,
                     gint id,
                     gpointer user_data)
{
    GwyAppDataId *object = (GwyAppDataId*)user_data;
    GwyDataField *op1, *op2;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    op1 = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(object->datano);
    quark = gwy_app_get_data_key_for_id(object->id);
    op2 = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    /* It does not make sense to xydenoiserelate with itself */
    if (op1 == op2)
        return FALSE;

    return !gwy_data_field_check_compatibility(op1, op2,
                                               GWY_DATA_COMPATIBILITY_RES
                                               | GWY_DATA_COMPATIBILITY_REAL
                                               | GWY_DATA_COMPATIBILITY_LATERAL
                                               | GWY_DATA_COMPATIBILITY_VALUE);
}
Example #4
0
static gboolean
maskcor_kernel_filter(GwyContainer *data,
                      gint id,
                      gpointer user_data)
{
    GwyAppDataId *object = (GwyAppDataId*)user_data;
    GwyDataField *kernel, *dfield;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    kernel = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(object->datano);
    quark = gwy_app_get_data_key_for_id(object->id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    if (gwy_data_field_get_xreal(kernel) <= gwy_data_field_get_xreal(dfield)/4
        && gwy_data_field_get_yreal(kernel) <= gwy_data_field_get_yreal(dfield)/4
        && !gwy_data_field_check_compatibility(kernel, dfield,
                                               GWY_DATA_COMPATIBILITY_LATERAL
                                               | GWY_DATA_COMPATIBILITY_VALUE))
        return TRUE;

    return FALSE;
}
Example #5
0
static void
presentation_attach_do(const GwyAppDataId *source,
                       const GwyAppDataId *target)
{
    GwyContainer *sourcedata, *targetdata;
    GwyDataField *dfield;
    GQuark quark;

    sourcedata = gwy_app_data_browser_get(source->datano);
    targetdata = gwy_app_data_browser_get(target->datano);
    quark = gwy_app_get_data_key_for_id(source->id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(sourcedata, quark));
    dfield = gwy_data_field_duplicate(dfield);
    quark = gwy_app_get_show_key_for_id(target->id);
    gwy_app_undo_qcheckpointv(targetdata, 1, &quark);
    gwy_container_set_object(targetdata, quark, dfield);
    g_object_unref(dfield);
}
Example #6
0
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);
}
Example #7
0
static void
immerse_update_detail_pixbuf(ImmerseControls *controls)
{
    GwyContainer *data;
    GwyDataField *dfield;
    GwyGradient *gradient;
    GdkPixbuf *pixbuf;
    const guchar *name;
    gchar *key;
    GQuark quark;
    gint w, h, xres, yres;

    GWY_OBJECT_UNREF(controls->detail);
    data = gwy_app_data_browser_get(controls->args->detail.datano);
    if (!data)
        return;

    quark = gwy_app_get_data_key_for_id(controls->args->detail.id);
    dfield = gwy_container_get_object(data, quark);
    gwy_data_view_coords_real_to_xy(GWY_DATA_VIEW(controls->view),
                                    gwy_data_field_get_xreal(dfield),
                                    gwy_data_field_get_yreal(dfield),
                                    &w, &h);
    gwy_debug("%dx%d", w, h);
    w = MAX(w, 2);
    h = MAX(h, 2);

    key = g_strdup_printf("/%d/base/palette", controls->args->image.id);
    name = NULL;
    data = gwy_app_data_browser_get(controls->args->image.datano);
    gwy_container_gis_string_by_name(data, key, &name);
    g_free(key);
    gradient = gwy_gradients_get_gradient(name);

    /* Handle real-square properly by using an intermediate
     * pixel-square pixbuf with sufficient resolution */
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, xres, yres);
    gwy_pixbuf_draw_data_field(pixbuf, dfield, gradient);
    controls->detail = gdk_pixbuf_scale_simple(pixbuf, w, h, GDK_INTERP_TILES);
    g_object_unref(pixbuf);
}
Example #8
0
/**
 * gwy_app_data_id_verify_spectra:
 * @id: Numerical identifiers of spectra in data managed by the data browser.
 *
 * Checks if numerical spectra identifiers correspond to existing spectra.
 *
 * If either the data contained referenced in @id or the spectra does not
 * exist the structure is cleared to %GWY_APP_DATA_ID_NONE and the function
 * returns %FALSE.  If it represents existing spectra it is kept intact and
 * the function return %TRUE.
 *
 * Returns: Whether @id refers to existing spectra now.
 *
 * Since: 2.41
 **/
gboolean
gwy_app_data_id_verify_spectra(GwyAppDataId *id)
{
    GwyContainer *container;
    GObject *object;
    GQuark quark;

    g_return_val_if_fail(id, FALSE);

    container = gwy_app_data_browser_get(id->datano);
    if (!container)
        return clear_data_id(id);

    quark = gwy_app_get_spectra_key_for_id(id->id);
    if (!gwy_container_gis_object(container, quark, &object))
        return clear_data_id(id);

    return GWY_IS_SPECTRA(object);
}
Example #9
0
static gboolean
tip_blind_source_filter(GwyContainer *data,
                        gint id,
                        gpointer user_data)
{
    GwyAppDataId *object = (GwyAppDataId*)user_data;
    GwyDataField *source, *orig;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    source = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(object->datano);
    quark = gwy_app_get_data_key_for_id(object->id);
    orig = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    return !gwy_data_field_check_compatibility(source, orig,
                                               GWY_DATA_COMPATIBILITY_MEASURE
                                               | GWY_DATA_COMPATIBILITY_LATERAL
                                               | GWY_DATA_COMPATIBILITY_VALUE);
}
Example #10
0
/* compute corelation */
static gboolean
get_score_iteratively(GwyDataField *data_field, GwyDataField *kernel_field,
                      GwyDataField *score, MergeArgs *args)
{
    enum { WORK_PER_UPDATE = 50000000 };
    GwyComputationState *state;
    GwyContainer *data;
    gboolean ok = FALSE;
    int work, wpi;

    work = 0;
    wpi = gwy_data_field_get_xres(kernel_field)
          *gwy_data_field_get_yres(kernel_field);
    wpi = MIN(wpi, WORK_PER_UPDATE);
    state = gwy_data_field_correlate_init(data_field, kernel_field, score);

    /* FIXME */
    data = gwy_app_data_browser_get(args->op1.datano);
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->op1.id),
                       _("Initializing..."));
    gwy_data_field_correlate_iteration(state);
    if (!gwy_app_wait_set_message(_("Correlating...")))
        goto get_score_fail;
    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))
                goto get_score_fail;
        }
    } while (state->state != GWY_COMPUTATION_STATE_FINISHED);
    ok = TRUE;

get_score_fail:
    gwy_data_field_correlate_finalize(state);
    gwy_app_wait_finish();

    return ok;
}
Example #11
0
static gboolean
merge_data_filter(GwyContainer *data,
                  gint id,
                  gpointer user_data)
{
    MergeArgs *args = (MergeArgs*)user_data;
    GwyDataCompatibilityFlags compatflags;
    GwyDataField *op1, *op2;
    gboolean ok;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    op2 = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(args->op1.datano);
    quark = gwy_app_get_data_key_for_id(args->op1.id);
    op1 = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    if (op1 == op2)
        return FALSE;

    compatflags = (GWY_DATA_COMPATIBILITY_MEASURE
                   | GWY_DATA_COMPATIBILITY_LATERAL
                   | GWY_DATA_COMPATIBILITY_VALUE);
    ok = !gwy_data_field_check_compatibility(op1, op2, compatflags);
    if (args->mode == GWY_MERGE_MODE_JOIN) {
        if (args->direction == GWY_MERGE_DIRECTION_UP
                || args->direction == GWY_MERGE_DIRECTION_DOWN) {
            if (op1->xres != op2->xres)
                ok = FALSE;
        }
        if (args->direction == GWY_MERGE_DIRECTION_LEFT
                || args->direction == GWY_MERGE_DIRECTION_RIGHT) {
            if (op1->yres != op2->yres)
                ok = FALSE;
        }
    }
    return ok;
}
Example #12
0
static gboolean
presentation_attach_filter(GwyContainer *source,
                           gint id,
                           gpointer user_data)
{
    const GwyAppDataId *target = (const GwyAppDataId*)user_data;
    GwyDataField *source_dfield, *target_dfield;
    GwyContainer *data;
    GQuark quark;

    quark = gwy_app_get_data_key_for_id(id);
    source_dfield = GWY_DATA_FIELD(gwy_container_get_object(source, quark));

    data = gwy_app_data_browser_get(target->datano);
    quark = gwy_app_get_data_key_for_id(target->id);
    target_dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    return !gwy_data_field_check_compatibility(source_dfield, target_dfield,
                                               GWY_DATA_COMPATIBILITY_RES
                                               | GWY_DATA_COMPATIBILITY_REAL
                                               | GWY_DATA_COMPATIBILITY_LATERAL);
}
Example #13
0
/**
 * gwy_app_add_graph_or_curves:
 * @gmodel: A graph model with curves to add.
 * @data: Data container where the graph would be added.
 * @target_graph: Graph where curves would be added.
 * @colorstep: Curve block size as in gwy_graph_model_append_curves().
 *
 * Puts the curves of a graph to another graph if possible, or adds the graph
 * as new.
 *
 * If the units of @gmodel are compatible with the units of the graph
 * identified by @target_graph the curves are copied to the target graph with
 * gwy_graph_model_append_curves().
 *
 * In all other cases, including when @target_graph does not refer to any
 * existing graph, the graph model is added to @data as a new graph.
 *
 * Either way, the caller usually need to release its own reference afterwards.
 *
 * This function is useful particularly in modules that create graphs and can
 * be run non-interactively.
 *
 * Returns: The numerical identifier of the newly-created graph of one was
 *          created.  Value -1 is returned if curves were added to
 *          @target_graph.
 *
 * Since: 2.41
 **/
gint
gwy_app_add_graph_or_curves(GwyGraphModel *gmodel,
                            GwyContainer *data,
                            const GwyAppDataId *target_graph,
                            gint colorstep)
{
    GwyAppDataId tgtgraph = *target_graph;

    if (gwy_app_data_id_verify_graph(&tgtgraph)) {
        GQuark quark = gwy_app_get_graph_key_for_id(tgtgraph.id);
        GwyContainer *data2 = gwy_app_data_browser_get(tgtgraph.datano);
        GwyGraphModel *target_gmodel = gwy_container_get_object(data2, quark);

        g_return_val_if_fail(GWY_IS_GRAPH_MODEL(target_gmodel), -1);
        if (gwy_graph_model_units_are_compatible(gmodel, target_gmodel)) {
            gwy_graph_model_append_curves(target_gmodel, gmodel, colorstep);
            return -1;
        }
    }
    g_return_val_if_fail(GWY_IS_CONTAINER(data), FALSE);
    return gwy_app_data_browser_add_graph_model(gmodel, data, TRUE);
}
Example #14
0
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;
}
Example #15
0
static void
tip_blind_dialog(TipBlindArgs *args)
{
    GtkWidget *dialog, *table, *hbox, *vbox, *label;
    GwyContainer *data;
    GwyGraphModel *gmodel;
    GwyGraphArea *area;
    TipBlindControls controls;
    GwyPixmapLayer *layer;
    GwyDataField *dfield;
    GQuark quark;
    GwySIUnit *unit;
    gint response, row;

    dialog = gtk_dialog_new_with_buttons(_("Blind Tip Estimation"), NULL, 0,
                                         _("Run _Partial"), RESPONSE_ESTIMATE,
                                         _("Run _Full"), RESPONSE_REFINE,
                                         _("_Reset Tip"), RESPONSE_RESET,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);

    controls.args = args;
    controls.in_update = TRUE;
    controls.good_tip = FALSE;
    controls.dialog = dialog;
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK,
                                      controls.good_tip);

    hbox = gtk_hbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    controls.vxres = 240;
    controls.vyres = 240;
    controls.oldnstripes = args->nstripes;

    /* set initial tip properties */
    data = gwy_app_data_browser_get(args->source.datano);
    quark = gwy_app_get_data_key_for_id(args->source.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    controls.tip = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_resample(controls.tip, args->xres, args->yres,
                            GWY_INTERPOLATION_NONE);
    gwy_data_field_clear(controls.tip);

    /* set up data of rescaled image of the tip */
    controls.vtip = gwy_container_new();
    gwy_app_sync_data_items(data, controls.vtip,
                            args->source.id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            0);

    dfield = gwy_data_field_new_alike(controls.tip, TRUE);
    gwy_data_field_resample(dfield, controls.vxres, controls.vyres,
                            GWY_INTERPOLATION_ROUND);
    gwy_container_set_object_by_name(controls.vtip, "/0/data", dfield);
    g_object_unref(dfield);

    /* set up rescaled image of the tip */
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.view = gwy_data_view_new(controls.vtip);
    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    /* set up tip estimation controls */
    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    gmodel = gwy_graph_model_new();
    controls.graph = gwy_graph_new(gmodel);
    g_object_unref(gmodel);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_LEFT),
                         FALSE);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_BOTTOM),
                         FALSE);
    area = GWY_GRAPH_AREA(gwy_graph_get_area(GWY_GRAPH(controls.graph)));
    gtk_widget_set_no_show_all(gwy_graph_area_get_label(area), TRUE);
    g_signal_connect_after(gwy_graph_area_get_label(area), "map",
                           G_CALLBACK(gtk_widget_hide), NULL);
    gtk_box_pack_start(GTK_BOX(vbox), controls.graph, TRUE, TRUE, 0);

    table = gtk_table_new(13, 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, FALSE, FALSE, 4);
    row = 0;

    controls.data = gwy_data_chooser_new_channels();
    gwy_data_chooser_set_filter(GWY_DATA_CHOOSER(controls.data),
                                tip_blind_source_filter, &args->orig, NULL);
    gwy_data_chooser_set_active_id(GWY_DATA_CHOOSER(controls.data),
                                   &args->source);
    g_signal_connect(controls.data, "changed",
                     G_CALLBACK(data_changed), &args->source);
    gwy_table_attach_hscale(table, row, _("Related _data:"), NULL,
                            GTK_OBJECT(controls.data), GWY_HSCALE_WIDGET);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    label = gtk_label_new(_("Estimated Tip Size"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 4, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.xres = gtk_adjustment_new(args->xres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Width:"), "px", controls.xres, 0);
    g_object_set_data(G_OBJECT(controls.xres), "controls", &controls);
    g_signal_connect(controls.xres, "value-changed",
                     G_CALLBACK(width_changed), &controls);
    row++;

    controls.yres = gtk_adjustment_new(args->yres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Height:"), "px", controls.yres, 0);
    g_object_set_data(G_OBJECT(controls.yres), "controls", &controls);
    g_signal_connect(controls.yres, "value-changed",
                     G_CALLBACK(height_changed), &controls);
    row++;

    controls.same_resolution
        = gtk_check_button_new_with_mnemonic(_("_Same resolution"));
    gtk_table_attach(GTK_TABLE(table), controls.same_resolution,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.same_resolution),
                                 args->same_resolution);
    g_signal_connect(controls.same_resolution, "toggled",
                     G_CALLBACK(same_resolution_changed), &controls);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Options")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.threshold = gtk_adjustment_new(1.0, 0.01, 1000.0, 0.01, 1.0, 0.0);
    controls.threshold_spin
        = gtk_spin_button_new(GTK_ADJUSTMENT(controls.threshold), 0.1, 2);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_spin,
                     2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    label = gtk_label_new_with_mnemonic(_("Noise suppression t_hreshold:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.threshold_spin);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    unit = gwy_data_field_get_si_unit_z(dfield);
    controls.threshold_unit
        = gwy_combo_box_metric_unit_new(G_CALLBACK(thresh_changed),
                                        &controls,
                                        -12, -3, unit, -9);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_unit,
                     3, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.threshold, "value-changed",
                     G_CALLBACK(thresh_changed), &controls);
    sci_entry_set_value(GTK_ADJUSTMENT(controls.threshold),
                        GTK_COMBO_BOX(controls.threshold_unit),
                        args->thresh);
    row++;

    controls.boundaries
                    = gtk_check_button_new_with_mnemonic(_("Use _boundaries"));
    gtk_table_attach(GTK_TABLE(table), controls.boundaries,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.boundaries),
                                                 args->use_boundaries);
    g_signal_connect(controls.boundaries, "toggled",
                     G_CALLBACK(bound_changed), args);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Stripes")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.nstripes = gtk_adjustment_new(args->nstripes,
                                           MIN_STRIPES, MAX_STRIPES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Split to stripes:"), NULL,
                            controls.nstripes, GWY_HSCALE_CHECK);
    controls.split_to_stripes = gwy_table_hscale_get_check(controls.nstripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 !args->split_to_stripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 args->split_to_stripes);
    g_signal_connect(controls.split_to_stripes, "toggled",
                     G_CALLBACK(split_to_stripes_changed), &controls);
    g_signal_connect(controls.nstripes, "value-changed",
                     G_CALLBACK(nstripes_changed), &controls);
    row++;

    controls.stripeno = gtk_adjustment_new(1, 1, args->nstripes, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Preview stripe:"), NULL,
                            controls.stripeno, GWY_HSCALE_DEFAULT);
    g_signal_connect(controls.stripeno, "value-changed",
                     G_CALLBACK(stripeno_changed), &controls);
    row++;

    controls.plot_size_graph
        = gtk_check_button_new_with_mnemonic(_("Plot size _graph"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.plot_size_graph),
                                 args->plot_size_graph);
    gtk_table_attach(GTK_TABLE(table), controls.plot_size_graph,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.plot_size_graph, "toggled",
                     G_CALLBACK(plot_size_graph_changed), &controls);
    row++;

    controls.create_images
        = gtk_check_button_new_with_mnemonic(_("Create tip i_mages"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.create_images),
                                 args->create_images);
    gtk_table_attach(GTK_TABLE(table), controls.create_images,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.create_images, "toggled",
                     G_CALLBACK(create_images_changed), &controls);
    row++;

    controls.tipdone = FALSE;
    controls.in_update = FALSE;
    split_to_stripes_changed(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                             &controls);
    gtk_widget_show_all(dialog);

    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            tip_blind_dialog_abandon(&controls);
            tip_blind_save_args(gwy_app_settings_get(), args);
            return;
            break;

            case GTK_RESPONSE_OK:
            tip_blind_save_args(gwy_app_settings_get(), args);
            tip_blind_do(&controls, args);
            break;

            case RESPONSE_RESET:
            reset(&controls, args);
            break;

            case RESPONSE_ESTIMATE:
            tip_blind_run(&controls, args, FALSE);
            break;

            case RESPONSE_REFINE:
            tip_blind_run(&controls, args, TRUE);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    gtk_widget_destroy(dialog);
    tip_blind_dialog_abandon(&controls);

    return;
}
Example #16
0
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);
}
Example #17
0
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);
}
Example #18
0
static void
merge_do_correlate(MergeArgs *args)
{
    GwyDataField *dfield1, *dfield2;
    GwyDataField *correlation_data, *correlation_kernel, *correlation_score;
    GwyRectangle cdata, kdata;
    gint max_col, max_row;
    gint xres1, xres2, yres1, yres2;
    GwyMergeDirectionType real_dir = args->direction;
    GwyMergeBoundaryType real_boundary = args->boundary;
    gint px1, py1, px2, py2;
    GwyContainer *data1, *data2;
    GQuark quark;

    data1 = gwy_app_data_browser_get(args->op1.datano);
    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfield1 = GWY_DATA_FIELD(gwy_container_get_object(data1, quark));

    data2 = gwy_app_data_browser_get(args->op2.datano);
    quark = gwy_app_get_data_key_for_id(args->op2.id);
    dfield2 = GWY_DATA_FIELD(gwy_container_get_object(data2, quark));

    if ((dfield1->xres*dfield1->yres) < (dfield2->xres*dfield2->yres)) {
        GWY_SWAP(GwyDataField*, dfield1, dfield2);
        if (args->direction == GWY_MERGE_DIRECTION_UP)
            real_dir = GWY_MERGE_DIRECTION_DOWN;
        else if (args->direction == GWY_MERGE_DIRECTION_DOWN)
            real_dir = GWY_MERGE_DIRECTION_UP;
        else if (args->direction == GWY_MERGE_DIRECTION_LEFT)
            real_dir = GWY_MERGE_DIRECTION_RIGHT;
        else if (args->direction == GWY_MERGE_DIRECTION_RIGHT)
            real_dir = GWY_MERGE_DIRECTION_LEFT;
        else
            g_return_if_reached();

        if (args->boundary == GWY_MERGE_BOUNDARY_FIRST)
            real_boundary = GWY_MERGE_BOUNDARY_SECOND;
        else if (args->boundary == GWY_MERGE_BOUNDARY_SECOND)
            real_boundary = GWY_MERGE_BOUNDARY_FIRST;
    }

    xres1 = gwy_data_field_get_xres(dfield1);
    xres2 = gwy_data_field_get_xres(dfield2);
    yres1 = gwy_data_field_get_yres(dfield1);
    yres2 = gwy_data_field_get_yres(dfield2);

    /*cut data for correlation*/
    switch (real_dir) {
    case GWY_MERGE_DIRECTION_UP:
        cdata.x = 0;
        cdata.y = 0;
        cdata.width = xres1;
        cdata.height = yres1/2;
        kdata.width = MIN(xres2, cdata.width/2);
        kdata.height = MIN(yres2, cdata.height/3);
        kdata.x = MAX(0, xres2/2 - kdata.width/2);
        kdata.y = MAX(0, yres2 - cdata.height/3);
        break;

    case GWY_MERGE_DIRECTION_DOWN:
        cdata.x = 0;
        cdata.y = yres1 - (yres1/2);
        cdata.width = xres1;
        cdata.height = yres1/2;
        kdata.width = MIN(xres2, cdata.width/2);
        kdata.height = MIN(yres2, cdata.height/3);
        kdata.x = MAX(0, xres2/2 - kdata.width/2);
        kdata.y = 0;
        break;

    case GWY_MERGE_DIRECTION_RIGHT:
        cdata.x = xres1 - (xres1/2);
        cdata.y = 0;
        cdata.width = xres1/2;
        cdata.height = yres1;
        kdata.width = MIN(xres2, cdata.width/3);
        kdata.height = MIN(yres2, cdata.height/2);
        kdata.x = 0;
        kdata.y = MAX(0, yres2/2 - kdata.height/2);
        break;

    case GWY_MERGE_DIRECTION_LEFT:
        cdata.x = 0;
        cdata.y = 0;
        cdata.width = xres1/2;
        cdata.height = yres1;
        kdata.width = MIN(xres2, cdata.width/3);
        kdata.height = MIN(yres2, cdata.height/2);
        kdata.x = MAX(0, xres2 - cdata.width/3);
        kdata.y = MAX(0, yres2/2 - kdata.height/2);
        break;

    default:
        g_assert_not_reached();
        break;
    }

    correlation_data = gwy_data_field_area_extract(dfield1,
                       cdata.x,
                       cdata.y,
                       cdata.width,
                       cdata.height);
    correlation_kernel = gwy_data_field_area_extract(dfield2,
                         kdata.x,
                         kdata.y,
                         kdata.width,
                         kdata.height);
    correlation_score = gwy_data_field_new_alike(correlation_data, FALSE);

    /* get appropriate correlation score */
    if (!get_score_iteratively(correlation_data, correlation_kernel,
                               correlation_score, args))
        goto end;

    find_score_maximum(correlation_score, &max_col, &max_row);
    gwy_debug("c: %d %d %dx%d  k: %d %d %dx%d res: %d %d",
              cdata.x,
              cdata.y,
              cdata.width,
              cdata.height,
              kdata.x,
              kdata.y,
              kdata.width,
              kdata.height,
              max_col, max_row);

    px1 = 0;
    px2 = (max_col - (kdata.width-1)/2) + cdata.x - kdata.x;
    py1 = 0;
    py2 = (max_row - (kdata.height-1)/2) + cdata.y - kdata.y;
    if (px2 < 0) {
        px1 = -px2;
        px2 = 0;
    }
    if (py2 < 0) {
        py1 = -py2;
        py2 = 0;
    }

    create_merged_field(data1, args->op1.id,
                        dfield1, dfield2,
                        px1, py1, px2, py2,
                        real_boundary, real_dir,
                        args->create_mask, args->crop_to_rectangle);

end:
    g_object_unref(correlation_data);
    g_object_unref(correlation_kernel);
    g_object_unref(correlation_score);
}
Example #19
0
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);
}
Example #20
0
static gboolean
immerse_dialog(ImmerseArgs *args)
{
    ImmerseControls controls;
    GwyContainer *data;
    GtkDialog *dialog;
    GtkWidget *table, *chooser, *hbox, *alignment, *label, *button, *vbox;
    GtkTooltips *tooltips;
    GdkDisplay *display;
    GwyDataField *dfield;
    gint response, row, id;
    gboolean ok;

    memset(&controls, 0, sizeof(ImmerseControls));
    controls.args = args;

    tooltips = gwy_app_get_tooltips();

    controls.dialog = gtk_dialog_new_with_buttons(_("Immerse Detail"),
                                                  NULL, 0, NULL);
    dialog = GTK_DIALOG(controls.dialog);
    button = gtk_dialog_add_button(dialog, _("_Locate"), RESPONSE_ESTIMATE);
    gtk_tooltips_set_tip(tooltips, button,
                         _("Locate detail by full image correlation search"),
                         NULL);
    button = gtk_dialog_add_button(dialog, _("_Improve"), RESPONSE_REFINE);
    gtk_tooltips_set_tip(tooltips, button,
                         _("Improve detail position by "
                           "correlation search in neighborhood"), NULL);
    gtk_dialog_add_button(dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button(dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
    gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);

    hbox = gtk_hbox_new(FALSE, 2);
    gtk_box_pack_start(GTK_BOX(dialog->vbox), hbox, FALSE, FALSE, 4);

    /* Preview */
    data = gwy_app_data_browser_get(args->image.datano);
    id = args->image.id;
    dfield = gwy_container_get_object(data, gwy_app_get_data_key_for_id(id));
    controls.vf
        = gwy_data_field_get_value_format_xy(dfield,
                                             GWY_SI_UNIT_FORMAT_VFMARKUP, NULL);

    controls.mydata = gwy_container_new();
    gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield);
    gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            0);
    gwy_container_set_boolean_by_name(controls.mydata, "/0/data/realsquare",
                                      TRUE);
    controls.view = create_preview(controls.mydata, 0, PREVIEW_SIZE, FALSE);
    alignment = GTK_WIDGET(gtk_alignment_new(0.5, 0, 0, 0));
    gtk_container_add(GTK_CONTAINER(alignment), controls.view);
    gtk_box_pack_start(GTK_BOX(hbox), alignment, FALSE, FALSE, 4);

    g_signal_connect_after(controls.view, "expose-event",
                           G_CALLBACK(immerse_view_expose), &controls);
    g_signal_connect(controls.view, "button-press-event",
                     G_CALLBACK(immerse_view_button_press), &controls);
    g_signal_connect(controls.view, "button-release-event",
                     G_CALLBACK(immerse_view_button_release), &controls);
    g_signal_connect(controls.view, "motion-notify-event",
                     G_CALLBACK(immerse_view_motion_notify), &controls);

    vbox = gtk_vbox_new(FALSE, 8);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    /* Parameters table */
    table = gtk_table_new(8, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 4);
    row = 0;

    /* Detail to immerse */
    chooser = gwy_data_chooser_new_channels();
    gwy_data_chooser_set_active_id(GWY_DATA_CHOOSER(chooser), &args->detail);
    gwy_data_chooser_set_filter(GWY_DATA_CHOOSER(chooser),
                                immerse_data_filter, &args->image, NULL);
    gwy_data_chooser_get_active_id(GWY_DATA_CHOOSER(chooser), &args->detail);
    g_signal_connect(chooser, "changed",
                     G_CALLBACK(immerse_detail_cb), &controls);
    gwy_table_attach_hscale(table, row, _("_Detail image:"), NULL,
                            GTK_OBJECT(chooser), GWY_HSCALE_WIDGET_NO_EXPAND);
    row++;

    /* Detail position */
    label = gtk_label_new(_("Position:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 1, row, row+1, GTK_FILL, 0, 0, 0);

    controls.pos = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(controls.pos), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), controls.pos,
                     1, 3, row, row+1, GTK_FILL, 0, 0, 0);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    /* Sampling */
    label = gtk_label_new(_("Result Sampling"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.sampling
        = gwy_radio_buttons_createl(G_CALLBACK(immerse_sampling_changed),
                                    &controls,
                                    args->sampling,
                                    _("_Upsample large image"),
                                    GWY_IMMERSE_SAMPLING_UP,
                                    _("_Downsample detail"),
                                    GWY_IMMERSE_SAMPLING_DOWN,
                                    NULL);

    row = gwy_radio_buttons_attach_to_table(controls.sampling, GTK_TABLE(table),
                                            4, row);
    gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

    /* Leveling */
    label = gtk_label_new(_("Detail Leveling"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.leveling
        = gwy_radio_buttons_createl(G_CALLBACK(immerse_leveling_changed),
                                    &controls,
                                    args->leveling,
                                    gwy_sgettext("levelling|_None"),
                                    GWY_IMMERSE_LEVEL_NONE,
                                    _("_Mean value"), GWY_IMMERSE_LEVEL_MEAN,
                                    NULL);

    row = gwy_radio_buttons_attach_to_table(controls.leveling, GTK_TABLE(table),
                                            4, row);
    gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

    /* Draw frame */
    controls.draw_frame = gtk_check_button_new_with_mnemonic(_("Show _frame"));
    gtk_table_attach(GTK_TABLE(table), controls.draw_frame,
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.draw_frame),
                                 args->draw_frame);
    g_signal_connect(controls.draw_frame, "toggled",
                     G_CALLBACK(immerse_frame_toggled), &controls);

    gtk_widget_show_all(controls.dialog);
    display = gtk_widget_get_display(controls.dialog);
    controls.near_cursor = gdk_cursor_new_for_display(display, GDK_FLEUR);
    controls.move_cursor = gdk_cursor_new_for_display(display, GDK_CROSS);
    immerse_detail_cb(GWY_DATA_CHOOSER(chooser), &controls);

    ok = FALSE;
    do {
        response = gtk_dialog_run(dialog);
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            case GTK_RESPONSE_NONE:
            immerse_controls_destroy(&controls);
            immerse_save_args(gwy_app_settings_get(), args);
            return FALSE;
            break;

            case RESPONSE_ESTIMATE:
            case RESPONSE_REFINE:
            immerse_search(&controls, response);
            break;

            case GTK_RESPONSE_OK:
            ok = TRUE;
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (!ok);

    immerse_controls_destroy(&controls);
    immerse_save_args(gwy_app_settings_get(), args);

    return TRUE;
}
Example #21
0
static void
merge_do_join(MergeArgs *args)
{
    GwyDataField *dfield1, *dfield2;
    gint xres1, xres2, yres1, yres2;
    gint maxover, i, off = 0;
    gint px1, py1, px2, py2;
    GwyContainer *data1, *data2;
    gdouble s, smin = G_MAXDOUBLE;
    GwyMergeBoundaryType real_boundary = args->boundary;
    GwyMergeDirectionType real_dir = args->direction;
    GQuark quark;

    data1 = gwy_app_data_browser_get(args->op1.datano);
    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfield1 = GWY_DATA_FIELD(gwy_container_get_object(data1, quark));

    data2 = gwy_app_data_browser_get(args->op2.datano);
    quark = gwy_app_get_data_key_for_id(args->op2.id);
    dfield2 = GWY_DATA_FIELD(gwy_container_get_object(data2, quark));

    /* Reduce joining to two cases. */
    if (args->direction == GWY_MERGE_DIRECTION_UP
            || args->direction == GWY_MERGE_DIRECTION_LEFT) {
        GWY_SWAP(GwyDataField*, dfield1, dfield2);

        if (args->direction == GWY_MERGE_DIRECTION_UP)
            real_dir = GWY_MERGE_DIRECTION_DOWN;
        else if (args->direction == GWY_MERGE_DIRECTION_LEFT)
            real_dir = GWY_MERGE_DIRECTION_RIGHT;
        else {
            g_assert_not_reached();
        }

        if (args->boundary == GWY_MERGE_BOUNDARY_FIRST)
            real_boundary = GWY_MERGE_BOUNDARY_SECOND;
        else if (args->boundary == GWY_MERGE_BOUNDARY_SECOND)
            real_boundary = GWY_MERGE_BOUNDARY_FIRST;
    }

    xres1 = gwy_data_field_get_xres(dfield1);
    yres1 = gwy_data_field_get_yres(dfield1);
    xres2 = gwy_data_field_get_xres(dfield2);
    yres2 = gwy_data_field_get_yres(dfield2);

    if (real_dir == GWY_MERGE_DIRECTION_DOWN) {
        g_return_if_fail(xres1 == xres2);
        maxover = 2*MIN(yres1, yres2)/5;
        for (i = 1; i <= maxover; i++) {
            s = get_row_difference(dfield1, 0, yres1 - i,
                                   dfield2, 0, 0,
                                   xres1, i);
            if (s < smin) {
                off = i;
                smin = s;
            }
        }
        /* Turn one-pixel overlap to no overlap. */
        if (off == 1)
            off = 0;
        px1 = px2 = 0;
        py1 = 0;
        py2 = yres1 - off;
    }
    else if (real_dir == GWY_MERGE_DIRECTION_RIGHT) {
        g_return_if_fail(yres1 == yres2);
        maxover = 2*MIN(xres1, xres2)/5;
        for (i = 1; i <= maxover; i++) {
            s = get_column_difference(dfield1, xres1 - i, 0,
                                      dfield2, 0, 0,
                                      i, yres1);
            if (s < smin) {
                off = i;
                smin = s;
            }
        }
        /* Turn one-pixel overlap to no overlap. */
        if (off == 1)
            off = 0;
        py1 = py2 = 0;
        px1 = 0;
        px2 = xres1 - off;
    }
    else {
        g_assert_not_reached();
    }

    create_merged_field(data1, args->op1.id,
                        dfield1, dfield2,
                        px1, py1, px2, py2,
                        real_boundary, real_dir,
                        FALSE, FALSE);
}