Beispiel #1
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 #2
0
static void
create_merged_field(GwyContainer *data, gint id1,
                    GwyDataField *dfield1, GwyDataField *dfield2,
                    gint px1, gint py1, gint px2, gint py2,
                    GwyMergeBoundaryType boundary, GwyMergeDirectionType dir,
                    gboolean create_mask, gboolean crop_to_rectangle)
{
    GwyDataField *result, *outsidemask = NULL;
    gint newxres, newyres, newid;

    gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres);
    gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres);
    gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2);

    result = gwy_data_field_new_alike(dfield1, FALSE);

    newxres = MAX(dfield1->xres + px1, dfield2->xres + px2);
    newyres = MAX(dfield1->yres + py1, dfield2->yres + py2);

    gwy_data_field_resample(result, newxres, newyres, GWY_INTERPOLATION_NONE);
    if (create_mask && !crop_to_rectangle) {
        outsidemask = gwy_data_field_new_alike(result, FALSE);
        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(outsidemask),
                                    NULL);
    }
    put_fields(dfield1, dfield2, result, outsidemask,
               boundary, px1, py1, px2, py2);

    if (crop_to_rectangle) {
        GwyOrientation orientation = GWY_ORIENTATION_HORIZONTAL;
        if (dir == GWY_MERGE_DIRECTION_UP || dir == GWY_MERGE_DIRECTION_DOWN)
            orientation = GWY_ORIENTATION_VERTICAL;

        crop_result(result, dfield1, dfield2, orientation, px1, py1, px2, py2);
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_set_data_field_title(data, newid, _("Merged images"));
    gwy_app_sync_data_items(data, data, id1, newid,
                            FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            0);

    if (outsidemask) {
        if (gwy_data_field_get_max(outsidemask) > 0.0) {
            GQuark quark = gwy_app_get_mask_key_for_id(newid);
            gwy_container_set_object(data, quark, outsidemask);
        }
        g_object_unref(outsidemask);
    }

    gwy_app_channel_log_add_proc(data, -1, newid);
    g_object_unref(result);
}
Beispiel #3
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 #4
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 #5
0
static void
round_pyramide(GwyDataField *tip, gdouble angle, gint n, gdouble ballradius)
{
    gdouble center_x, center_y, center_z;
    gdouble height = gwy_data_field_get_max(tip);
    gint col, row;
    gdouble dcol, drow;
    gdouble sphere, radius;
    gdouble beta, zd;

    radius = sqrt((tip->xres/2)*(tip->xres/2) + (tip->yres/2)*(tip->yres/2));
    beta = atan(gwy_data_field_itor(tip, radius)/height);
    center_x = tip->xreal/2;
    center_y = tip->yreal/2;
    beta = atan(tan(angle)/cos(G_PI/n));
    center_z = height - ballradius/sin(beta);
    gwy_debug("z:%g, height=%g, ballradius=%g, cosbeta=%g, beta=%g "
              "(%g deg of %g deg)\n",
              center_z, height, ballradius, cos(beta), beta,
              beta*180/G_PI, angle*180/G_PI);
    for (row = 0; row < tip->yres; row++) {
        gdouble *datarow = tip->data + tip->xres*row;

        for (col = 0; col < tip->xres; col++) {
            if (datarow[col] > (center_z + ballradius*sin(beta))) {
                dcol = gwy_data_field_itor(tip, col) - center_x;
                drow = gwy_data_field_jtor(tip, row) - center_y;
                sphere = (ballradius*ballradius - dcol*dcol - drow*drow);
                zd = G_LIKELY(sphere >= 0) ? sqrt(sphere) : 0.0;
                datarow[col] = MIN(datarow[col], center_z + zd);
            }
        }
    }

    gwy_data_field_invalidate(tip);
}
Beispiel #6
0
static void
gwy_data_field_facet_distribution(GwyDataField *dfield,
                                  gint kernel_size,
                                  GwyContainer *container)
{
    GwyDataField *dtheta, *dphi, *dist;
    GwySIUnit *siunit;
    gdouble *xd, *yd, *data;
    const gdouble *xdc, *ydc;
    gdouble q, max;
    gint res, hres, i, j, mi, mj, xres, yres;

    if (gwy_container_gis_object_by_name(container, "/theta", &dtheta))
        g_object_ref(dtheta);
    else
        dtheta = gwy_data_field_new_alike(dfield, FALSE);

    if (gwy_container_gis_object_by_name(container, "/phi", &dphi))
        g_object_ref(dphi);
    else
        dphi = gwy_data_field_new_alike(dfield, FALSE);

    compute_slopes(dfield, kernel_size, dtheta, dphi);
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    xd = gwy_data_field_get_data(dtheta);
    yd = gwy_data_field_get_data(dphi);

    for (i = xres*yres; i; i--, xd++, yd++) {
        gdouble theta, phi;

        slopes_to_angles(*xd, *yd, &theta, &phi);
        *xd = theta;
        *yd = phi;
    }
    q = gwy_data_field_get_max(dtheta);
    q = MIN(q*1.05, G_PI/2.0);
    q = G_SQRT2/(2.0*sin(q/2.0));

    if (gwy_container_gis_object_by_name(container, "/0/data", &dist)) {
        g_object_ref(dist);
        gwy_data_field_clear(dist);
        gwy_data_field_set_xreal(dist, 2.0*G_SQRT2/q);
        gwy_data_field_set_yreal(dist, 2.0*G_SQRT2/q);
    }
    else {
        dist = gwy_data_field_new(FDATA_RES, FDATA_RES,
                                  2.0*G_SQRT2/q, 2.0*G_SQRT2/q,
                                  TRUE);
        siunit = gwy_si_unit_new("");
        gwy_data_field_set_si_unit_z(dist, siunit);
        g_object_unref(siunit);
        /* FIXME */
        siunit = gwy_si_unit_new("");
        gwy_data_field_set_si_unit_xy(dist, siunit);
        g_object_unref(siunit);
    }

    res = FDATA_RES;
    hres = (res - 1)/2;
    data = gwy_data_field_get_data(dist);

    xdc = gwy_data_field_get_data_const(dtheta);
    ydc = gwy_data_field_get_data_const(dphi);
    for (i = xres*yres; i; i--, xdc++, ydc++) {
        gdouble x, y;
        gint xx, yy;

        angles_to_xy(*xdc, *ydc, &x, &y);
        xx = GWY_ROUND(q*x/G_SQRT2*hres) + hres;
        yy = GWY_ROUND(q*y/G_SQRT2*hres) + hres;
        data[yy*res + xx] += 1.0;
    }

    /* Find maxima */
    mi = mj = hres;
    max = 0;
    for (i = 1; i+1 < res; i++) {
        for (j = 1; j+1 < res; j++) {
            gdouble z;

            z = data[i*res + j]
                + 0.3*(data[i*res + j - 1]
                       + data[i*res + j + 1]
                       + data[i*res - res + j]
                       + data[i*res + res + j])
                + 0.1*(data[i*res - res + j - 1]
                       + data[i*res - res + j + 1]
                       + data[i*res + res + j - 1]
                       + data[i*res + res + j + 1]);
            if (G_UNLIKELY(z > max)) {
                max = z;
                mi = i;
                mj = j;
            }
        }
    }

    for (i = res*res; i; i--, data++)
        *data = pow(*data, 0.35);

    gwy_container_set_double_by_name(container, "/q", q);
    {
        gdouble x, y, theta, phi;

        x = (mj - hres)*G_SQRT2/(q*hres);
        y = (mi - hres)*G_SQRT2/(q*hres);
        xy_to_angles(x, y, &theta, &phi);
        gwy_container_set_double_by_name(container, "/theta0", theta);
        gwy_container_set_double_by_name(container, "/phi0", phi);
    }
    gwy_container_set_object_by_name(container, "/0/data", dist);
    g_object_unref(dist);
    gwy_container_set_object_by_name(container, "/theta", dtheta);
    g_object_unref(dtheta);
    gwy_container_set_object_by_name(container, "/phi", dphi);
    g_object_unref(dphi);
    gwy_container_set_string_by_name(container, "/0/base/palette",
                                     g_strdup(FVIEW_GRADIENT));

    gwy_data_field_data_changed(dist);
}
Beispiel #7
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 #8
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 #9
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 #10
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 #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;
}