static void copy_info(GwySurface *dest, const GwySurface *src) { Surface *dpriv = dest->priv, *spriv = src->priv; /* SI Units can be NULL */ if (spriv->si_unit_xy && dpriv->si_unit_xy) gwy_serializable_clone(G_OBJECT(spriv->si_unit_xy), G_OBJECT(dpriv->si_unit_xy)); else if (spriv->si_unit_xy && !dpriv->si_unit_xy) dpriv->si_unit_xy = gwy_si_unit_duplicate(spriv->si_unit_xy); else if (!spriv->si_unit_xy && dpriv->si_unit_xy) GWY_OBJECT_UNREF(dpriv->si_unit_xy); if (spriv->si_unit_z && dpriv->si_unit_z) gwy_serializable_clone(G_OBJECT(spriv->si_unit_z), G_OBJECT(dpriv->si_unit_z)); else if (spriv->si_unit_z && !dpriv->si_unit_z) dpriv->si_unit_z = gwy_si_unit_duplicate(spriv->si_unit_z); else if (!spriv->si_unit_z && dpriv->si_unit_z) GWY_OBJECT_UNREF(dpriv->si_unit_z); dpriv->cached_ranges = spriv->cached_ranges; dpriv->min = spriv->min; dpriv->max = spriv->max; dpriv->cached_checksum = spriv->cached_checksum; gwy_assign(dpriv->checksum, spriv->checksum, G_N_ELEMENTS(spriv->checksum)); }
/** * 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); }
static void init_graph_model_units(GwyGraphModel *gmodel, GwyDataField *dfield) { GwySIUnit *unit; unit = gwy_data_field_get_si_unit_xy(dfield); unit = gwy_si_unit_duplicate(unit); g_object_set(gmodel, "si-unit-x", unit, NULL); g_object_unref(unit); unit = gwy_data_field_get_si_unit_z(dfield); unit = gwy_si_unit_duplicate(unit); g_object_set(gmodel, "si-unit-y", unit, NULL); g_object_unref(unit); }
static GObject* gwy_spectra_duplicate_real(GObject *object) { gint i; GwySpectra *spectra, *duplicate; GwyDataLine *dataline; g_return_val_if_fail(GWY_IS_SPECTRA(object), NULL); spectra = GWY_SPECTRA(object); duplicate = gwy_spectra_new_alike(spectra); duplicate->title = g_strdup(spectra->title); if (spectra->si_unit_xy) duplicate->si_unit_xy = gwy_si_unit_duplicate(spectra->si_unit_xy); g_array_append_vals(duplicate->spectra, spectra->spectra->data, spectra->spectra->len); /* Duplicate the spectra themselves */ for (i = 0; i < duplicate->spectra->len; i++) { dataline = g_array_index(duplicate->spectra, GwySpectrum, i).ydata; g_array_index(duplicate->spectra, GwySpectrum, i).ydata = gwy_data_line_duplicate(dataline); } return (GObject*)duplicate; }
/** * gwy_spectra_new_alike: * @model: A Spectra object to take units from. * * Creates a new Spectra object similar to an existing one, but containing zero * spectra. * * Use gwy_spectra_duplicate() if you want to copy a spectra object including * the spectra in it. * * Returns: A newly created Spectra object. * * Since: 2.7 **/ GwySpectra* gwy_spectra_new_alike(GwySpectra *model) { GwySpectra *spectra; g_return_val_if_fail(GWY_IS_SPECTRA(model), NULL); spectra = g_object_new(GWY_TYPE_SPECTRA, NULL); if (model->si_unit_xy) spectra->si_unit_xy = gwy_si_unit_duplicate(model->si_unit_xy); return spectra; }
static void gwy_spectra_clone_real(GObject *source, GObject *copy) { GwySpectra *spectra, *clone; GwyDataLine *dataline; guint i; g_return_if_fail(GWY_IS_SPECTRA(source)); g_return_if_fail(GWY_IS_SPECTRA(copy)); spectra = GWY_SPECTRA(source); clone = GWY_SPECTRA(copy); /* Title */ g_free(clone->title); clone->title = g_strdup(spectra->title); /* Remove any existing datalines in the clone */ for (i = 0; i < clone->spectra->len; i++) { g_object_unref(g_array_index(clone->spectra, GwySpectrum, i).ydata); } /* Copy the spectra to clone */ g_array_set_size(clone->spectra, 0); g_array_append_vals(clone->spectra, spectra->spectra->data, spectra->spectra->len); /* Clone the spectra theselves */ for (i = 0; i < spectra->spectra->len; i++) { dataline = g_array_index(clone->spectra, GwySpectrum, i).ydata; g_array_index(clone->spectra, GwySpectrum, i).ydata = gwy_data_line_duplicate(dataline); } /* SI Units can be NULL */ if (spectra->si_unit_xy && clone->si_unit_xy) gwy_serializable_clone(G_OBJECT(spectra->si_unit_xy), G_OBJECT(clone->si_unit_xy)); else if (spectra->si_unit_xy && !clone->si_unit_xy) clone->si_unit_xy = gwy_si_unit_duplicate(spectra->si_unit_xy); else if (!spectra->si_unit_xy && clone->si_unit_xy) gwy_object_unref(clone->si_unit_xy); }
/** * gwy_si_unit_power_multiply: * @siunit1: An SI unit. * @power1: Power to raise @siunit1 to. * @siunit2: An SI unit. * @power2: Power to raise @siunit2 to. * @result: An SI unit to set to @siunit1^@power1*@siunit2^@power2. * It is safe to pass @siunit1 or @siunit2. It can be %NULL too, * a new SI unit is created then and returned. * * Computes the product of two SI units raised to arbitrary powers. * * This is the most complex SI unit arithmetic function. It can be easily * chanied when more than two units are to be multiplied. * * Returns: When @result is %NULL, a newly created SI unit that has to be * dereferenced when no longer used later. Otherwise @result itself * is simply returned, its reference count is NOT increased. * * Since: 2.4 **/ GwySIUnit* gwy_si_unit_power_multiply(GwySIUnit *siunit1, gint power1, GwySIUnit *siunit2, gint power2, GwySIUnit *result) { GwySIUnit *op2 = NULL; GwySimpleUnit *unit, *unit2; gint i, j; g_return_val_if_fail(GWY_IS_SI_UNIT(siunit1), NULL); g_return_val_if_fail(GWY_IS_SI_UNIT(siunit2), NULL); g_return_val_if_fail(!result || GWY_IS_SI_UNIT(result), NULL); if (!result) result = gwy_si_unit_new(NULL); /* Try to avoid hard work by making siunit2 the simplier one */ if (siunit1->units->len < siunit2->units->len || (power2 && !power1) || (siunit2 == result && siunit1 != result)) { GWY_SWAP(GwySIUnit*, siunit1, siunit2); GWY_SWAP(gint, power1, power2); } gwy_si_unit_power_real(siunit1, power1, result); if (!power2) { gwy_si_unit_canonicalize(result); return result; } /* When the second operand is the same object as the result, we have to * operate on a temporary copy */ if (siunit2 == result) { op2 = gwy_si_unit_duplicate(siunit2); siunit2 = op2; } result->power10 += power2*siunit2->power10; for (i = 0; i < siunit2->units->len; i++) { unit2 = &g_array_index(siunit2->units, GwySimpleUnit, i); for (j = 0; j < result->units->len; j++) { unit = &g_array_index(result->units, GwySimpleUnit, j); gwy_debug("[%d] %u == [%d] %u", i, unit2->unit, j, unit->unit); if (unit2->unit == unit->unit) { unit->power += power2*unit2->power; break; } } if (j == result->units->len) { g_array_append_val(result->units, *unit2); unit = &g_array_index(result->units, GwySimpleUnit, result->units->len - 1); unit->power *= power2; } } gwy_si_unit_canonicalize(result); gwy_object_unref(op2); g_signal_emit(result, si_unit_signals[VALUE_CHANGED], 0); return result; }
static GwyContainer* text_dump_import(gchar *buffer, gsize size, const gchar *filename, GError **error) { gchar *val, *key, *pos, *line, *title; GwyContainer *data; GwyDataField *dfield; gdouble xreal, yreal; gint xres, yres, id; GwySIUnit *uxy, *uz; const guchar *s; gdouble *d; gsize n; data = gwy_container_new(); pos = buffer; while ((line = gwy_str_next_line(&pos)) && *line) { val = strchr(line, '='); if (!val || *line != '/') { g_warning("Garbage key: %s", line); continue; } if ((gsize)(val - buffer) + 1 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when value was expected.")); goto fail; } *val = '\0'; val++; if (!gwy_strequal(val, "[") || !pos || *pos != '[') { gwy_debug("<%s>=<%s>", line, val); if (*val) gwy_container_set_string_by_name(data, line, g_strdup(val)); else gwy_container_remove_by_name(data, line); continue; } g_assert(pos && *pos == '['); pos++; dfield = NULL; gwy_container_gis_object_by_name(data, line, &dfield); id = 0; sscanf(line, "/%d", &id); /* get datafield parameters from already read values, failing back * to values of original data field */ key = g_strconcat(line, "/xres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xres = atoi(s); else if (dfield) xres = gwy_data_field_get_xres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field width.")); goto fail; } g_free(key); key = g_strconcat(line, "/yres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yres = atoi(s); else if (dfield) yres = gwy_data_field_get_yres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field height.")); goto fail; } g_free(key); key = g_strconcat(line, "/xreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xreal = g_ascii_strtod(s, NULL); else if (dfield) xreal = gwy_data_field_get_xreal(dfield); else { g_warning("Missing real data field width."); xreal = 1.0; /* 0 could cause troubles */ } g_free(key); key = g_strconcat(line, "/yreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yreal = g_ascii_strtod(s, NULL); else if (dfield) yreal = gwy_data_field_get_yreal(dfield); else { g_warning("Missing real data field height."); yreal = 1.0; /* 0 could cause troubles */ } g_free(key); if (!(xres > 0 && yres > 0 && xreal > 0 && yreal > 0)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Data field dimensions are not positive numbers.")); goto fail; } key = g_strconcat(line, "/unit-xy", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uxy = gwy_si_unit_new((const gchar*)s); else if (dfield) { uxy = gwy_data_field_get_si_unit_xy(dfield); uxy = gwy_si_unit_duplicate(uxy); } else { g_warning("Missing lateral units."); uxy = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/unit-z", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uz = gwy_si_unit_new((const gchar*)s); else if (dfield) { uz = gwy_data_field_get_si_unit_z(dfield); uz = gwy_si_unit_duplicate(uz); } else { g_warning("Missing value units."); uz = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/title", NULL); title = NULL; gwy_container_gis_string_by_name(data, key, (const guchar**)&title); /* We got the contained string but that would disappear. */ title = g_strdup(title); g_free(key); n = xres*yres*sizeof(gdouble); if ((gsize)(pos - buffer) + n + 3 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached inside a data field.")); goto fail; } dfield = GWY_DATA_FIELD(gwy_data_field_new(xres, yres, xreal, yreal, FALSE)); gwy_data_field_set_si_unit_xy(dfield, GWY_SI_UNIT(uxy)); gwy_object_unref(uxy); gwy_data_field_set_si_unit_z(dfield, GWY_SI_UNIT(uz)); gwy_object_unref(uz); d = gwy_data_field_get_data(dfield); #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) memcpy(d, pos, n); #else gwy_memcpy_byte_swap(pos, (guint8*)d, sizeof(gdouble), xres*yres, sizeof(gdouble)-1); #endif pos += n; val = gwy_str_next_line(&pos); if (!gwy_strequal(val, "]]")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing end of data field marker.")); gwy_object_unref(dfield); goto fail; } gwy_container_remove_by_prefix(data, line); gwy_container_set_object_by_name(data, line, dfield); g_object_unref(dfield); if (title) { key = g_strconcat(line, "/title", NULL); gwy_container_set_string_by_name(data, key, title); g_free(key); } gwy_file_channel_import_log_add(data, id, NULL, filename); } return data; fail: gwy_container_remove_by_prefix(data, NULL); g_object_unref(data); return NULL; }
static gboolean curvature_plot_graph(GwyDataField *dfield, const Intersection *i1, const Intersection *i2, GwyGraphModel *gmodel) { GwyGraphCurveModel *gcmodel; GwyDataLine *dline; gint xres, yres; guint i; if (!gwy_graph_model_get_n_curves(gmodel)) { GwySIUnit *siunitxy, *siunitz; gchar *s; siunitxy = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_xy(dfield)); siunitz = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_z(dfield)); g_object_set(gmodel, "title", _("Curvature Sections"), "si-unit-x", siunitxy, "si-unit-y", siunitz, NULL); g_object_unref(siunitxy); g_object_unref(siunitz); for (i = 0; i < 2; i++) { gcmodel = gwy_graph_curve_model_new(); s = g_strdup_printf(_("Profile %d"), (gint)i+1); g_object_set(gcmodel, "description", s, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); g_free(s); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); } } else { g_assert(gwy_graph_model_get_n_curves(gmodel) == 2); } dline = gwy_data_line_new(1, 1.0, FALSE); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); for (i = 0; i < 2; i++) { gint col1 = gwy_data_field_rtoj(dfield, i1[i].x); gint row1 = gwy_data_field_rtoi(dfield, i1[i].y); gint col2 = gwy_data_field_rtoj(dfield, i2[i].x); gint row2 = gwy_data_field_rtoi(dfield, i2[i].y); gwy_data_field_get_profile(dfield, dline, CLAMP(col1, 0, xres-1), CLAMP(row1, 0, yres-1), CLAMP(col2, 0, xres-1), CLAMP(row2, 0, yres-1), -1, 1, GWY_INTERPOLATION_BILINEAR); gwy_data_line_set_offset(dline, i1[i].t/(i2[i].t - i1[i].t) * gwy_data_line_get_real(dline)); gcmodel = gwy_graph_model_get_curve(gmodel, i); gwy_graph_curve_model_set_data_from_dataline(gcmodel, dline, 0, 0); } g_object_unref(dline); return TRUE; }