Beispiel #1
0
/**
 * gwy_data_field_get_raw_correlation_score:
 * @data_field: A data field.
 * @kernel_field: Kernel to correlate data field with.
 * @col: Upper-left column position in the data field.
 * @row: Upper-left row position in the data field.
 * @kernel_col: Upper-left column position in kernel field.
 * @kernel_row: Upper-left row position in kernel field.
 * @kernel_width: Width of kernel field area.
 * @kernel_height: Heigh of kernel field area.
 * @data_avg: Mean value of the effective data field area.
 * @data_rms: Mean value of the effective kernel field area.
 *
 * Calculates a raw correlation score in one point.
 *
 * See gwy_data_field_get_correlation_score() for description.  This function
 * is useful if you know the mean values and rms.
 *
 * To obtain the score, divide the returned value with the product of rms of
 * data field area and rms of the kernel.
 *
 * Returns: Correlation score (normalized to multiple of kernel and data
 *          area rms).
 **/
static gdouble
gwy_data_field_get_raw_correlation_score(GwyDataField *data_field,
                                         GwyDataField *kernel_field,
                                         gint col,
                                         gint row,
                                         gint kernel_col,
                                         gint kernel_row,
                                         gint kernel_width,
                                         gint kernel_height,
                                         gdouble data_avg,
                                         gdouble kernel_avg)
{
    gint xres, yres, kxres, kyres, i, j;
    gdouble sumpoints, score;
    gdouble *data, *kdata;

    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), -1.0);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(kernel_field), -1.0);

    xres = data_field->xres;
    yres = data_field->yres;
    kxres = kernel_field->xres;
    kyres = kernel_field->yres;
    kernel_width = kernel_width;
    kernel_height = kernel_height;

    /* correlation request outside kernel */
    if (kernel_col > kxres || kernel_row > kyres)
        return -1;

    /* correlation request outside data field */
    if (col < 0 || row < 0
        || col + kernel_width > xres
        || row + kernel_height > yres)
        return -1;
    if (kernel_col < 0
        || kernel_row < 0
        || kernel_col + kernel_width > kxres
        || kernel_row + kernel_height > kyres)
        return -1;

    score = 0;
    sumpoints = kernel_width * kernel_height;
    data = data_field->data;
    kdata = kernel_field->data;
    for (j = 0; j < kernel_height; j++) {   /* row */
        for (i = 0; i < kernel_width; i++) {   /* col */
            score += (data[(i + col) + xres*(j + row)] - data_avg)
                      * (kdata[(i + kernel_col) + kxres*(j + kernel_row)]
                         - kernel_avg);
        }
    }
    score /= sumpoints;

    return score;
}
Beispiel #2
0
/**
 * gwy_surface_set_from_data_field_mask:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 * @mask: Mask of pixels to include from/exclude, or %NULL
 * @masking: Masking mode to use.
 *
 * Fills the data of a surface from a data field, possibly using masking.
 *
 * Since: 2.46
 **/
void
gwy_surface_set_from_data_field_mask(GwySurface *surface,
                                     GwyDataField *dfield,
                                     GwyDataField *mask,
                                     GwyMaskingType masking)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    g_return_if_fail(!mask || GWY_IS_DATA_FIELD(mask));
    copy_field_to_surface(dfield, surface, mask, masking);
}
Beispiel #3
0
/**
 * gwy_surface_copy_units_to_data_field:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 *
 * Sets lateral and value units of a data field to match a surface.
 *
 * Since: 2.46
 **/
void
gwy_surface_copy_units_to_data_field(GwySurface *surface,
                                     GwyDataField *data_field)
{
    Surface *priv;

    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(data_field));

    priv = surface->priv;
    if (priv->si_unit_xy && data_field->si_unit_xy)
        gwy_serializable_clone(G_OBJECT(priv->si_unit_xy),
                               G_OBJECT(data_field->si_unit_xy));
    else if (priv->si_unit_xy && !data_field->si_unit_xy)
        data_field->si_unit_xy = gwy_si_unit_duplicate(priv->si_unit_xy);
    else if (!priv->si_unit_xy && data_field->si_unit_xy)
        GWY_OBJECT_UNREF(data_field->si_unit_xy);

    if (priv->si_unit_z && data_field->si_unit_z)
        gwy_serializable_clone(G_OBJECT(priv->si_unit_z),
                               G_OBJECT(data_field->si_unit_z));
    else if (priv->si_unit_z && !data_field->si_unit_z)
        data_field->si_unit_z = gwy_si_unit_duplicate(priv->si_unit_z);
    else if (!priv->si_unit_z && data_field->si_unit_z)
        GWY_OBJECT_UNREF(data_field->si_unit_z);
}
Beispiel #4
0
/**
 * gwy_data_field_crosscorrelate_init:
 * @data_field1: A data field.
 * @data_field2: A data field.
 * @x_dist: A data field to store x-distances to, or %NULL.
 * @y_dist: A data field to store y-distances to, or %NULL.
 * @score: Data field to store correlation scores to, or %NULL.
 * @search_width: Search area width.
 * @search_height: Search area height.
 * @window_width: Correlation window width.
 * @window_height: Correlation window height.
 *
 * Initializes a cross-correlation iterator.
 *
 * This iterator reports its state as #GwyComputationStateType.
 *
 * Returns: A new cross-correlation iterator.
 **/
