/** * 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 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)); }
static void gwy_surface_dispose(GObject *object) { GwySurface *surface = GWY_SURFACE(object); GWY_OBJECT_UNREF(surface->priv->si_unit_xy); GWY_OBJECT_UNREF(surface->priv->si_unit_z); G_OBJECT_CLASS(gwy_surface_parent_class)->dispose(object); }
/** * gwy_data_field_correlate_finalize: * @state: Correlation iterator. * * Destroys a correlation iterator, freeing all resources. **/ void gwy_data_field_correlate_finalize(GwyComputationState *cstate) { GwyCorrelationState *state = (GwyCorrelationState*)cstate; GWY_OBJECT_UNREF(state->data_field); GWY_OBJECT_UNREF(state->kernel_field); GWY_OBJECT_UNREF(state->score); GWY_OBJECT_UNREF(state->avg); GWY_OBJECT_UNREF(state->rms); g_free(state); }
static void immerse_controls_destroy(ImmerseControls *controls) { gtk_widget_destroy(controls->dialog); gwy_si_unit_value_format_free(controls->vf); g_object_unref(controls->mydata); gdk_cursor_unref(controls->near_cursor); gdk_cursor_unref(controls->move_cursor); GWY_OBJECT_UNREF(controls->detail); }
static void gwy_coords_view_finalize(GObject *object) { GwyCoordsView *view = GWY_COORDS_VIEW(object); CoordsView *priv = view->priv; free_dim_info(view); GWY_OBJECT_UNREF(priv->pixel_format); // The columns should be already destroyed. g_assert(!priv->column_info); G_OBJECT_CLASS(gwy_coords_view_parent_class)->finalize(object); }
static void gwy_adjustment_dispose(GObject *object) { Adjustment *priv = GWY_ADJUSTMENT(object)->priv; // Clean up in case the binding survives us somehow. if (priv->binding) { g_object_remove_weak_pointer(G_OBJECT(priv->binding), (gpointer*)&priv->binding); GWY_OBJECT_UNREF(priv->binding); } G_OBJECT_CLASS(gwy_adjustment_parent_class)->dispose(object); }
/** * gwy_surface_set_si_unit_z: * @surface: A surface. * @si_unit: SI unit to be set. * * Sets the SI unit corresponding to the "height" (Z) dimension of a surface. * * It does not assume a reference on @si_unit, instead it adds its own * reference. * * Since: 2.45 **/ void gwy_surface_set_si_unit_z(GwySurface *surface, GwySIUnit *si_unit) { g_return_if_fail(GWY_IS_SURFACE(surface)); g_return_if_fail(GWY_IS_SI_UNIT(si_unit)); if (surface->priv->si_unit_z == si_unit) return; GWY_OBJECT_UNREF(surface->priv->si_unit_z); g_object_ref(si_unit); surface->priv->si_unit_z = si_unit; }
/** * gwy_resource_classes_finalize: * * Destroys the inventories of all resource classes. * * This function makes the affected resource classes unusable. Its purpose is * to faciliate reference leak debugging by destroying a large number of * objects that normally live forever. * * Note static resource classes that never called gwy_resource_class_load() * are excluded. * * Since: 2.8 **/ void gwy_resource_classes_finalize(void) { GSList *l; for (l = all_resources; l; l = g_slist_next(l)) { GwyResourceClass *klass; klass = g_type_class_ref((GType)GPOINTER_TO_SIZE(all_resources->data)); GWY_OBJECT_UNREF(klass->inventory); } g_slist_free(all_resources); all_resources = NULL; }
static void free_dim_info(GwyCoordsView *view) { CoordsView *priv = view->priv; if (!priv->dim_info) return; guint dimension = priv->coords_class->dimension; for (guint i = 0; i < dimension; i++) { DimInfo *info = priv->dim_info + i; GWY_SIGNAL_HANDLER_DISCONNECT(info->vf, info->vf_notify_id); GWY_OBJECT_UNREF(info->vf); GWY_FREE(info->units); } g_slice_free1(dimension*sizeof(DimInfo), priv->dim_info); priv->dim_info = NULL; g_type_class_unref(priv->coords_class); }
void test_user_grain_value_save(void) { GwyUserGrainValue *usergrainvalue = make_test_grain_value(); GwyResource *resource = GWY_RESOURCE(usergrainvalue); GError *error = NULL; gwy_resource_set_filename(resource, "Bloat3"); g_assert(gwy_resource_save(resource, &error)); g_assert_no_error(error); g_test_queue_destroy((GDestroyNotify)g_unlink, "Bloat3"); resource_check_file(resource, "Bloat3"); GWY_OBJECT_UNREF(usergrainvalue); user_grain_value_load_check("Bloat3", "Bloat", "The Bloat Group", "V_0/L_b0^3", -1, 0, 1, GWY_GRAIN_VALUE_SAME_UNITS_LATERAL, FALSE); }
/** * gwy_data_field_crosscorrelate_finalize: * @state: Cross-correlation iterator. * * Destroys a cross-correlation iterator, freeing all resources. **/ void gwy_data_field_crosscorrelate_finalize(GwyComputationState *cstate) { GwyCrossCorrelationState *state = (GwyCrossCorrelationState*)cstate; GWY_OBJECT_UNREF(state->data_field1); GWY_OBJECT_UNREF(state->data_field2); GWY_OBJECT_UNREF(state->x_dist); GWY_OBJECT_UNREF(state->y_dist); GWY_OBJECT_UNREF(state->score); GWY_OBJECT_UNREF(state->weights); g_free(state); }
static GObject* gwy_surface_deserialize(const guchar *buffer, gsize size, gsize *position) { guint32 datasize = 0; GwySIUnit *si_unit_xy = NULL, *si_unit_z = NULL; GwySurface *surface; GwyXYZ *data = NULL; GwySerializeSpec spec[] = { { 'o', "si_unit_xy", &si_unit_xy, NULL, }, { 'o', "si_unit_z", &si_unit_z, NULL, }, { 'D', "data", &data, &datasize, }, }; g_return_val_if_fail(buffer, NULL); if (!gwy_serialize_unpack_object_struct(buffer, size, position, GWY_SURFACE_TYPE_NAME, G_N_ELEMENTS(spec), spec)) { g_free(data); GWY_OBJECT_UNREF(si_unit_xy); GWY_OBJECT_UNREF(si_unit_z); return NULL; } if (datasize % 3 != 0) { g_critical("Serialized %s data size %u not a multiple of 3", GWY_SURFACE_TYPE_NAME, datasize); g_free(data); GWY_OBJECT_UNREF(si_unit_xy); GWY_OBJECT_UNREF(si_unit_z); return NULL; } surface = gwy_surface_new(); g_free(surface->data); surface->data = data; surface->n = datasize/3; if (si_unit_z) { GWY_OBJECT_UNREF(surface->priv->si_unit_z); surface->priv->si_unit_z = si_unit_z; } if (si_unit_xy) { GWY_OBJECT_UNREF(surface->priv->si_unit_xy); surface->priv->si_unit_xy = si_unit_xy; } return (GObject*)surface; }
static void immerse_update_detail_pixbuf(ImmerseControls *controls) { GwyContainer *data; GwyDataField *dfield; GwyGradient *gradient; GdkPixbuf *pixbuf; const guchar *name; gchar *key; GQuark quark; gint w, h, xres, yres; GWY_OBJECT_UNREF(controls->detail); data = gwy_app_data_browser_get(controls->args->detail.datano); if (!data) return; quark = gwy_app_get_data_key_for_id(controls->args->detail.id); dfield = gwy_container_get_object(data, quark); gwy_data_view_coords_real_to_xy(GWY_DATA_VIEW(controls->view), gwy_data_field_get_xreal(dfield), gwy_data_field_get_yreal(dfield), &w, &h); gwy_debug("%dx%d", w, h); w = MAX(w, 2); h = MAX(h, 2); key = g_strdup_printf("/%d/base/palette", controls->args->image.id); name = NULL; data = gwy_app_data_browser_get(controls->args->image.datano); gwy_container_gis_string_by_name(data, key, &name); g_free(key); gradient = gwy_gradients_get_gradient(name); /* Handle real-square properly by using an intermediate * pixel-square pixbuf with sufficient resolution */ xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, xres, yres); gwy_pixbuf_draw_data_field(pixbuf, dfield, gradient); controls->detail = gdk_pixbuf_scale_simple(pixbuf, w, h, GDK_INTERP_TILES); g_object_unref(pixbuf); }
static gboolean set_coords(GwyCoordsView *view, GwyCoords *coords) { CoordsView *priv = view->priv; if (!gwy_set_member_object(view, coords, GWY_TYPE_COORDS, &priv->coords, NULL)) return FALSE; GWY_OBJECT_UNREF(priv->store); if (!coords) { gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); return TRUE; } set_coords_type(view, G_OBJECT_TYPE(coords)); priv->store = gwy_list_store_new(GWY_LISTABLE(coords)); g_object_ref_sink(priv->store); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(priv->store)); return TRUE; }
static void user_grain_value_load_check(const gchar *filename, const gchar *expected_name, const gchar *expected_group, const gchar *expected_formula, gint expected_power_x, gint expected_power_y, gint expected_power_z, GwyGrainValueSameUnits expected_same_units, gboolean expected_is_angle) { GError *error = NULL; GwyResource *resource = gwy_resource_load(filename, GWY_TYPE_USER_GRAIN_VALUE, TRUE, &error); g_assert_no_error(error); g_assert(GWY_IS_USER_GRAIN_VALUE(resource)); GwyUserGrainValue *usergrainvalue = GWY_USER_GRAIN_VALUE(resource); g_assert_cmpstr(gwy_resource_get_name(resource), ==, expected_name); g_assert_cmpstr(gwy_user_grain_value_get_group(usergrainvalue), ==, expected_group); g_assert(!gwy_resource_is_managed(resource)); g_assert(gwy_resource_is_modifiable(resource)); resource_check_file(resource, filename); g_assert_cmpstr(gwy_user_grain_value_get_formula(usergrainvalue), ==, expected_formula); g_assert_cmpint(gwy_user_grain_value_get_power_x(usergrainvalue), ==, expected_power_x); g_assert_cmpint(gwy_user_grain_value_get_power_y(usergrainvalue), ==, expected_power_y); g_assert_cmpint(gwy_user_grain_value_get_power_z(usergrainvalue), ==, expected_power_z); g_assert_cmpuint(gwy_user_grain_value_get_same_units(usergrainvalue), ==, expected_same_units); g_assert_cmpint(gwy_user_grain_value_get_is_angle(usergrainvalue), ==, expected_is_angle); GWY_OBJECT_UNREF(usergrainvalue); }
static void free_header(BurleighExpHeader *header) { GWY_OBJECT_UNREF(header->xyunits); GWY_OBJECT_UNREF(header->zunits); }
static GwyContainer* rawxyz_load(const gchar *filename, GwyRunType mode, GError **error) { GwyContainer *settings, *container = NULL; GwySurface *surface = NULL; RawXYZArgs args; GwySIUnit *unit; gint power10; gdouble q; gchar *buffer = NULL; gsize size; GError *err = NULL; gboolean ok; guint k; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } surface = read_xyz_points(buffer); g_free(buffer); if (!surface->n) { err_NO_DATA(error); goto fail; } settings = gwy_app_settings_get(); rawxyz_load_args(settings, &args); if (mode == GWY_RUN_INTERACTIVE) { ok = rawxyz_dialog(&args, surface); rawxyz_save_args(settings, &args); if (!ok) { err_CANCELLED(error); goto fail; } } unit = gwy_si_unit_new_parse(args.xy_units, &power10); if (power10) { q = pow10(power10); for (k = 0; k < surface->n; k++) { surface->data[k].x *= q; surface->data[k].y *= q; } gwy_surface_invalidate(surface); } gwy_serializable_clone(G_OBJECT(unit), G_OBJECT(gwy_surface_get_si_unit_xy(surface))); unit = gwy_si_unit_new_parse(args.z_units, &power10); if (power10) { q = pow10(power10); for (k = 0; k < surface->n; k++) surface->data[k].z *= q; gwy_surface_invalidate(surface); } gwy_serializable_clone(G_OBJECT(unit), G_OBJECT(gwy_surface_get_si_unit_z(surface))); container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_surface_key_for_id(0), surface); gwy_app_xyz_title_fall_back(container, 0); gwy_file_xyz_import_log_add(container, 0, NULL, filename); fail: g_free(args.xy_units); g_free(args.z_units); GWY_OBJECT_UNREF(surface); return container; }
static GwyContainer* asc_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; GwyDataField *dfield = NULL, *mfield = NULL; GwyTextHeaderParser parser; GwySIUnit *unit; gchar *line, *p, *value, *buffer = NULL; GHashTable *hash = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal, q; gint i, xres, yres; gdouble *data; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } p = buffer; line = gwy_str_next_line(&p); if (!gwy_strequal(line, MAGIC_BARE)) { err_FILE_TYPE(error, "SPIP ASCII data"); goto fail; } gwy_clear(&parser, 1); parser.line_prefix = "#"; parser.key_value_separator = "="; parser.terminator = "# Start of Data:"; parser.error = &header_error; parser.end = &header_end; if (!(hash = gwy_text_header_parse(p, &parser, &p, &err))) { g_propagate_error(error, err); goto fail; } if (!require_keys(hash, error, "x-pixels", "y-pixels", "x-length", "y-length", NULL)) goto fail; xres = atoi(g_hash_table_lookup(hash, "x-pixels")); yres = atoi(g_hash_table_lookup(hash, "y-pixels")); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; xreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "x-length"), NULL); yreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "y-length"), NULL); /* Use negated positive conditions to catch NaNs */ if (!((xreal = fabs(xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); xreal = 1.0; } if (!((yreal = fabs(yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); yreal = 1.0; } dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); if ((value = g_hash_table_lookup(hash, "z-unit"))) { gint power10; unit = gwy_si_unit_new_parse(value, &power10); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); q = pow10(power10); } else if ((value = g_hash_table_lookup(hash, "Bit2nm"))) { q = Nanometer * g_ascii_strtod(value, NULL); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); } else q = 1.0; data = gwy_data_field_get_data(dfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = q*g_ascii_strtod(value, &p); if (p == value && (!*p || g_ascii_isspace(*p))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when reading sample #%d of %d"), i, xres*yres); goto fail; } if (p == value) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Malformed data encountered when reading sample " "#%d of %d"), i, xres*yres); goto fail; } value = p; } if ((value = g_hash_table_lookup(hash, "voidpixels")) && atoi(value)) { mfield = gwy_data_field_new_alike(dfield, FALSE); data = gwy_data_field_get_data(mfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = 1.0 - g_ascii_strtod(value, &p); value = p; } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) GWY_OBJECT_UNREF(mfield); } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: GWY_OBJECT_UNREF(dfield); g_free(buffer); if (hash) g_hash_table_destroy(hash); return container; }
static GwyContainer* csmfile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; GHashTable *hash = NULL; guchar *d24, *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; guint xres, yres, bmpsize, header_size, maxval, i, j; gdouble real, zmin, zmax, q, z0; GwyTextHeaderParser parser; GwySIUnit *unit = NULL; gchar *value, *end, *header = NULL; gdouble *data; gint power10; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < BMP_HEADER_SIZE) { err_TOO_SHORT(error); goto fail; } if (!read_bmp_header(buffer, &xres, &yres, &bmpsize) || size <= bmpsize) { err_FILE_TYPE(error, "CSM"); goto fail; } header_size = size - bmpsize; header = g_new(gchar, header_size + 1); memcpy(header, buffer + bmpsize, header_size); header[header_size] = '\0'; gwy_clear(&parser, 1); parser.key_value_separator = "="; hash = gwy_text_header_parse(header, &parser, NULL, NULL); /* Do NOT use the fields Image width, Image height from the added footer. * Even though it is specifically added by Benyuan it can disagree with the * BMP diemsions and when they disagree the BMP diemsions are apparently * right. */ if (err_DIMENSION(error, xres)) goto fail; if (err_DIMENSION(error, yres)) goto fail; if (!(value = g_hash_table_lookup(hash, "ScanSize"))) { err_MISSING_FIELD(error, "ScanSize"); goto fail; } real = g_ascii_strtod(value, NULL); /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real size is 0.0, fixing to 1.0"); real = 1.0; } if (!(value = g_hash_table_lookup(hash, "HeightScale"))) { err_MISSING_FIELD(error, "HeightScale"); goto fail; } zmax = g_ascii_strtod(value, &end); unit = gwy_si_unit_new_parse(end, &power10); /* Optional stuff for which we try to fall back. */ if (!(value = g_hash_table_lookup(hash, "StartHeightScale"))) zmin = 0.0; else zmin = g_ascii_strtod(value, NULL); if (!(value = g_hash_table_lookup(hash, "MaxValue"))) maxval = 0xffff; else maxval = MAX(atoi(value), 1); dfield = gwy_data_field_new(xres, yres, real*Nanometre, real*Nanometre, FALSE); data = gwy_data_field_get_data(dfield); d24 = buffer + BMP_HEADER_SIZE; q = pow10(power10)*(zmax - zmin)/maxval; z0 = pow10(power10)*zmin; for (i = 0; i < yres; i++) { gdouble *row = data + (yres-1 - i)*xres; for (j = 0; j < xres; j++, row++, d24 += 3) *row = (d24[0] + 256.0*d24[1])*q + z0; } gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m"); gwy_data_field_set_si_unit_z(dfield, unit); container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); meta = gwy_container_new(); g_hash_table_foreach(hash, store_meta, meta); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); if ((value = g_hash_table_lookup(hash, "sTitle")) && g_utf8_validate(value, -1, NULL)) { gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(value)); } else gwy_app_channel_title_fall_back(container, 0); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: gwy_file_abandon_contents(buffer, size, NULL); GWY_OBJECT_UNREF(unit); if (header) g_free(header); if (hash) g_hash_table_destroy(hash); return container; }