static gboolean filter_target_graphs(GwyContainer *data, gint id, gpointer user_data) { CurvatureControls *controls = (CurvatureControls*)user_data; GwyGraphModel *gmodel = controls->gmodel, *targetgmodel; GQuark quark = gwy_app_get_graph_key_for_id(id); g_return_val_if_fail(gmodel, FALSE); return (gwy_container_gis_object(data, quark, (GObject**)&targetgmodel) && gwy_graph_model_units_are_compatible(gmodel, targetgmodel)); }
static gboolean filter_target_graphs(GwyContainer *data, gint id, gpointer user_data) { GrainCrossControls *controls = (GrainCrossControls*)user_data; GwyGraphModel *gmodel, *targetgmodel; GQuark quark = gwy_app_get_graph_key_for_id(id); gmodel = gwy_graph_get_model(GWY_GRAPH(controls->graph)); g_return_val_if_fail(GWY_IS_GRAPH_MODEL(gmodel), FALSE); return (gwy_container_gis_object(data, quark, (GObject**)&targetgmodel) && gwy_graph_model_units_are_compatible(gmodel, targetgmodel)); }
/** * gwy_app_data_id_verify_graph: * @id: Numerical identifiers of a graph in data managed by the data browser. * * Checks if numerical graph identifiers correspond to an existing graph. * * If either the data contained referenced in @id or the graph model does not * exist the structure is cleared to %GWY_APP_DATA_ID_NONE and the function * returns %FALSE. If it represents an existing graph it is kept intact and * the function return %TRUE. * * Returns: Whether @id refers to an existing graph now. * * Since: 2.41 **/ gboolean gwy_app_data_id_verify_graph(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_graph_key_for_id(id->id); if (!gwy_container_gis_object(container, quark, &object)) return clear_data_id(id); return GWY_IS_GRAPH_MODEL(object); }
/** * gwy_app_add_graph_or_curves: * @gmodel: A graph model with curves to add. * @data: Data container where the graph would be added. * @target_graph: Graph where curves would be added. * @colorstep: Curve block size as in gwy_graph_model_append_curves(). * * Puts the curves of a graph to another graph if possible, or adds the graph * as new. * * If the units of @gmodel are compatible with the units of the graph * identified by @target_graph the curves are copied to the target graph with * gwy_graph_model_append_curves(). * * In all other cases, including when @target_graph does not refer to any * existing graph, the graph model is added to @data as a new graph. * * Either way, the caller usually need to release its own reference afterwards. * * This function is useful particularly in modules that create graphs and can * be run non-interactively. * * Returns: The numerical identifier of the newly-created graph of one was * created. Value -1 is returned if curves were added to * @target_graph. * * Since: 2.41 **/ gint gwy_app_add_graph_or_curves(GwyGraphModel *gmodel, GwyContainer *data, const GwyAppDataId *target_graph, gint colorstep) { GwyAppDataId tgtgraph = *target_graph; if (gwy_app_data_id_verify_graph(&tgtgraph)) { GQuark quark = gwy_app_get_graph_key_for_id(tgtgraph.id); GwyContainer *data2 = gwy_app_data_browser_get(tgtgraph.datano); GwyGraphModel *target_gmodel = gwy_container_get_object(data2, quark); g_return_val_if_fail(GWY_IS_GRAPH_MODEL(target_gmodel), -1); if (gwy_graph_model_units_are_compatible(gmodel, target_gmodel)) { gwy_graph_model_append_curves(target_gmodel, gmodel, colorstep); return -1; } } g_return_val_if_fail(GWY_IS_CONTAINER(data), FALSE); return gwy_app_data_browser_add_graph_model(gmodel, data, TRUE); }
static GwyContainer* rhk_sm4_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { RHKFile rhkfile; RHKObject *obj, o; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; GString *key = NULL; guint i, imageid = 0, graphid = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&rhkfile, 1); if (size < HEADER_SIZE) { err_TOO_SHORT(error); goto fail; } /* File header */ p = buffer + MAGIC_OFFSET + MAGIC_TOTAL_SIZE; rhkfile.page_count = gwy_get_guint32_le(&p); rhkfile.object_count = gwy_get_guint32_le(&p); rhkfile.object_field_size = gwy_get_guint32_le(&p); gwy_debug("page_count: %u, object_count: %u, object_field_size: %u", rhkfile.page_count, rhkfile.object_count, rhkfile.object_field_size); if (rhkfile.object_field_size != OBJECT_SIZE) g_warning("Object field size %u differs from %u", rhkfile.object_field_size, OBJECT_SIZE); rhkfile.reserved1 = gwy_get_guint32_le(&p); rhkfile.reserved2 = gwy_get_guint32_le(&p); /* Header objects */ if (!(rhkfile.objects = rhk_sm4_read_objects(buffer, p, size, rhkfile.object_count, RHK_OBJECT_FILE_HEADER, error))) goto fail; /* Find page index header */ if (!(obj = rhk_sm4_find_object(rhkfile.objects, rhkfile.object_count, RHK_OBJECT_PAGE_INDEX_HEADER, RHK_OBJECT_FILE_HEADER, error)) || !rhk_sm4_read_page_index_header(&rhkfile.page_index_header, obj, buffer, size, error)) goto fail; /* There, find the page index array. That's a single object in the object * list but it contains a page_count-long sequence of page indices. */ rhkfile.page_indices = g_new0(RHKPageIndex, rhkfile.page_index_header.page_count); if (!(obj = rhk_sm4_find_object(rhkfile.page_index_header.objects, rhkfile.page_index_header.object_count, RHK_OBJECT_PAGE_INDEX_ARRAY, RHK_OBJECT_PAGE_INDEX_HEADER, error))) goto fail; o = *obj; for (i = 0; i < rhkfile.page_index_header.page_count; i++) { if (!rhk_sm4_read_page_index(rhkfile.page_indices + i, &o, buffer, size, error)) goto fail; /* Carefully move to the next page index */ o.offset += o.size + OBJECT_SIZE*rhkfile.page_indices[i].object_count; } container = gwy_container_new(); key = g_string_new(NULL); /* Read pages */ for (i = 0; i < rhkfile.page_index_header.page_count; i++) { RHKPageIndex *pi = rhkfile.page_indices + i; RHKPage *page = &pi->page; /* Page must contain header */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_HEADER, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_header(page, obj, buffer, size, error)) goto fail; /* Page must contain data */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_DATA, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_data(page, obj, buffer, error)) goto fail; /* Page may contain strings */ if (!(obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_STRING_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) || !rhk_sm4_read_string_data(page, obj, pi->page.string_count, buffer)) { g_warning("Failed to read string data in page %u", i); } /* Read the data */ if (pi->data_type == RHK_DATA_IMAGE) { GwyDataField *dfield = rhk_sm4_page_to_data_field(page); GQuark quark = gwy_app_get_data_key_for_id(imageid); const gchar *scandir, *name; gchar *title; gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); if ((name = page->strings[RHK_STRING_LABEL])) { scandir = gwy_enum_to_string(page->scan_dir, scan_directions, G_N_ELEMENTS(scan_directions)); g_string_assign(key, g_quark_to_string(quark)); g_string_append(key, "/title"); if (scandir && *scandir) title = g_strdup_printf("%s [%s]", name, scandir); else title = g_strdup(name); gwy_container_set_string_by_name(container, key->str, title); } meta = rhk_sm4_get_metadata(pi, page); g_string_printf(key, "/%u/meta", imageid); gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); imageid++; } else if (pi->data_type == RHK_DATA_LINE) { GwyGraphModel *gmodel; RHKSpecDriftHeader drift_header; RHKSpecInfo spec_info; G_GNUC_UNUSED gboolean have_header = FALSE, have_info = FALSE; gwy_debug("page_type %u", page->page_type); gwy_debug("line_type %u", page->line_type); gwy_debug("page_sizes %u %u", page->x_size, page->y_size); /* Page may contain drift header */ if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_HEADER, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_drift_header(&drift_header, obj, buffer)) { gwy_debug("drift_header OK"); have_header = TRUE; } if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_spec_info(&spec_info, obj, buffer)) { gwy_debug("spec_info OK"); have_info = TRUE; } /* FIXME: RHK_STRING_PLL_PRO_STATUS may contain interesting * metadata. But we have not place where to put it. */ if ((gmodel = rhk_sm4_page_to_graph_model(page))) { graphid++; gwy_container_set_object(container, gwy_app_get_graph_key_for_id(graphid), gmodel); g_object_unref(gmodel); } } } if (!imageid && !graphid) err_NO_DATA(error); fail: gwy_file_abandon_contents(buffer, size, NULL); rhk_sm4_free(&rhkfile); if (!imageid && !graphid) { gwy_object_unref(container); } if (key) g_string_free(key, TRUE); return container; }
static gboolean read_aist_curve(const guchar **p, gsize *size, AistContext *context) { AistCurve curve; GwyGraphModel *gmodel; GwyGraphCurveModel *gcmodel; GwySIUnit *xunit, *yunit; gboolean ok = FALSE; guint len, viewlen, i; const guchar *data, *viewdata; const gdouble *xdata, *ydata; gdouble *xdatacal, *ydatacal; gdouble *must_free = NULL; gdouble qx, qy; GQuark quark; gwy_clear(&curve, 1); gwy_debug("reading common"); if (!read_aist_common(p, size, &curve.common)) goto fail; gwy_debug("reading curve"); if (!read_qt_int(p, size, &curve.res)) goto fail; if (!read_qt_byte_array(p, size, &len, &data)) goto fail; if (len != 2*curve.res*sizeof(gdouble)) goto fail; /* Again something called view data. Skip it. The units follow. */ if (!read_qt_byte_array(p, size, &viewlen, &viewdata)) goto fail; if (!read_qt_string(p, size, &curve.xunits) || !read_qt_string(p, size, &curve.yunits)) goto fail; xunit = extract_units(curve.xunits, &qx); yunit = extract_units(curve.yunits, &qy); /* The data are already stored as doubles in the correct order, so save * work if also the endianess matches. */ if (G_BYTE_ORDER == G_BIG_ENDIAN) { must_free = g_new(gdouble, 2*curve.res); xdata = must_free; ydata = xdata + curve.res; gwy_memcpy_byte_swap(data, (guchar*)must_free, 8, 2*curve.res, 7); } else if (G_BYTE_ORDER == G_LITTLE_ENDIAN) { xdata = (const gdouble *)data; ydata = xdata + curve.res; } xdatacal = g_new(gdouble, curve.res); ydatacal = g_new(gdouble, curve.res); for (i = 0; i < curve.res; i++) { xdatacal[i] = xdata[i]*qx; ydatacal[i] = ydata[i]*qy; } gcmodel = gwy_graph_curve_model_new(); gwy_graph_curve_model_set_data(gcmodel, xdatacal, ydatacal, curve.res); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "description", curve.common.description, NULL); g_free(must_free); g_free(xdatacal); g_free(ydatacal); gmodel = gwy_graph_model_new(); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); g_object_set(gmodel, "title", curve.common.name, "si-unit-x", xunit, "si-unit-y", yunit, NULL); g_object_unref(xunit); g_object_unref(yunit); quark = gwy_app_get_graph_key_for_id(context->graph_id+1); gwy_container_set_object(context->container, quark, gmodel); g_object_unref(gmodel); context->graph_id++; ok = TRUE; fail: free_aist_common(&curve.common); g_free(curve.xunits); g_free(curve.yunits); return ok; }
static void create_profiles(const X3PFile *x3pfile, GwyContainer *container) { GwyGraphModel *gmodel; GwySIUnit *siunitx, *siunity; GArray *validx, *validy; GQuark quark; gint id; gmodel = gwy_graph_model_new(); siunitx = gwy_si_unit_new("m"); siunity = gwy_si_unit_new("m"); g_object_set(gmodel, "title", "Profiles", "si-unit-x", siunitx, "si-unit-y", siunity, NULL); g_object_unref(siunity); g_object_unref(siunitx); validx = g_array_new(FALSE, FALSE, sizeof(gdouble)); validy = g_array_new(FALSE, FALSE, sizeof(gdouble)); for (id = 0; id < x3pfile->zres; id++) { guint n = x3pfile->xres; GwyGraphCurveModel *gcmodel; gchar *title; guint j; g_array_set_size(validx, 0); g_array_set_size(validy, 0); for (j = 0; j < x3pfile->xres; j++) { gdouble v = x3pfile->values[id*n + j]; if (gwy_isnan(v) || gwy_isinf(v) || !x3pfile->valid[id*n + j]) continue; g_array_append_val(validy, v); v = j*x3pfile->dx; g_array_append_val(validx, v); } if (!validx->len) continue; gcmodel = gwy_graph_curve_model_new(); title = g_strdup_printf("Profile %u", id+1); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "description", title, "color", gwy_graph_get_preset_color(id), NULL); g_free(title); gwy_graph_curve_model_set_data(gcmodel, (gdouble*)validx->data, (gdouble*)validy->data, validx->len); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); } g_array_free(validy, TRUE); g_array_free(validx, TRUE); quark = gwy_app_get_graph_key_for_id(0); gwy_container_set_object(container, quark, gmodel); g_object_unref(gmodel); }
static GwyContainer* sensofar_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SensofarDataDesc data_desc; GwyContainer *container = NULL; GwyDataField *dfield, *mfield; GwyGraphModel *gmodel; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE + 12) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated")); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* Date block */ p = buffer; memcpy(&data_desc.date.str, p, DATE_SIZE); data_desc.date.str[DATE_SIZE-1] = '\0'; p += DATE_SIZE; data_desc.date.t = gwy_get_guint32_le(&p); /* Comment block */ memcpy(&data_desc.user_comment, p, COMMENT_SIZE); data_desc.user_comment[COMMENT_SIZE-1] = '\0'; p += COMMENT_SIZE; /* Calbration block */ data_desc.axes_config.yres = gwy_get_guint32_le(&p); data_desc.axes_config.xres = gwy_get_guint32_le(&p); data_desc.axes_config.N_tall = gwy_get_guint32_le(&p); data_desc.axes_config.dy_multip = gwy_get_gfloat_le(&p); data_desc.axes_config.mppx = gwy_get_gfloat_le(&p); data_desc.axes_config.mppy = gwy_get_gfloat_le(&p); data_desc.axes_config.x_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.y_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.mpp_tall = gwy_get_gfloat_le(&p); data_desc.axes_config.z_0 = gwy_get_gfloat_le(&p); /* Measurement block */ data_desc.measure_config.type = gwy_get_guint32_le(&p); data_desc.measure_config.algorithm = gwy_get_guint32_le(&p); data_desc.measure_config.method = gwy_get_guint32_le(&p); data_desc.measure_config.objective = gwy_get_guint32_le(&p); data_desc.measure_config.area = gwy_get_guint32_le(&p); data_desc.measure_config.xres_area = gwy_get_guint32_le(&p); data_desc.measure_config.yres_area = gwy_get_guint32_le(&p); data_desc.measure_config.xres = gwy_get_guint32_le(&p); data_desc.measure_config.yres = gwy_get_guint32_le(&p); data_desc.measure_config.na = gwy_get_guint32_le(&p); data_desc.measure_config.incr_z = gwy_get_gdouble_le(&p); data_desc.measure_config.range = gwy_get_gfloat_le(&p); data_desc.measure_config.n_planes = gwy_get_guint32_le(&p); data_desc.measure_config.tpc_umbral_F = gwy_get_guint32_le(&p); data_desc.measure_config.restore = gwy_get_gboolean8(&p); data_desc.measure_config.num_layers = *(p++); data_desc.measure_config.version = *(p++); data_desc.measure_config.config_hardware = *(p++); data_desc.measure_config.stack_im_num = *(p++); data_desc.measure_config.reserved = *(p++); p += 2; // struct padding data_desc.measure_config.factor_delmacio = gwy_get_guint32_le(&p); gwy_debug("File date=<%s>, data type=%d, xres=%d, yres=%d, version=%d", data_desc.date.str, data_desc.measure_config.type, data_desc.measure_config.xres, data_desc.measure_config.yres, data_desc.measure_config.version); switch (data_desc.measure_config.type) { case MES_TOPO: case MES_IMATGE: dfield = sensofar_read_data_field(&data_desc, &mfield, &p, size - (p - buffer), error); if (!dfield) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_app_channel_title_fall_back(container, 0); break; case MES_PERFIL: case MES_GRUIX: gmodel = sensofar_read_profile(&data_desc, &p, size - (p - buffer), error); if (!gmodel) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_graph_key_for_id(0), gmodel); g_object_unref(gmodel); break; default: err_DATA_TYPE(error, data_desc.measure_config.type); break; } return container; }