GwyComputationState*
gwy_data_field_crosscorrelate_init(GwyDataField *data_field1,
                                   GwyDataField *data_field2,
                                   GwyDataField *x_dist,
                                   GwyDataField *y_dist,
                                   GwyDataField *score,
                                   gint search_width,
                                   gint search_height,
                                   gint window_width,
                                   gint window_height)
{
    GwyCrossCorrelationState *state;

    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field1), NULL);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field2), NULL);
    g_return_val_if_fail(data_field1->xres == data_field2->xres
                     && data_field1->yres == data_field2->yres, NULL);
    g_return_val_if_fail(!x_dist || GWY_IS_DATA_FIELD(x_dist), NULL);
    g_return_val_if_fail(!y_dist || GWY_IS_DATA_FIELD(y_dist), NULL);
    g_return_val_if_fail(!score || GWY_IS_DATA_FIELD(score), NULL);

    state = g_new0(GwyCrossCorrelationState, 1);

    state->cs.state = GWY_COMPUTATION_STATE_INIT;
    state->cs.fraction = 0.0;
    state->data_field1 = g_object_ref(data_field1);
    state->data_field2 = g_object_ref(data_field2);

    if (x_dist)
        state->x_dist = g_object_ref(x_dist);
    if (y_dist)
        state->y_dist = g_object_ref(y_dist);
    if (score)
        state->score = g_object_ref(score);

    state->search_width = search_width;
    state->search_height = search_height;
    state->window_width = window_width;
    state->window_height = window_height;

    state->weights = gwy_data_field_new(window_width, window_height, 
                                        window_width, window_height, 1);
    gwy_data_field_fill(state->weights, 1);

    return (GwyComputationState*)state;
}
Beispiel #5
0
/**
 * gwy_surface_set_from_data_field:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 *
 * Fills the data of a surface from a data field.
 *
 * The number of points in the new surface will be equal to the number of
 * points in the field.  Lateral coordinates will be equal to the corresponding
 * @data_field coordinates; values will be created in regular grid according to
 * @data_field's physical size and offset.
 *
 * Lateral and value units will correspond to @data_field's units.  This means
 * the field needs to have identical @x and @y units.
 *
 * Since: 2.45
 **/
void
gwy_surface_set_from_data_field(GwySurface *surface,
                                GwyDataField *dfield)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    copy_field_to_surface(dfield, surface, NULL, GWY_MASK_IGNORE);
}
Beispiel #6
0
static GwyContainer*
gwyfile_load(const gchar *filename)
{
    GObject *object, *dfield;
    GError *err = NULL;
    guchar *buffer = NULL;
    gsize size = 0;
    gsize pos = 0;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        g_warning("Cannot read file %s", filename);
        g_clear_error(&err);
        return NULL;
    }
    if (size < MAGIC_SIZE
        || (memcmp(buffer, MAGIC, MAGIC_SIZE)
            && memcmp(buffer, MAGIC2, MAGIC_SIZE))) {
        g_warning("File %s doesn't seem to be a .gwy file", filename);
        if (!gwy_file_abandon_contents(buffer, size, &err)) {
            g_critical("%s", err->message);
            g_clear_error(&err);
        }
        return NULL;
    }

    if (!memcmp(buffer, MAGIC, MAGIC_SIZE))
        object = gwy_serializable_deserialize(buffer + MAGIC_SIZE,
                                              size - MAGIC_SIZE, &pos);
    else
        object = gwy_container_deserialize2(buffer + MAGIC_SIZE,
                                            size - MAGIC_SIZE, &pos);

    if (!gwy_file_abandon_contents(buffer, size, &err)) {
        g_critical("%s", err->message);
        g_clear_error(&err);
    }
    if (!object) {
        g_warning("File %s deserialization failed", filename);
        return NULL;
    }
    if (!GWY_IS_CONTAINER(object)) {
        g_warning("File %s contains some strange object", filename);
        g_object_unref(object);
        return NULL;
    }
    dfield = gwy_container_get_object_by_name(GWY_CONTAINER(object), "/0/data");
    if (!dfield || !GWY_IS_DATA_FIELD(dfield)) {
        g_warning("File %s contains no data field", filename);
        g_object_unref(object);
        return NULL;
    }

    return (GwyContainer*)object;
}
Beispiel #7
0
/**
 * gwy_data_field_correlate_init:
 * @data_field: A data field.
 * @kernel_field: Kernel to correlate data field with.
 * @score: Data field to store correlation scores to.
 *
 * Creates a new correlation iterator.
 *
 * This iterator reports its state as #GwyComputationStateType.
 *
 * Returns: A new correlation iterator.
 **/
