Beispiel #1
0
/**
 * gwy_tip_estimate_partial:
 * @tip: Tip data to be refined (allocated).
 * @surface: Surface data.
 * @threshold: Threshold for noise supression.
 * @use_edges: Whether use also edges of image.
 * @count: Where to store the number of places that produced refinements to.
 * @set_fraction: Function that sets fraction to output (or %NULL).
 * @set_message: Function that sets message to output (or %NULL).
 *
 * Performs partial blind estimation algorithm published by Villarrubia. This
 * function converts all fields into form requested by "morph_lib.c" library,
 * that is almost identical with original Villarubia's library. Note that the
 * threshold value must be chosen sufficently high value to supress small
 * fluctulations due to noise (that would lead to very sharp tip) but
 * sufficiently low value to put algorithm at work. A value similar to 1/10000
 * of surface range can be good. Otherwise we recommend to start with zero
 * threshold and increase it slowly to observe changes and choose right value.
 *
 * Returns: Estimated tip.  May return %NULL if aborted.
 **/
GwyDataField*
gwy_tip_estimate_partial(GwyDataField *tip,
                         GwyDataField *surface,
                         gdouble threshold,
                         gboolean use_edges,
                         gint *count,
                         GwySetFractionFunc set_fraction,
                         GwySetMessageFunc set_message)
{
    gint **ftip;
    gint **fsurface;
    gdouble tipmin, surfacemin, step;
    gint cnt;

    if (set_message && !set_message(N_("Converting fields")))
        return NULL;

    tipmin = gwy_data_field_get_min(tip);
    surfacemin = gwy_data_field_get_min(surface);
    step = (gwy_data_field_get_max(surface)-surfacemin)/10000;

    ftip = i_datafield_to_field(tip, TRUE,  tipmin, step);
    fsurface = i_datafield_to_field(surface, FALSE, surfacemin, step);

    if (set_message && !set_message(N_("Starting partial estimation"))) {
        _gwy_morph_lib_ifreematrix(ftip, tip->xres);
        _gwy_morph_lib_ifreematrix(fsurface, surface->xres);
        return NULL;
    }

    cnt = _gwy_morph_lib_itip_estimate0(fsurface, surface->yres, surface->xres,
                                        tip->yres, tip->xres,
                                        tip->yres/2, tip->xres/2,
                                        ftip, threshold/step, use_edges,
                                        set_fraction, set_message);
    if (cnt == -1 || (set_fraction && !set_fraction(0.0))) {
        _gwy_morph_lib_ifreematrix(ftip, tip->xres);
        _gwy_morph_lib_ifreematrix(fsurface, surface->xres);
        return NULL;
    }
    gwy_debug("Converting fields");
    if (set_message)
        set_message(N_("Converting fields"));

    tip = i_field_to_datafield(ftip, tip, tipmin, step);
    gwy_data_field_add(tip, -gwy_data_field_get_min(tip));

    _gwy_morph_lib_ifreematrix(ftip, tip->xres);
    _gwy_morph_lib_ifreematrix(fsurface, surface->xres);
    if (count)
        *count = cnt;

    return tip;
}
Beispiel #2
0
static void
gwy_layer_basic_get_fixed_range(GwyLayerBasic *basic_layer,
                                GwyContainer *container,
                                GwyDataField *data_field,
                                gdouble *rmin,
                                gdouble *rmax)
{
    const gchar *prefix;
    gchar *key;
    guint len;

    if (!basic_layer->fixed_key) {
        gwy_data_field_get_min_max(data_field, rmin, rmax);
        return;
    }

    prefix = g_quark_to_string(basic_layer->fixed_key);
    len = strlen(prefix);
    key = g_newa(gchar, len + sizeof("/min"));

    g_stpcpy(g_stpcpy(key, prefix), "/min");
    if (!gwy_container_gis_double_by_name(container, key, rmin))
        *rmin = gwy_data_field_get_min(data_field);

    strcpy(key + len + 1, "max");
    if (!gwy_container_gis_double_by_name(container, key, rmax))
        *rmax = gwy_data_field_get_max(data_field);
}
Beispiel #3
0
static GdkPixbuf*
gwy_layer_basic_paint(GwyPixmapLayer *layer)
{
    GwyDataField *data_field;
    GwyLayerBasic *basic_layer;
    GwyContainer *data;
    gdouble min = 0.0, max = 0.0;
    gboolean fixedmin, fixedmax;
    gboolean fixedrange = FALSE;

    gwy_debug(" ");
    g_return_val_if_fail(GWY_IS_LAYER_BASIC(layer), NULL);
    basic_layer = GWY_LAYER_BASIC(layer);
    data = GWY_DATA_VIEW_LAYER(layer)->data;

    /* TODO Container */
    if (!gwy_container_gis_object_by_name(data, "/0/show",
                                          (GObject**)&data_field)) {
        data_field
            = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data"));
        fixedrange = TRUE;
    }
    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), layer->pixbuf);
    if (fixedrange) {
        fixedmin = gwy_container_gis_double_by_name(data, "/0/base/min", &min);
        fixedmax = gwy_container_gis_double_by_name(data, "/0/base/max", &max);
        if (fixedmin || fixedmax) {
            if (!fixedmin)
                min = gwy_data_field_get_min(data_field);
            if (!fixedmax)
                max = gwy_data_field_get_max(data_field);
        }
        else
            fixedrange = FALSE;
    }
    /* XXX */
    /*if (GWY_LAYER_BASIC(layer)->changed)*/ {
        if (fixedrange)
            gwy_pixbuf_draw_data_field_with_range(layer->pixbuf, data_field,
                                                  basic_layer->gradient,
                                                  min, max);
        else
            gwy_pixbuf_draw_data_field(layer->pixbuf, data_field,
                                       basic_layer->gradient);
        basic_layer->changed = FALSE;
    }

    return layer->pixbuf;
}
Beispiel #4
0
static void
fix_zero(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield;
    GQuark quark;

    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,
                                     0);
    g_return_if_fail(dfield && quark);
    gwy_app_undo_qcheckpoint(data, quark, NULL);
    gwy_data_field_add(dfield, -gwy_data_field_get_min(dfield));
    gwy_data_field_data_changed(dfield);
}
Beispiel #5
0
static void
rotate_datafield(GwyDataField *dfield,
                 RotateArgs *args)
{
    gint xres, yres, xborder, yborder;
    gdouble xreal, yreal, phi, min;
    GwyDataField *df;

    if (!args->expand) {
        gwy_data_field_rotate(dfield, args->angle, args->interp);
        return;
    }

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    min = gwy_data_field_get_min(dfield);
    phi = args->angle;
    xborder = fabs(xres/2.0 * cos(phi)) + fabs(yres/2.0 * sin(phi));
    xborder -= xres/2;
    yborder = fabs(yres/2.0 * cos(phi)) + fabs(xres/2.0 * sin(phi));
    yborder -= yres/2;
    df = gwy_data_field_new(xres + fabs(2*xborder), yres + fabs(2*yborder), 1.0, 1.0,
                            FALSE);
    gwy_data_field_fill(df, min);
    gwy_data_field_area_copy(dfield, df, 0, 0, xres, yres, fabs(xborder), fabs(yborder));
    gwy_data_field_rotate(df, args->angle, args->interp);
    gwy_data_field_resample(dfield, xres + 2*xborder, yres + 2*yborder,
                            GWY_INTERPOLATION_NONE);
    if (xborder <= 0)
        gwy_data_field_area_copy(df, dfield, fabs(2*xborder), 0, xres + 2*xborder, yres + 2*yborder, 0, 0);
    else {
          if (yborder <= 0)
              gwy_data_field_area_copy(df, dfield, 0, fabs(2*yborder), xres + 2*xborder, yres + 2*yborder, 0, 0);
          else
            gwy_data_field_area_copy(df, dfield, 0, 0, xres + 2*xborder, yres + 2*yborder, 0, 0);
    }
    gwy_data_field_set_xreal(dfield, xreal*(xres + 2.0*xborder)/xres);
    gwy_data_field_set_yreal(dfield, yreal*(yres + 2.0*yborder)/yres);
    g_object_unref(df);
}
Beispiel #6
0
static GwyContainer*
surffile_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    SurfFile surffile;
    GwyContainer *meta, *container = NULL;
    guchar *buffer = NULL;
    const guchar *p;
    gsize expected_size, size = 0;
    GError *err = NULL;
    gchar signature[12];
    gdouble max, min;
    gint add = 0;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        g_clear_error(&err);
        return NULL;
    }

    if (size < SURF_HEADER_SIZE + 2) {
        err_TOO_SHORT(error);
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    p = buffer;

    get_CHARARRAY(signature, &p);
    if (strncmp(signature, "DIGITAL SURF", 12) != 0) {
        err_FILE_TYPE(error, "Surf");
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    surffile.format = gwy_get_guint16_le(&p);
    surffile.nobjects = gwy_get_guint16_le(&p);
    surffile.version = gwy_get_guint16_le(&p);
    surffile.type = gwy_get_guint16_le(&p);
    get_CHARS0(surffile.object_name, &p, 30);
    get_CHARS0(surffile.operator_name, &p, 30);
    surffile.material_code = gwy_get_guint16_le(&p);
    surffile.acquisition = gwy_get_guint16_le(&p);
    surffile.range = gwy_get_guint16_le(&p);
    surffile.special_points = gwy_get_guint16_le(&p);
    surffile.absolute = gwy_get_guint16_le(&p);
    /*reserved*/
    p += 8;
    surffile.pointsize = gwy_get_guint16_le(&p);
    surffile.zmin = gwy_get_gint32_le(&p);
    surffile.zmax = gwy_get_gint32_le(&p);
    surffile.xres = gwy_get_gint32_le(&p);
    surffile.yres = gwy_get_gint32_le(&p);
    surffile.nofpoints = gwy_get_guint32_le(&p);

    surffile.dx = gwy_get_gfloat_le(&p);
    surffile.dy = gwy_get_gfloat_le(&p);
    surffile.dz = gwy_get_gfloat_le(&p);
    get_CHARS0(surffile.xaxis, &p, 16);
    get_CHARS0(surffile.yaxis, &p, 16);
    get_CHARS0(surffile.zaxis, &p, 16);
    get_CHARS0(surffile.dx_unit, &p, 16);
    get_CHARS0(surffile.dy_unit, &p, 16);
    get_CHARS0(surffile.dz_unit, &p, 16);
    get_CHARS0(surffile.xlength_unit, &p, 16);
    get_CHARS0(surffile.ylength_unit, &p, 16);
    get_CHARS0(surffile.zlength_unit, &p, 16);

    surffile.xunit_ratio = gwy_get_gfloat_le(&p);
    surffile.yunit_ratio = gwy_get_gfloat_le(&p);
    surffile.zunit_ratio = gwy_get_gfloat_le(&p);
    surffile.imprint = gwy_get_guint16_le(&p);
    surffile.inversion = gwy_get_guint16_le(&p);
    surffile.leveling = gwy_get_guint16_le(&p);

    p += 12;

    surffile.seconds = gwy_get_guint16_le(&p);
    surffile.minutes = gwy_get_guint16_le(&p);
    surffile.hours = gwy_get_guint16_le(&p);
    surffile.day = gwy_get_guint16_le(&p);
    surffile.month = gwy_get_guint16_le(&p);
    surffile.year = gwy_get_guint16_le(&p);
    surffile.measurement_duration = gwy_get_guint16_le(&p);
    surffile.comment_size = gwy_get_guint16_le(&p);
    surffile.private_size = gwy_get_guint16_le(&p);

    get_CHARARRAY(surffile.client_zone, &p);

    surffile.XOffset = gwy_get_gfloat_le(&p);
    surffile.YOffset = gwy_get_gfloat_le(&p);
    surffile.ZOffset = gwy_get_gfloat_le(&p);


    gwy_debug("fileformat: %d,  n_of_objects: %d, "
              "version: %d, object_type: %d",
              surffile.format, surffile.nobjects,
              surffile.version, surffile.type);
    gwy_debug("object name: <%s>", surffile.object_name);
    gwy_debug("operator name: <%s>", surffile.operator_name);

    gwy_debug("material code: %d, acquisition type: %d",
              surffile.material_code, surffile.acquisition);
    gwy_debug("range type: %d, special points: %d, absolute: %d",
              surffile.range,
              surffile.special_points, (gint)surffile.absolute);
    gwy_debug("data point size: %d", surffile.pointsize);
    gwy_debug("zmin: %d, zmax: %d", surffile.zmin, surffile.zmax);
    gwy_debug("xres: %d, yres: %d (xres*yres = %d)",
              surffile.xres, surffile.yres, (surffile.xres*surffile.yres));
    gwy_debug("total number of points: %d", surffile.nofpoints);
    gwy_debug("dx: %g, dy: %g, dz: %g",
              surffile.dx, surffile.dy, surffile.dz);
    gwy_debug("X axis name: %16s", surffile.xaxis);
    gwy_debug("Y axis name: %16s", surffile.yaxis);
    gwy_debug("Z axis name: %16s", surffile.zaxis);
    gwy_debug("dx unit: %16s", surffile.dx_unit);
    gwy_debug("dy unit: %16s", surffile.dy_unit);
    gwy_debug("dz unit: %16s", surffile.dz_unit);
    gwy_debug("X axis unit: %16s", surffile.xlength_unit);
    gwy_debug("Y axis unit: %16s", surffile.ylength_unit);
    gwy_debug("Z axis unit: %16s", surffile.zlength_unit);
    gwy_debug("xunit_ratio: %g, yunit_ratio: %g, zunit_ratio: %g",
              surffile.xunit_ratio, surffile.yunit_ratio, surffile.zunit_ratio);
    gwy_debug("imprint: %d, inversion: %d, leveling: %d",
              surffile.imprint, surffile.inversion, surffile.leveling);
    gwy_debug("Time: %d:%d:%d, Date: %d.%d.%d",
              surffile.hours, surffile.minutes, surffile.seconds,
              surffile.day, surffile.month, surffile.year);
    gwy_debug("private zone size: %d, comment size %d",
              surffile.private_size, surffile.comment_size);

    expected_size = (SURF_HEADER_SIZE
                     + surffile.pointsize/8*surffile.xres*surffile.yres);
    if (expected_size != size) {
        gwy_debug("Size mismatch!");
        if (size > expected_size) add = size - expected_size; /*TODO  correct this !*/
        else {
          err_SIZE_MISMATCH(error, expected_size, size);
          gwy_file_abandon_contents(buffer, size, NULL);
          return NULL;
        }
    }

    p = buffer + SURF_HEADER_SIZE + add;
    if (!fill_data_fields(&surffile, p, error)) {
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    if (!surffile.absolute) {
        max = gwy_data_field_get_max(surffile.dfield);
        min = gwy_data_field_get_min(surffile.dfield);
        gwy_data_field_add(surffile.dfield, -min);

        gwy_data_field_multiply(surffile.dfield,
                                (surffile.zmax - surffile.zmin)/(max-min));
    }

    switch (surffile.inversion) {
        case SURF_INV_Z:
        gwy_data_field_invert(surffile.dfield, FALSE, FALSE, TRUE);
        break;

        case SURF_FLIP_Z:
        gwy_data_field_invert(surffile.dfield, FALSE, TRUE, TRUE);
        break;

        case SURF_FLOP_Z:
        gwy_data_field_invert(surffile.dfield, TRUE, FALSE, TRUE);
        break;

        default:
        break;
    }

    container = gwy_container_new();
    gwy_container_set_object_by_name(container, "/0/data", surffile.dfield);
    g_object_unref(surffile.dfield);

    meta = surffile_get_metadata(&surffile);
    gwy_container_set_object_by_name(container, "/0/meta", meta);
    g_object_unref(meta);

    gwy_app_channel_check_nonsquare(container, 0);

    return container;
}
Beispiel #7
0
static GwyContainer*
surffile_load(const gchar *filename)
{
    SurfFile surffile;
    GObject *object = NULL;
    guchar *buffer = NULL;
    const guchar *p;
    gsize size = 0;
    gsize estsize;
    GError *err = NULL;
    gchar signature[12];
    gdouble max, min;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        g_warning("Cannot read file %s", filename);
        g_clear_error(&err);
        return NULL;
    }
    p = buffer;

    get_CHARARRAY(signature, &p);
    if (strncmp(signature, "DIGITAL SURF", 12) != 0) {
        g_warning("File %s is not a Surf file", filename);
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    if (size < 500) {
        g_warning("File %s is too short to be Surf file", filename);
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }


    surffile.format = get_WORD_LE(&p);
    surffile.nobjects = get_WORD_LE(&p);
    surffile.version = get_WORD_LE(&p);
    surffile.type = get_WORD_LE(&p);
    get_CHARS0(surffile.object_name, &p, 30);
    get_CHARS0(surffile.operator_name, &p, 30);
    surffile.material_code = get_WORD_LE(&p);
    surffile.acquisition = get_WORD_LE(&p);
    surffile.range = get_WORD_LE(&p);
    surffile.special_points = get_WORD_LE(&p);
    surffile.absolute = get_WORD_LE(&p);
    /*reserved*/
    p += 8;
    surffile.pointsize = get_WORD_LE(&p);
    surffile.zmin = get_DWORD(&p);
    surffile.zmax = get_DWORD(&p);
    surffile.xres = get_DWORD(&p);
    surffile.yres = get_DWORD(&p);
    surffile.nofpoints = get_DWORD(&p);

    //surffile.xres = 200; surffile.yres = 200;

    surffile.dx = get_FLOAT_LE(&p);
    surffile.dy = get_FLOAT_LE(&p);
    surffile.dz = get_FLOAT_LE(&p);
    get_CHARS0(surffile.xaxis, &p, 16);
    get_CHARS0(surffile.yaxis, &p, 16);
    get_CHARS0(surffile.zaxis, &p, 16);
    get_CHARS0(surffile.dx_unit, &p, 16);
    get_CHARS0(surffile.dy_unit, &p, 16);
    get_CHARS0(surffile.dz_unit, &p, 16);
    get_CHARS0(surffile.xlength_unit, &p, 16);
    get_CHARS0(surffile.ylength_unit, &p, 16);
    get_CHARS0(surffile.zlength_unit, &p, 16);

    surffile.xunit_ratio = get_FLOAT_LE(&p);
    surffile.yunit_ratio = get_FLOAT_LE(&p);
    surffile.zunit_ratio = get_FLOAT_LE(&p);
    surffile.imprint = get_WORD_LE(&p);
    surffile.inversion = get_WORD_LE(&p);
    surffile.leveling = get_WORD_LE(&p);

    p += 12;

    surffile.seconds = get_WORD_LE(&p);
    surffile.minutes = get_WORD_LE(&p);
    surffile.hours = get_WORD_LE(&p);
    surffile.day = get_WORD_LE(&p);
    surffile.month = get_WORD_LE(&p);
    surffile.year = get_WORD_LE(&p);
    surffile.measurement_duration = get_WORD_LE(&p);
    surffile.comment_size = get_WORD_LE(&p);
    surffile.private_size = get_WORD_LE(&p);

    get_CHARARRAY(surffile.client_zone, &p);

    surffile.XOffset = get_FLOAT_LE(&p);
    surffile.YOffset = get_FLOAT_LE(&p);
    surffile.ZOffset = get_FLOAT_LE(&p);

    gwy_debug("fileformat: %d,  n_of_objects: %d, version: %d, object_type: %d",
              surffile.format, surffile.nobjects, surffile.version, surffile.type);
    gwy_debug("object name: %s", surffile.object_name);
    gwy_debug("operator name: %s", surffile.operator_name);

    gwy_debug("material code: %d, acquisition type: %d", surffile.material_code, surffile.acquisition);
    gwy_debug("range type: %d, special points: %d, absolute: %d", surffile.range,
           surffile.special_points, (gint)surffile.absolute);
    gwy_debug("data point size: %d", surffile.pointsize);
    gwy_debug("zmin: %d, zmax: %d", surffile.zmin, surffile.zmax);
    gwy_debug("xres: %d, yres: %d (xres*yres = %d)", surffile.xres, surffile.yres, (surffile.xres*surffile.yres));
    gwy_debug("total number of points: %d", surffile.nofpoints);
    gwy_debug("dx: %g, dy: %g, dz: %g", surffile.dx, surffile.dy, surffile.dz);
    gwy_debug("X axis name: %16s", surffile.xaxis);
    gwy_debug("Y axis name: %16s", surffile.yaxis);
    gwy_debug("Z axis name: %16s", surffile.zaxis);
    gwy_debug("dx unit: %16s", surffile.dx_unit);
    gwy_debug("dy unit: %16s", surffile.dy_unit);
    gwy_debug("dz unit: %16s", surffile.dz_unit);
    gwy_debug("X axis unit: %16s", surffile.xlength_unit);
    gwy_debug("Y axis unit: %16s", surffile.ylength_unit);
    gwy_debug("Z axis unit: %16s", surffile.zlength_unit);
    gwy_debug("xunit_ratio: %g, yunit_ratio: %g, zunit_ratio: %g", surffile.xunit_ratio, surffile.yunit_ratio, surffile.zunit_ratio);
    gwy_debug("imprint: %d, inversion: %d, leveling: %d", surffile.imprint, surffile.inversion, surffile.leveling);
    gwy_debug("Time: %d:%d:%d, Date: %d.%d.%d", surffile.hours, surffile.minutes, surffile.seconds,
           surffile.day, surffile.month, surffile.year);

    p = buffer + 512;

    estsize = 512 + surffile.pointsize*surffile.xres*surffile.yres/8;
    if (size < estsize) {
        g_warning("File %s is too short to contain Surf data %d %d", filename, (int)size, (int)estsize);
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    fill_data_fields(&surffile, p);
    gwy_file_abandon_contents(buffer, size, NULL);

    if (surffile.absolute == 0)
    {
        max = gwy_data_field_get_max(surffile.dfield);
        min = gwy_data_field_get_min(surffile.dfield);
        gwy_data_field_add(surffile.dfield, -min);

        gwy_data_field_multiply(surffile.dfield,
                                (surffile.zmax - surffile.zmin)/(max-min));
    }

    if (surffile.inversion == 1)
        gwy_data_field_invert(surffile.dfield, FALSE, FALSE, TRUE);

    if (surffile.inversion == 2)
        gwy_data_field_invert(surffile.dfield, FALSE, TRUE, TRUE);

    if (surffile.inversion == 3)
        gwy_data_field_invert(surffile.dfield, TRUE, FALSE, TRUE);


    if (surffile.dfield) {
        object = gwy_container_new();
        gwy_container_set_object_by_name(GWY_CONTAINER(object), "/0/data",
                                         G_OBJECT(surffile.dfield));
        store_metadata(&surffile, GWY_CONTAINER(object));
    }
    return (GwyContainer*)object;

    return NULL;
}
Beispiel #8
0
/**
 * gwy_tip_cmap:
 * @tip: Tip data.
 * @surface: Surface data.
 * @result: Data field to store ceratainty map data to.
 * @set_fraction: Function that sets fraction to output (or %NULL).
 * @set_message: Function that sets message to output (of %NULL).
 *
 * Performs certainty map algorithm published by Villarrubia. This function
 * converts all fields into form requested by "morph_lib.c" library, that is
 * almost identical with original Villarubia's library. Result certainty map
 * can be used as a mask of points where tip did not directly touch the
 * surface.
 *
 * Returns: Certainty map, i.e. @result, on success.  May return %NULL if
 *          aborted.
 **/
GwyDataField*
gwy_tip_cmap(GwyDataField *tip,
             GwyDataField *surface,
             GwyDataField *result,
             GwySetFractionFunc set_fraction,
             GwySetMessageFunc set_message)
{
    gint **ftip;
    gint **fsurface;
    gint **rsurface;
    gint **fresult;
    gint newx, newy;
    gdouble tipmin, surfacemin, step;
    GwyDataField *buffertip;
    gboolean freetip;

    newx = surface->xres + tip->xres;
    newy = surface->yres + tip->yres;

    /*if tip and surface have different spacings, make new, resampled tip*/
    buffertip = get_right_tip_field(tip, surface, &freetip);
    /*invert tip (as necessary by dilation algorithm)*/
    gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    /*convert fields to integer arrays*/
    tipmin = gwy_data_field_get_min(buffertip);
    surfacemin = gwy_data_field_get_min(surface);
    step = (gwy_data_field_get_max(surface) - surfacemin)/10000;

    ftip = i_datafield_to_field(buffertip, TRUE, tipmin, step);
    fsurface = i_datafield_to_largefield(surface, buffertip, surfacemin, step);

    /*perform erosion as it is necessary parameter of certainty map algorithm*/
    rsurface = _gwy_morph_lib_ierosion(fsurface, newy, newx,
                                       ftip, buffertip->yres, buffertip->xres,
                                       buffertip->yres/2, buffertip->xres/2,
                                       set_fraction, set_message);
    if (!rsurface) {
        _gwy_morph_lib_ifreematrix(ftip, buffertip->xres);
        _gwy_morph_lib_ifreematrix(fsurface, newx);
       if (freetip)
           g_object_unref(buffertip);
       return NULL;
    }

    /*find certanty map*/
    if (rsurface) {
        fresult = _gwy_morph_lib_icmap(fsurface, newy, newx,
                                       ftip, buffertip->yres, buffertip->xres,
                                       rsurface,
                                       buffertip->yres/2, buffertip->xres/2,
                                       set_fraction, set_message);
    }
    else
        fresult = NULL;

    /*convert result back*/
    if (fresult) {
        gwy_data_field_resample(result, surface->xres, surface->yres,
                                GWY_INTERPOLATION_NONE);
        result = i_largefield_to_datafield(fresult, result, buffertip,
                                           0.0, 1.0);
    }
    else
        result = NULL;

    _gwy_morph_lib_ifreematrix(ftip, buffertip->xres);
    _gwy_morph_lib_ifreematrix(fsurface, newx);
    _gwy_morph_lib_ifreematrix(rsurface, newx);
    if (fresult)
        _gwy_morph_lib_ifreematrix(fresult, result->xres);
    if (freetip)
        g_object_unref(buffertip);
    else
        gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    return result;
}
Beispiel #9
0
static gboolean
surffile_save(GwyContainer *data,
             const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    FILE *fh;
    gboolean ok = TRUE;
    SurfWriter surf;
    gfloat uintmax = 1073741824.0;
    gdouble zmaxreal;
    gdouble zminreal;
    gdouble xreal;
    gdouble yreal;
    gchar *dxunittmp;
    gchar *dyunittmp;
    gchar *dzunittmp;
    GwySIUnit *xysi;
    GwySIUnit *zsi;
    GwyContainer *current_data;
    int power = 0;
    int k = 0;
    GwyDataField *dfield;
    const gdouble *points;
    gint32 *integer_values;

    strncpy(surf.signature, "DIGITAL SURF", 12);
    surf.format = 0;
    surf.nobjects = 1;
    surf.version = 1;
    surf.type = 1;
    strncpy(surf.object_name, "SCRATCH", 30);
    strncpy(surf.operator_name, "csm", 30);
    surf.material_code = 0;
    surf.acquisition = 0;
    surf.range = 1;
    surf.special_points = 0;
    surf.absolute = 1;
    strncpy(surf.reserved, " ", 8);
    surf.pointsize = 32;
    surf.zmin = 0;
    surf.zmax = 1073741824.0;
    strncpy(surf.xaxis, "X", 16);
    strncpy(surf.yaxis, "Y", 16);
    strncpy(surf.zaxis, "Z", 16);
    surf.xunit_ratio = 1;
    surf.yunit_ratio = 1;
    surf.zunit_ratio = 1;
    surf.imprint = 1;
    surf.inversion = 0;
    surf.leveling = 0;
    strncpy(surf.obsolete, " ", 12);
    surf.seconds = 0;
    surf.minutes = 0;
    surf.hours = 0;
    surf.day = 5;
    surf.month = 1;
    surf.year = 2001;
    surf.dayof = 0;
    surf.measurement_duration = 1.0;
    strncpy(surf.obsolete2, " ", 10);
    surf.comment_size = 0;
    surf.private_size = 0;
    strncpy(surf.client_zone," ", 128);

    surf.XOffset = 0.0;
    surf.YOffset = 0.0;
    surf.ZOffset = 0.0;
    strncpy(surf.reservedzone, " ", 34);

    if (!(fh = gwy_fopen( filename, "wb"))) {
        err_OPEN_WRITE(error);
        return FALSE;
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &current_data, 0);
    if (!current_data) {
        err_NO_CHANNEL_EXPORT(error);
        return FALSE;
    }

    if (data != current_data) {
        return FALSE;
    }

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, 0);
    if (!dfield) {
        err_NO_CHANNEL_EXPORT(error);
        return FALSE;
    }

    /*header values*/
    xysi = gwy_data_field_get_si_unit_xy(dfield);
    zsi = gwy_data_field_get_si_unit_z(dfield);
    dxunittmp = gwy_si_unit_get_string(xysi, GWY_SI_UNIT_FORMAT_PLAIN);
    dyunittmp = gwy_si_unit_get_string (xysi, GWY_SI_UNIT_FORMAT_PLAIN);
    dzunittmp = gwy_si_unit_get_string (zsi, GWY_SI_UNIT_FORMAT_PLAIN);
    strncpy(surf.dx_unit, dxunittmp, 16);
    strncpy(surf.dy_unit, dyunittmp, 16);
    strncpy(surf.dz_unit, dzunittmp, 16);
    g_free(dxunittmp);
    g_free(dyunittmp);
    g_free(dzunittmp);

    /*extrema*/
    zmaxreal = gwy_data_field_get_max(dfield);
    zminreal = gwy_data_field_get_min(dfield);
    surf.xres = gwy_data_field_get_xres(dfield);
    surf.yres = gwy_data_field_get_yres(dfield);
    surf.nofpoints = surf.xres * surf.yres;
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);

    /*units*/
    power = 0;
    surf.dx = (gfloat)(xreal / surf.xres);
    get_unit(surf.dx_unit, &power, xreal);
    surf.dx *= pow10(power);
    strncpy(surf.xlength_unit, surf.dx_unit, 16);
    power = 0;
    surf.dy = (gfloat)(yreal / surf.yres);
    get_unit(surf.dy_unit, &power, yreal);
    surf.dy *= pow10(power);
    strncpy(surf.ylength_unit, surf.dy_unit, 16);

    power = 0;
    if (zmaxreal > zminreal) {
        get_unit(surf.dz_unit, &power, (zmaxreal - zminreal));
    }
    strncpy(surf.zlength_unit, surf.dz_unit, 16);

    zmaxreal *= pow10(power);
    zminreal *= pow10(power);
    surf.dz = (zmaxreal - zminreal) / uintmax;
    surf.ZOffset = zminreal;

    /*convert data into integer32*/
    integer_values = g_new(gint32, surf.nofpoints);
    points = gwy_data_field_get_data_const(dfield);

    if (zminreal != zmaxreal) {
        for (k = 0; k < surf.nofpoints; k++) {  // * pow10( power ) to convert in the dz_unit
            integer_values[k] = floor(uintmax * (points[k] * pow10(power)  - zminreal) / (zmaxreal - zminreal));
        }
    }
    else {
        for (k = 0; k < surf.nofpoints; k++) {
            integer_values[k] = 0;
        }
    }


    /* byte order*/
    surf.format = GINT16_TO_LE(surf.format);
    surf.nobjects = GUINT16_TO_LE(surf.nobjects);
    surf.version = GINT16_TO_LE(surf.version);
    surf.type = GINT16_TO_LE(surf.type);
    surf.material_code = GINT16_TO_LE(surf.material_code);
    surf.acquisition = GINT16_TO_LE(surf.acquisition);
    surf.range = GINT16_TO_LE(surf.range);
    surf.special_points = GINT16_TO_LE(surf.special_points);
    surf.absolute = GINT16_TO_LE(surf.absolute);
    surf.pointsize = GINT16_TO_LE(surf.pointsize);
    surf.zmin = GINT32_TO_LE(surf.zmin);
    surf.zmax = GINT32_TO_LE(surf.zmax);
    surf.xres = GINT32_TO_LE(surf.xres);
    surf.yres = GINT32_TO_LE(surf.yres);
    surf.nofpoints = GINT32_TO_LE(surf.nofpoints);
    surf.dx = GFLOAT_TO_LE(surf.dx);
    surf.dy = GFLOAT_TO_LE(surf.dy);
    surf.dz = GFLOAT_TO_LE(surf.dz);
    surf.xunit_ratio = GFLOAT_TO_LE(surf.xunit_ratio);
    surf.yunit_ratio = GFLOAT_TO_LE(surf.yunit_ratio);
    surf.zunit_ratio = GFLOAT_TO_LE(surf.zunit_ratio);
    surf.imprint = GINT16_TO_LE(surf.imprint);
    surf.inversion = GINT16_TO_LE(surf.inversion);
    surf.leveling = GINT16_TO_LE(surf.leveling);
    surf.seconds = GINT16_TO_LE(surf.seconds);
    surf.minutes = GINT16_TO_LE(surf.minutes);
    surf.hours = GINT16_TO_LE(surf.hours);
    surf.day = GINT16_TO_LE(surf.day);
    surf.month = GINT16_TO_LE(surf.month);
    surf.year = GINT16_TO_LE(surf.year);
    surf.dayof = GINT16_TO_LE(surf.dayof);
    surf.measurement_duration = GFLOAT_TO_LE(surf.measurement_duration);
    surf.comment_size = GINT16_TO_LE(surf.comment_size);
    surf.private_size = GINT16_TO_LE(surf.private_size);
    surf.XOffset = GFLOAT_TO_LE(surf.XOffset);
    surf.YOffset = GFLOAT_TO_LE(surf.YOffset);
    surf.ZOffset = GFLOAT_TO_LE(surf.ZOffset);
    for (k = 0; k < surf.nofpoints; k++) {
        integer_values[k] = GINT32_TO_LE(integer_values[k]);
    }


//write

// fwrite(&surf, sizeof( SurfWriter ), 1, fh) bad struct align
    if(
        fwrite(&surf.signature, sizeof(char), 12, fh) != 12 ||
        fwrite(&surf.format, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.nobjects, sizeof(guint16), 1, fh) != 1 ||
        fwrite(&surf.version, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.type, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.object_name, sizeof(char), 30, fh) != 30 ||
        fwrite(&surf.operator_name, sizeof(char), 30, fh) != 30 ||
        fwrite(&surf.material_code, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.acquisition, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.range, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.special_points, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.absolute, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.reserved, sizeof(char), 8, fh) != 8 ||
        fwrite(&surf.pointsize, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.zmin, sizeof(gint32), 1, fh) != 1 ||
        fwrite(&surf.zmax, sizeof(gint32), 1, fh) != 1 ||
        fwrite(&surf.xres, sizeof(gint32), 1, fh) != 1 ||
        fwrite(&surf.yres, sizeof(gint32), 1, fh) != 1 ||
        fwrite(&surf.nofpoints, sizeof(gint32), 1, fh) != 1 ||
        fwrite(&surf.dx, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.dy, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.dz, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.xaxis, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.yaxis, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.zaxis, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.dx_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.dy_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.dz_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.xlength_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.ylength_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.zlength_unit, sizeof(char), 16, fh) != 16 ||
        fwrite(&surf.xunit_ratio, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.yunit_ratio, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.zunit_ratio, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.imprint, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.inversion, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.leveling, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.obsolete, sizeof(char), 12, fh) != 12 ||
        fwrite(&surf.seconds, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.minutes, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.hours, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.day, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.month, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.year, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.dayof, sizeof(gint16),1,fh) != 1 ||
        fwrite(&surf.measurement_duration, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.obsolete2, sizeof(char), 10, fh) != 10 ||
        fwrite(&surf.comment_size, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.private_size, sizeof(gint16), 1, fh) != 1 ||
        fwrite(&surf.client_zone, sizeof(char), 128, fh) != 128 ||
        fwrite(&surf.XOffset, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.YOffset, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.ZOffset, sizeof(gfloat), 1, fh) != 1 ||
        fwrite(&surf.reservedzone, sizeof(char), 34, fh)!= 34 ||
        fwrite(integer_values, sizeof(gint32), surf.nofpoints, fh) != surf.nofpoints
	    ) {
            err_WRITE(error);
            ok = FALSE;
            g_unlink(filename);
        }

    g_free(integer_values);
    fclose( fh );

    return ok;
}
Beispiel #10
0
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);
    }
}
Beispiel #11
0
static gboolean
mask_process(GwyDataField *dfield, GwyDataField *maskfield, WshedArgs *args,
             GtkWidget *wait_window)
{
    gdouble max, min;
    GwyWatershedStatus status;
    GwyWatershedStateType oldstate = -1;

    max = gwy_data_field_get_max(dfield);
    min = gwy_data_field_get_min(dfield);

    /*
    gwy_data_field_grains_mark_watershed(dfield, maskfield,
                                         args->locate_steps,
                                         args->locate_thresh,
                                         args->locate_dropsize*(max-min)/5000.0,
                                         args->wshed_steps,
                                         args->wshed_dropsize*(max-min)/5000.0,
                                         FALSE, 0);
    */
    status.state = GWY_WSHED_INIT;
    gwy_app_wait_start(wait_window, _("Initializing"));
    do {
        gwy_data_field_grains_watershed_iteration(dfield, maskfield,
                                         &status,
                                         args->locate_steps,
                                         args->locate_thresh,
                                         args->locate_dropsize*(max-min)/5000.0,
                                         args->wshed_steps,
                                         args->wshed_dropsize*(max-min)/5000.0,
                                         FALSE, args->inverted);

        if (status.state == GWY_WSHED_MIN) {
            gwy_app_wait_set_message(_("Finding minima"));
            if (!gwy_app_wait_set_fraction(0.0))
                  break;
        }
        else if (status.state == GWY_WSHED_LOCATE) {
            if (status.state != oldstate)
                gwy_app_wait_set_message(_("Locating"));
            if (!gwy_app_wait_set_fraction((gdouble)status.internal_i
                                           /(gdouble)args->locate_steps))
                break;
        }
        else if (status.state == GWY_WSHED_WSHED) {
            if (status.state != oldstate)
                gwy_app_wait_set_message(_("Watershed"));
            if (!gwy_app_wait_set_fraction((gdouble)status.internal_i
                                           /(gdouble)args->wshed_steps))
                break;
        }
        else if (status.state == GWY_WSHED_MARK) {
            gwy_app_wait_set_message(_("Marking boundaries"));
            if (!gwy_app_wait_set_fraction(0.0))
                break;
        }
        oldstate = status.state;
    } while (status.state != GWY_WSHED_FINISHED);

    gwy_app_wait_finish();
    return status.state == GWY_WSHED_FINISHED;
}