GwyComputationState*
gwy_data_field_correlate_init(GwyDataField *data_field,
                              GwyDataField *kernel_field,
                              GwyDataField *score)
{
    GwyCorrelationState *state;

    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), NULL);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(kernel_field), NULL);
    g_return_val_if_fail(kernel_field->xres <= data_field->xres
                         && kernel_field->yres <= data_field->yres, NULL);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(score), NULL);

    state = g_new0(GwyCorrelationState, 1);
    state->cs.state = GWY_COMPUTATION_STATE_INIT;
    state->cs.fraction = 0.0;
    state->data_field = g_object_ref(data_field);
    state->kernel_field = g_object_ref(kernel_field);
    state->score = g_object_ref(score);

    return (GwyComputationState*)state;
}
Beispiel #8
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 #9
0
/**
 * gwy_set_data_preview_size:
 * @data_view: A data view used for module preview.
 * @max_size: Maximum allowed @data_view size (width and height).
 *
 * Sets up data view zoom to not exceed specified size.
 *
 * Before calling this function, data keys have be set, data fields and layers
 * have to be present and physically square mode set in the container.
 * Sizing of both pixel-wise square and physically square displays is performed
 * correctly.
 *
 * Since: 2.7
 **/
void
gwy_set_data_preview_size(GwyDataView *data_view,
                          gint max_size)
{
    GwyContainer *container;
    GwyDataField *data_field;
    GwyPixmapLayer *layer;
    gdouble zoomval, scale, xreal, yreal;
    gboolean realsquare;
    gint xres, yres;
    const gchar *prefix;
    gchar *key;

    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    g_return_if_fail(max_size >= 2);

    container = gwy_data_view_get_data(data_view);
    g_return_if_fail(GWY_IS_CONTAINER(container));

    layer = gwy_data_view_get_base_layer(data_view);
    g_return_if_fail(GWY_IS_PIXMAP_LAYER(layer));
    prefix = gwy_pixmap_layer_get_data_key(layer);
    g_return_if_fail(prefix);

    data_field = gwy_container_get_object_by_name(container, prefix);
    g_return_if_fail(GWY_IS_DATA_FIELD(data_field));

    prefix = gwy_data_view_get_data_prefix(data_view);
    g_return_if_fail(prefix);
    key = g_strconcat(prefix, "/realsquare", NULL);
    realsquare = FALSE;
    gwy_container_gis_boolean_by_name(container, key, &realsquare);
    g_free(key);

    xres = gwy_data_field_get_xres(data_field);
    yres = gwy_data_field_get_yres(data_field);
    if (!realsquare)
        zoomval = max_size/(gdouble)MAX(xres, yres);
    else {
        xreal = gwy_data_field_get_xreal(data_field);
        yreal = gwy_data_field_get_yreal(data_field);
        scale = MAX(xres/xreal, yres/yreal);
        zoomval = max_size/(scale*MAX(xreal, yreal));
    }
    gwy_data_view_set_zoom(data_view, zoomval);
}
static void
add_object_id(gpointer hkey,
              gpointer hvalue,
              gpointer user_data)
{
    GValue *value = (GValue*)hvalue;
    FileInfoData *filedata = (FileInfoData*)user_data;
    const gchar *strkey;
    gchar *end;
    gint id;

    strkey = g_quark_to_string(GPOINTER_TO_UINT(hkey));
    if (!strkey || strkey[0] != '/' || !G_VALUE_HOLDS_OBJECT(value))
        return;

    if ((id = strtol(strkey + 1, &end, 10)) >= 0
            && gwy_strequal(end, "/data")
            && GWY_IS_DATA_FIELD(g_value_get_object(value))) {
        filedata->nchannels++;
        filedata->channels = g_slist_prepend(filedata->channels,
                                             GINT_TO_POINTER(id));
        return;
    }

    if (g_str_has_prefix(strkey, "/0/graph/graph/")
            && (id = strtol(strkey + 15, &end, 10)) >= 0
            && !*end
            && GWY_IS_GRAPH_MODEL(g_value_get_object(value))) {
        filedata->ngraphs++;
        filedata->graphs = g_slist_prepend(filedata->graphs,
                                           GINT_TO_POINTER(id));
        return;
    }

    if (g_str_has_prefix(strkey, "/sps/")
            && (id = strtol(strkey + 5, &end, 10)) >= 0
            && !*end
            && GWY_IS_SPECTRA(g_value_get_object(value))) {
        filedata->nspectra++;
        filedata->spectra = g_slist_prepend(filedata->spectra,
                                            GINT_TO_POINTER(id));
        return;
    }
}
Beispiel #11
0
static void
gwy_app_file_chooser_describe_channel(GwyContainer *container,
                                      gint id,
                                      GString *str)
{
    GwyDataField *dfield;
    GwySIUnit *siunit;
    GwySIValueFormat *vf;
    GQuark quark;
    gint xres, yres;
    gdouble xreal, yreal;
    gchar *s;

    g_string_truncate(str, 0);

    quark = gwy_app_get_data_key_for_id(id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(container, quark));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));

    s = gwy_app_get_data_field_title(container, id);
    g_string_append(str, s);
    g_free(s);

    siunit = gwy_data_field_get_si_unit_z(dfield);
    s = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP);
    g_string_append_printf(str, " [%s]\n", s);
    g_free(s);

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    g_string_append_printf(str, "%d×%d px\n", xres, yres);

    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    siunit = gwy_data_field_get_si_unit_xy(dfield);
    vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP,
                                sqrt(xreal*yreal), NULL);
    g_string_append_printf(str, "%.*f×%.*f%s%s",
                          vf->precision, xreal/vf->magnitude,
                          vf->precision, yreal/vf->magnitude,
                          (vf->units && *vf->units) ? " " : "", vf->units);
    gwy_si_unit_value_format_free(vf);
}
Beispiel #12
0
/**
 * gwy_app_data_id_verify_channel:
 * @id: Numerical identifiers of a channel in data managed by the data browser.
 *
 * Checks if numerical channel identifiers correspond to an existing channel.
 *
 * If either the data contained referenced in @id or the channel does not exist
 * the structure is cleared to %GWY_APP_DATA_ID_NONE and the function returns
 * %FALSE.  If it represents an existing channel it is kept intact and the
 * function return %TRUE.
 *
 * Returns: Whether @id refers to an existing channel now.
 *
 * Since: 2.41
 **/
gboolean
gwy_app_data_id_verify_channel(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_data_key_for_id(id->id);
    if (!gwy_container_gis_object(container, quark, &object))
        return clear_data_id(id);

    return GWY_IS_DATA_FIELD(object);
}
static void
modify_channel_for_preview(GwyContainer *data,
                           gint id,
                           gboolean plane_level, gboolean row_level)
{
    GwyDataField *field;
    gdouble a, bx, by;

    if (!plane_level && !row_level)
        return;

    if (!gwy_container_gis_object(data, gwy_app_get_data_key_for_id(id), &field)
            || !GWY_IS_DATA_FIELD(field))
        return;

    if (plane_level) {
        gwy_data_field_fit_plane(field, &a, &bx, &by);
        gwy_data_field_plane_level(field, a, bx, by);
    }

    if (row_level) {
        guint xres = gwy_data_field_get_xres(field);
        guint yres = gwy_data_field_get_yres(field);
        gdouble *row = gwy_data_field_get_data(field);
        gdouble *diffs = g_new(gdouble, xres);
        guint i, j;

        for (i = 1; i < yres; i++) {
            gdouble *prev = row;
            gdouble median;

            row += xres;
            for (j = 0; j < xres; j++)
                diffs[j] = prev[j] - row[j];
            median = gwy_math_median(xres, diffs);
            for (j = 0; j < xres; j++)
                row[j] += median;
        }

        g_free(diffs);
    }
}
Beispiel #14
0
static void
add_channel_id(gpointer hkey,
               gpointer hvalue,
               gpointer user_data)
{
    GValue *value = (GValue*)hvalue;
    GSList **list = (GSList**)user_data;
    const gchar *strkey;
    gchar *end;
    gint id;

    strkey = g_quark_to_string(GPOINTER_TO_UINT(hkey));
    if (!strkey)
        return;

    if (strkey[0] != '/'
        || (id = strtol(strkey + 1, &end, 10)) < 0
        || !gwy_strequal(end, "/data")
        || !G_VALUE_HOLDS_OBJECT(value)
        || !GWY_IS_DATA_FIELD(g_value_get_object(value)))
        return;

    *list = g_slist_prepend(*list, GINT_TO_POINTER(id));
}
Beispiel #15
0
static void
gwy_recent_file_update_thumbnail(GwyRecentFile *rf,
                                 GwyContainer *data,
                                 gint hint,
                                 GdkPixbuf *use_this_pixbuf)
{
    GwyDataField *dfield;
    GdkPixbuf *pixbuf;
    GStatBuf st;
    gchar *fnm;
    GwySIUnit *siunit;
    GwySIValueFormat *vf;
    gdouble xreal, yreal;
    gchar str_mtime[22];
    gchar str_size[22];
    gchar str_width[22];
    gchar str_height[22];
    GError *err = NULL;
    GQuark quark;
    gint id;

    g_return_if_fail(GWY_CONTAINER(data));

    if (use_this_pixbuf) {
        /* If we are given a pixbuf, hint must be the ultimate channel id.
         * We also ignore the thnumbnail state then. */
        g_return_if_fail(GDK_IS_PIXBUF(use_this_pixbuf));
        id = hint;
        pixbuf = g_object_ref(use_this_pixbuf);
    }
    else {
        pixbuf = NULL;
        id = gwy_recent_file_find_some_channel(data, hint);

        if (rf->file_state == FILE_STATE_UNKNOWN)
            gwy_app_recent_file_try_load_thumbnail(rf);
    }

    /* Find channel with the lowest id not smaller than hint */
    if (id == G_MAXINT) {
        gwy_debug("There is no channel in the file, cannot make thumbnail.");
        return;
    }

    if (g_stat(rf->file_sys, &st) != 0) {
        g_warning("File <%s> was just loaded or saved, but it doesn't seem to "
                  "exist any more: %s",
                  rf->file_utf8, g_strerror(errno));
        return;
    }

    if ((gulong)rf->file_mtime == (gulong)st.st_mtime)
        return;

    quark = gwy_app_get_data_key_for_id(id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    rf->file_mtime = st.st_mtime;
    rf->file_size = st.st_size;
    rf->image_width = gwy_data_field_get_xres(dfield);
    rf->image_height = gwy_data_field_get_yres(dfield);
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    siunit = gwy_data_field_get_si_unit_xy(dfield);
    vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP,
                                sqrt(xreal*yreal), NULL);
    g_free(rf->image_real_size);
    rf->image_real_size
        = g_strdup_printf("%.*f×%.*f%s%s",
                          vf->precision, xreal/vf->magnitude,
                          vf->precision, yreal/vf->magnitude,
                          (vf->units && *vf->units) ? " " : "", vf->units);
    rf->file_state = FILE_STATE_OK;
    gwy_si_unit_value_format_free(vf);

    if (g_str_has_prefix(rf->file_sys, gwy_recent_file_thumbnail_dir())) {
        gchar c;

        c = rf->file_sys[strlen(gwy_recent_file_thumbnail_dir())];
        if (!c || G_IS_DIR_SEPARATOR(c))
            return;
    }

    if (!pixbuf)
        pixbuf = gwy_app_get_channel_thumbnail(data, id,
                                               TMS_NORMAL_THUMB_SIZE,
                                               TMS_NORMAL_THUMB_SIZE);

    g_snprintf(str_mtime, sizeof(str_mtime), "%lu", rf->file_mtime);
    g_snprintf(str_size, sizeof(str_size), "%lu", rf->file_size);
    g_snprintf(str_width, sizeof(str_width), "%d", rf->image_width);
    g_snprintf(str_height, sizeof(str_height), "%d", rf->image_height);

    /* invent an unique temporary name for atomic save
     * FIXME: rough, but works on Win32 */
    fnm = g_strdup_printf("%s.%u", rf->thumb_sys, getpid());
    if (!gdk_pixbuf_save(pixbuf, fnm, "png", &err,
                         KEY_SOFTWARE, PACKAGE_NAME,
                         KEY_THUMB_URI, rf->file_uri,
                         KEY_THUMB_MTIME, str_mtime,
                         KEY_THUMB_FILESIZE, str_size,
                         KEY_THUMB_IMAGE_WIDTH, str_width,
                         KEY_THUMB_IMAGE_HEIGHT, str_height,
                         KEY_THUMB_GWY_REAL_SIZE, rf->image_real_size,
                         NULL)) {
        g_clear_error(&err);
        rf->thumb_state = FILE_STATE_FAILED;
    }
#ifndef G_OS_WIN32
    chmod(fnm, 0600);
#endif
    g_unlink(rf->thumb_sys);
    if (g_rename(fnm, rf->thumb_sys) != 0) {
        g_unlink(fnm);
        rf->thumb_state = FILE_STATE_FAILED;
        rf->thumb_mtime = 0;
    }
    else {
        rf->thumb_state = FILE_STATE_UNKNOWN;  /* force reload */
        rf->thumb_mtime = rf->file_mtime;
    }
    g_free(fnm);

    gwy_object_unref(rf->pixbuf);
    g_object_unref(pixbuf);
}
Beispiel #16
0
/**
 * gwy_data_field_get_weighted_correlation_score:
 * @data_field: A data field.
 * @kernel_field: Kernel to correlate data field with.
 * @weight_field: data field of same size as kernel window size
 * @col: Upper-left column position in the data field.
 * @row: Upper-left row position in the data field.
 * @kernel_col: Upper-left column position in kernel field.
 * @kernel_row: Upper-left row position in kernel field.
 * @kernel_width: Width of kernel field area.
 * @kernel_height: Heigh of kernel field area.
 *
 * Calculates a correlation score in one point using weights to center
 * the used information to the center of kernel.
 *
 * Correlation window size is given
 * by @kernel_col, @kernel_row, @kernel_width, @kernel_height,
 * postion of the correlation window on data is given by
 * @col, @row.
 *
 * If anything fails (data too close to boundary, etc.),
 * function returns -1.0 (none correlation)..
 *
 * Returns: Correlation score (between -1.0 and 1.0). Value 1.0 denotes
 *          maximum correlation, -1.0 none correlation.
 **/
gdouble
gwy_data_field_get_weighted_correlation_score(GwyDataField *data_field,
                                     GwyDataField *kernel_field,
                                     GwyDataField *weight_field,
                                     gint col,
                                     gint row,
                                     gint kernel_col,
                                     gint kernel_row,
                                     gint kernel_width,
                                     gint kernel_height)
{
    gint xres, yres, kxres, kyres, wxres, i, j;
    gdouble rms1, rms2, avg1, avg2, score;
    gdouble *data, *kdata, *wdata, weightsum;

    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), -10.0);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(kernel_field), -11.0);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(weight_field), -12.0);
    g_return_val_if_fail(kernel_width == weight_field->xres && 
                     kernel_height == weight_field->yres, -13);

    xres = data_field->xres;
    yres = data_field->yres;
    kxres = kernel_field->xres;
    kyres = kernel_field->yres;
    wxres = weight_field->xres;

    /* correlation request outside kernel */
    if (kernel_col > kxres || kernel_row > kyres)
        return -2;

    /* correlation request outside data field */
    if (col < 0 || row < 0
        || col + kernel_width > xres
        || row + kernel_height > yres) {
     
        printf("error: %d %d %d  %d %d %d\n", col, kernel_width, xres, row, kernel_height, yres);
        return -3;
    }

    if (kernel_col < 0
        || kernel_row < 0
        || kernel_col + kernel_width > kxres
        || kernel_row + kernel_height > kyres)
        return -4;

    data = data_field->data;
    kdata = kernel_field->data;
    wdata = weight_field->data;
    weightsum = gwy_data_field_get_sum(weight_field);

    avg1 = avg2 = 0;
    for (j = 0; j < kernel_height; j++) {   /* row */
        for (i = 0; i < kernel_width; i++) {   /* col */
            avg1 += data[(i + col) + xres*(j + row)]*wdata[i + wxres*j];
            avg2 += kdata[(i + kernel_col) + kxres*(j + kernel_row)]*wdata[i + wxres*j];
        }
    }
    avg1 /= gwy_data_field_get_sum(weight_field);
    avg2 /= gwy_data_field_get_sum(weight_field);

    rms1 = rms2 = 0;
    for (j = 0; j < kernel_height; j++) {   /* row */
        for (i = 0; i < kernel_width; i++) {   /* col */
            rms1 += wdata[i + wxres*j]*(data[(i + col) + xres*(j + row)] - avg1)
                      *(data[(i + col) + xres*(j + row)] - avg1);
            rms2 += wdata[i + wxres*j]*(kdata[(i + kernel_col) + kxres*(j + kernel_row)] - avg2)
                      *(kdata[(i + kernel_col) + kxres*(j + kernel_row)] - avg2);
        }
    }
    rms1 /= gwy_data_field_get_sum(weight_field);
    rms2 /= gwy_data_field_get_sum(weight_field);

    rms1 = sqrt(rms1);
    rms2 = sqrt(rms2);

    if (rms1 == 0.0)
        return 0.0;
    if (rms2 == 0.0)
        return 0.0;


    score = 0;
    data = data_field->data;
    kdata = kernel_field->data;
    for (j = 0; j < kernel_height; j++) {   /* row */
        for (i = 0; i < kernel_width; i++) {   /* col */
            score += wdata[i + wxres*j]*(data[(i + col) + xres*(j + row)] - avg1)
                      * (kdata[(i + kernel_col) + kxres*(j + kernel_row)]
                         - avg2);
        }
    }
    //printf("%g %g %g %g  = %g\n", rms1, rms2, score, weightsum, score/(rms1 * rms2 * weightsum));

    score /= rms1 * rms2 * weightsum;

    return score;
}
Beispiel #17
0
/**
 * file_plugin_proxy_load:
 * @filename. A file name to load.
 * @mode: Run mode.
 * @error: Return location for a #GError (or %NULL).
 * @name: Plug-in name (i.e. file-loading function) to run.
 *
 * The plug-in proxy itself, runs file-loading plug-in @name to load @filename.
 *
 * Returns: A newly created data container with the contents of @filename,
 *          or %NULL if it fails.
 **/
static GwyContainer*
file_plugin_proxy_load(const gchar *filename,
                       GwyRunType mode,
                       GError **error,
                       const gchar *name)
{
    FilePluginInfo *info;
    GwyContainer *data = NULL;
    GObject *dfield;
    gchar *tmpname = NULL, *buffer = NULL;
    GError *err = NULL;
    gint exit_status;
    gsize size = 0;
    FILE *fh;
    gchar *args[] = { NULL, NULL, NULL, NULL, NULL };
    gboolean ok;

    gwy_debug("called as %s with file `%s'", name, filename);
    if (mode != GWY_RUN_INTERACTIVE) {
        g_set_error(error, GWY_MODULE_FILE_ERROR,
                    GWY_MODULE_FILE_ERROR_INTERACTIVE,
                    _("Plugin-proxy must be run as interactive."));
        return NULL;
    }
    if (!(info = file_find_plugin(name, GWY_FILE_OPERATION_LOAD))) {
        g_set_error(error, GWY_MODULE_FILE_ERROR,
                    GWY_MODULE_FILE_ERROR_UNIMPLEMENTED,
                    _("Plug-in `%s' does not implement file loading."), name);
        return NULL;
    }
    if (!(fh = open_temporary_file(&tmpname, error)))
        return NULL;

    args[0] = info->file;
    args[1] = g_strdup(gwy_enum_to_string(GWY_FILE_OPERATION_LOAD,
                                          file_op_names, -1));
    args[2] = tmpname;
    args[3] = decode_glib_encoded_filename(filename);
    gwy_debug("%s %s %s %s", args[0], args[1], args[2], args[3]);
    ok = g_spawn_sync(NULL, args, NULL, 0, NULL, NULL,
                      NULL, NULL, &exit_status, &err);
    if (ok) {
        ok = g_file_get_contents(tmpname, &buffer, &size, &err);
        if (!ok) {
            g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO,
                        _("Cannot read temporary file: %s."), err->message);
            g_clear_error(&err);
        }
    }
    else {
        g_set_error(error, GWY_MODULE_FILE_ERROR,
                    GWY_MODULE_FILE_ERROR_SPECIFIC,
                    _("Cannot execute plug-in `%s': %s."), name, err->message);
        g_clear_error(&err);
    }
    g_unlink(tmpname);
    fclose(fh);
    gwy_debug("ok = %d, exit_status = %d, err = %p", ok, exit_status, err);
    if (ok && exit_status) {
        g_set_error(error, GWY_MODULE_FILE_ERROR,
                    GWY_MODULE_FILE_ERROR_SPECIFIC,
                    _("Plug-in `%s' returned non-zero exit status: %d."),
                    name, exit_status);
        ok = FALSE;
    }
    if (ok) {
        data = text_dump_import(buffer, size, error);
        if (!data)
            ok = FALSE;
    }
    if (ok
        && (!gwy_container_gis_object_by_name(data, "/0/data", &dfield)
            || !GWY_IS_DATA_FIELD(dfield))) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Plug-in `%s' did not return any meaningful data."),
                    name);
        gwy_object_unref(data);
    }
    g_free(args[1]);
    g_free(args[3]);
    g_free(buffer);
    g_free(tmpname);

    return data;
}
Beispiel #18
0
/**
 * gwy_data_field_get_correlation_score:
 * @data_field: A data field.
 * @kernel_field: Kernel to correlate data field with.
 * @col: Upper-left column position in the data field.
 * @row: Upper-left row position in the data field.
 * @kernel_col: Upper-left column position in kernel field.
 * @kernel_row: Upper-left row position in kernel field.
 * @kernel_width: Width of kernel field area.
 * @kernel_height: Heigh of kernel field area.
 *
 * Calculates a correlation score in one point.
 *
 * Correlation window size is given
 * by @kernel_col, @kernel_row, @kernel_width, @kernel_height,
 * postion of the correlation window on data is given by
 * @col, @row.
 *
 * If anything fails (data too close to boundary, etc.),
 * function returns -1.0 (none correlation)..
 *
 * Returns: Correlation score (between -1.0 and 1.0). Value 1.0 denotes
 *          maximum correlation, -1.0 none correlation.
 **/
gdouble
gwy_data_field_get_correlation_score(GwyDataField *data_field,
                                     GwyDataField *kernel_field,
                                     gint col,
                                     gint row,
                                     gint kernel_col,
                                     gint kernel_row,
                                     gint kernel_width,
                                     gint kernel_height)
{
    gint xres, yres, kxres, kyres, i, j;
    gdouble rms1, rms2, avg1, avg2, sumpoints, score;
    gdouble *data, *kdata;

    g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), -1.0);
    g_return_val_if_fail(GWY_IS_DATA_FIELD(kernel_field), -1.0);

    xres = data_field->xres;
    yres = data_field->yres;
    kxres = kernel_field->xres;
    kyres = kernel_field->yres;
    kernel_width = kernel_width;
    kernel_height = kernel_height;

    /* correlation request outside kernel */
    if (kernel_col > kxres || kernel_row > kyres)
        return -1;

    /* correlation request outside data field */
    if (col < 0 || row < 0
        || col + kernel_width > xres
        || row + kernel_height > yres)
        return -1;
    if (kernel_col < 0
        || kernel_row < 0
        || kernel_col + kernel_width > kxres
        || kernel_row + kernel_height > kyres)
        return -1;

    avg1 = gwy_data_field_area_get_avg(data_field, NULL,
                                       col, row, kernel_width, kernel_height);
    avg2 = gwy_data_field_area_get_avg(kernel_field, NULL,
                                       kernel_col, kernel_row,
                                       kernel_width, kernel_height);

    rms1 = gwy_data_field_area_get_rms(data_field, NULL,
                                       col, row, kernel_width, kernel_height);
    if (rms1 == 0.0)
        return 0.0;
    rms2 = gwy_data_field_area_get_rms(kernel_field, NULL,
                                       kernel_col, kernel_row,
                                       kernel_width, kernel_height);
    if (rms2 == 0.0)
        return 0.0;

    score = 0;
    sumpoints = kernel_width * kernel_height;
    data = data_field->data;
    kdata = kernel_field->data;
    for (j = 0; j < kernel_height; j++) {   /* row */
        for (i = 0; i < kernel_width; i++) {   /* col */
            score += (data[(i + col) + xres*(j + row)] - avg1)
                      * (kdata[(i + kernel_col) + kxres*(j + kernel_row)]
                         - avg2);
        }
    }
    score /= rms1 * rms2 * sumpoints;

    return score;
}