static gchar* format_vt_date(gdouble vt_date) { struct tm tm; UDATE udate; if (!gwy_VarUdateFromDate(vt_date, &udate)) return NULL; gwy_clear(&tm, 1); gwy_debug("Date: %d-%d-%d %d:%d:%d", udate.st.wYear, udate.st.wMonth, udate.st.wDay, udate.st.wHour, udate.st.wMinute, udate.st.wSecond); tm.tm_year = udate.st.wYear - 1900; tm.tm_mon = udate.st.wMonth - 1; tm.tm_mday = udate.st.wDay; tm.tm_hour = udate.st.wHour; tm.tm_min = udate.st.wMinute; tm.tm_sec = udate.st.wSecond; tm.tm_wday = udate.st.wDayOfWeek; tm.tm_yday = udate.wDayOfYear; tm.tm_isdst = -1; return g_strstrip(g_strdup(asctime(&tm))); }
/* This is called only explicitly as we always know the enabled state changes * because we always do it and otherwise we would have to prevent recursion. */ static void update_group_states(GtkTreeModel *model) { GroupState group_states[GWY_GRAIN_VALUE_GROUP_USER+1]; GrainValueStorePrivate *priv; GtkTreeIter iter; gwy_clear(group_states, GWY_GRAIN_VALUE_GROUP_USER+1); gtk_tree_model_foreach(model, update_state, group_states); if (!gtk_tree_model_get_iter_first(model, &iter)) return; priv = g_object_get_qdata(G_OBJECT(model), priv_quark); do { GwyGrainValueGroup group; GtkTreePath *path; gtk_tree_model_get(model, &iter, GWY_GRAIN_VALUE_STORE_COLUMN_GROUP, &group, -1); if (group_states[group] != priv->group_states[group]) { priv->group_states[group] = group_states[group]; path = gtk_tree_model_get_path(model, &iter); gtk_tree_model_row_changed(model, path, &iter); gtk_tree_path_free(path); } } while (gtk_tree_model_iter_next(model, &iter)); }
static GHashTable* hitachi_load_header(const gchar *filename, gchar **header, GError **error) { gchar *line, *p; GwyTextHeaderParser parser; GHashTable *hash = NULL; gsize size; GError *err = NULL; *header = NULL; if (!g_file_get_contents(filename, header, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = *header; line = gwy_str_next_line(&p); if (!gwy_strequal(line, MAGIC)) { err_FILE_TYPE(error, "Hitachi SEM"); g_free(header); *header = NULL; return NULL; } gwy_clear(&parser, 1); parser.key_value_separator = "="; gwy_debug("reading header"); hash = gwy_text_header_parse(p, &parser, NULL, NULL); gwy_debug("header %p", hash); return hash; }
static gint gxsm_detect(const GwyFileDetectInfo *fileinfo, gboolean only_name) { NetCDF cdffile; const guchar *p; gint score; if (only_name) return g_str_has_suffix(fileinfo->name_lowercase, EXTENSION) ? 10 : 0; /* Weed out non-netCDF files quickly */ if (fileinfo->buffer_len < MAGIC_SIZE || (memcmp(fileinfo->head, MAGIC1, MAGIC_SIZE) != 0 && memcmp(fileinfo->head, MAGIC2, MAGIC_SIZE) != 0)) return 0; score = 0; gwy_clear(&cdffile, 1); p = fileinfo->head + MAGIC_SIZE; cdffile.nrecs = gwy_get_guint32_be(&p); if (cdffile_read_dim_array(&cdffile.dims, &cdffile.ndims, fileinfo->head, fileinfo->buffer_len-1, &p, NULL)) { if (cdffile_get_dim(&cdffile, "dimx") && cdffile_get_dim(&cdffile, "dimy")) score = 80; } cdffile_free(&cdffile); return score; }
static gboolean mif_read_header(const guchar *buffer, gsize size, MIFHeader *header, GError **error) { const guchar *p = buffer; if (size <= HEADER_SIZE) { err_TOO_SHORT(error); return FALSE; } if (memcmp(buffer, MAGIC, MAGIC_SIZE)) { err_FILE_TYPE(error, "MIF"); return FALSE; } gwy_clear(header, 1); get_CHARARRAY(header->magic, &p); header->software_version = gwy_get_guint16_be(&p); header->file_version = gwy_get_guint16_be(&p); gwy_debug("sw version: %u.%u, file version: %u.%u", header->software_version/0x100, header->software_version % 0x100, header->file_version/0x100, header->file_version % 0x100); /* Version 1.7 is the only actually implemented. Other can be added upon * request and, namely, provision of the files as each file version is * different. */ if (header->file_version != 0x107) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Loading of file version %u.%u is not implemented."), header->file_version/0x100, header->file_version % 0x100); return FALSE; } get_CHARARRAY(header->time, &p); get_CHARARRAY(header->comment, &p); header->nimages = gwy_get_guint16_le(&p); gwy_debug("n images: %u", header->nimages); header->info.offset = gwy_get_guint32_le(&p); header->info.size = gwy_get_guint32_le(&p); gwy_debug("info offset: %zu, info size: %zu", header->info.offset, header->info.size); get_CHARARRAY(header->unused, &p); if (header->info.offset < HEADER_SIZE || header->info.offset > size || header->info.size > size || header->info.offset + header->info.size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File information block is outside the file.")); return FALSE; } return TRUE; }
static gboolean burleigh_exp_read_header(BurleighExpHeader *header, gchar *buf, GError **error) { GwySIUnit *yunits = NULL, *dummy = NULL; gchar *p, *line; gwy_clear(header, 1); p = buf; /* Magic header */ if (!(line = gwy_str_next_line(&p)) || strncmp(line, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "Burleigh export"); return FALSE; } /* Skip all other lines starting with a dot */ while ((line = gwy_str_next_line(&p))) { if (sscanf(line, ".Binary Format, Header Length=%u, Integer %u bits", &header->length, &header->bpp)) header->binary = TRUE; if (!line || !p || p[0] != '.') break; } if (!line) { err_FILE_TYPE(error, "Burleigh export"); return FALSE; } if (!parse_scale(&p, "X Scale", &header->xscale, &header->xyunits, error)) return FALSE; if (!parse_dim(&p, "X Pixel", &header->xres, error)) return FALSE; if (!parse_scale(&p, "Y Scale", &header->yscale, &yunits, error)) return FALSE; /* FIXME: Check sanity */ g_object_unref(yunits); if (!parse_dim(&p, "Y Pixel", &header->yres, error)) return FALSE; if (!parse_scale(&p, "Z Scale", &header->zscale, &header->zunits, error)) return FALSE; if (!parse_scale(&p, "Z Res.(value/digital)", &header->zres, &dummy, error)) return FALSE; g_object_unref(dummy); if (!header->binary) header->length = p - buf; return TRUE; }
static void ensure_ranges(GwySurface *surface) { Surface *priv = surface->priv; GwyXYZ min, max; guint i; if (priv->cached_ranges) return; priv->cached_ranges = TRUE; if (!surface->n) { gwy_clear(&priv->min, 1); gwy_clear(&priv->max, 1); return; } min = max = surface->data[0]; for (i = 1; i < surface->n; i++) { GwyXYZ pt = surface->data[i]; if (pt.x > max.x) max.x = pt.x; if (pt.x < min.x) min.x = pt.x; if (pt.y > max.y) max.y = pt.y; if (pt.y < min.y) min.y = pt.y; if (pt.z > max.z) max.z = pt.z; if (pt.z < min.z) min.z = pt.z; } priv->min = min; priv->max = max; return; }
static GwyContainer* x3p_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; X3PFile x3pfile; unzFile zipfile; zipfile = gwyminizip_unzOpen(filename); if (!zipfile) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_SPECIFIC, _("Minizip cannot open the file as a ZIP file.")); return NULL; } gwy_clear(&x3pfile, 1); if (!x3p_parse_main(zipfile, &x3pfile, error)) goto fail; if (!x3pfile.ndata) { err_NO_DATA(error); goto fail; } if (!x3pfile.datapos) { if (!read_binary_data(&x3pfile, zipfile, error)) goto fail; } container = gwy_container_new(); if (x3pfile.feature_type == X3P_FEATURE_SUR) create_images(&x3pfile, container); else if (x3pfile.feature_type == X3P_FEATURE_PRF) create_profiles(&x3pfile, container); else { g_assert_not_reached(); } fail: gwy_debug("calling unzClose()"); unzClose(zipfile); x3p_file_free(&x3pfile); return container; }
static gint microprof_txt_detect(const GwyFileDetectInfo *fileinfo, gboolean only_name) { GwyTextHeaderParser parser; GHashTable *meta; const guchar *p; gchar *buffer; gsize size; gint score = 0; if (only_name) return g_str_has_suffix(fileinfo->name_lowercase, EXTENSION_TXT) ? 10 : 0; if (fileinfo->buffer_len < MICROPROF_MIN_TEXT_SIZE || memcmp(fileinfo->head, MAGIC_TXT, MAGIC_TXT_SIZE) != 0) return 0; if (!(p = strstr(fileinfo->head, "\n\n")) && !(p = strstr(fileinfo->head, "\r\r")) && !(p = strstr(fileinfo->head, "\r\n\r\n"))) return 0; size = p - (const guchar*)fileinfo->head; buffer = g_memdup(fileinfo->head, size); gwy_clear(&parser, 1); parser.key_value_separator = "="; meta = gwy_text_header_parse(buffer, &parser, NULL, NULL); if (g_hash_table_lookup(meta, "XSize") && g_hash_table_lookup(meta, "YSize") && g_hash_table_lookup(meta, "XRange") && g_hash_table_lookup(meta, "YRange") && g_hash_table_lookup(meta, "ZScale")) score = 90; g_free(buffer); if (meta) g_hash_table_destroy(meta); return score; }
static gboolean sdfile_read_header_bin(const guchar **p, gsize *len, SDFile *sdfile, GError **error) { if (*len < SDF_HEADER_SIZE_BIN) { err_TOO_SHORT(error); return FALSE; } gwy_clear(sdfile, 1); get_CHARARRAY(sdfile->version, p); get_CHARARRAY(sdfile->manufacturer, p); get_CHARARRAY(sdfile->creation, p); get_CHARARRAY(sdfile->modification, p); sdfile->xres = gwy_get_guint16_le(p); sdfile->yres = gwy_get_guint16_le(p); sdfile->xscale = gwy_get_gdouble_le(p); sdfile->yscale = gwy_get_gdouble_le(p); sdfile->zscale = gwy_get_gdouble_le(p); sdfile->zres = gwy_get_gdouble_le(p); sdfile->compression = **p; (*p)++; sdfile->data_type = **p; (*p)++; sdfile->check_type = **p; (*p)++; sdfile->data = (gchar*)*p; if (sdfile->data_type < SDF_NTYPES) sdfile->expected_size = type_sizes[sdfile->data_type] * sdfile->xres * sdfile->yres; else sdfile->expected_size = -1; *len -= SDF_HEADER_SIZE_BIN; return TRUE; }
static void noise_synth_load_args(GwyContainer *container, NoiseSynthArgs *args, GwyDimensionArgs *dimsargs) { *args = noise_synth_defaults; gwy_container_gis_int32_by_name(container, active_page_key, &args->active_page); gwy_container_gis_boolean_by_name(container, update_key, &args->update); gwy_container_gis_int32_by_name(container, seed_key, &args->seed); gwy_container_gis_boolean_by_name(container, randomize_key, &args->randomize); gwy_container_gis_enum_by_name(container, distribution_key, &args->distribution); gwy_container_gis_enum_by_name(container, direction_key, &args->direction); gwy_container_gis_double_by_name(container, sigma_key, &args->sigma); noise_synth_sanitize_args(args); gwy_clear(dimsargs, 1); gwy_dimensions_copy_args(&dims_defaults, dimsargs); gwy_dimensions_load_args(dimsargs, container, prefix); }
G_GNUC_UNUSED static gboolean mif_read_id(MIFUniqueID *id, const guchar **p, gsize size, GError **error) { gwy_clear(id, 1); if (size < ID_SIZE) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Unique id record is too short.")); return FALSE; } id->ms = gwy_get_guint32_le(p); id->ls = gwy_get_guint32_le(p); gwy_debug("id: %08x %08x", id->ms, id->ls); id->index = gwy_get_guint32_le(p); gwy_debug("index: %u", id->index); get_CHARARRAY(id->workstation, p); gwy_debug_chars(id, workstation); return TRUE; }
static gboolean mif_read_axis_info(MIFAxisInfo *axis, const guchar **p, gsize size, guint file_version, GError **error) { gwy_clear(axis, 1); if (file_version >= 0x105) { if (size < AXIS_INFO_SIZE_1_1) return err_AXIS_INFO_TOO_SHORT(error); get_CHARARRAY(axis->units, p); gwy_debug_chars(axis, units); get_CHARARRAY(axis->units_str_1_1, p); gwy_debug_chars(axis, units_str_1_1); axis->show = *((*p)++); gwy_debug_bool(axis, show); } else if (file_version >= 0x104) { if (size < AXIS_INFO_SIZE_1_0) return err_AXIS_INFO_TOO_SHORT(error); get_CHARARRAY(axis->units, p); gwy_debug_chars(axis, units); get_CHARARRAY(axis->units_str_1_0, p); gwy_debug_chars(axis, units_str_1_0); axis->show = *((*p)++); gwy_debug_bool(axis, show); } else { g_return_val_if_reached(FALSE); } return TRUE; }
static void apedax_get_channels_data(unzFile uFile, guchar *scanXmlContent, gsize contentSize, const gchar *filename, GwyContainer *container, GwyContainer *meta, const APEScanSize *scanSize, GError **error) { xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; xmlXPathContextPtr context; xmlXPathObjectPtr pathObj; xmlNodeSetPtr nodeset; xmlChar *buffer = NULL; gchar key[256]; gint i; gint power10 = 0; gdouble scaleFactor = 1.0; GwySIUnit *zUnit; gchar *zUnitString = NULL; gchar *binFileName = NULL; GwyDataField *dfield; GwyContainer *tmp; if (scanXmlContent == NULL || contentSize == 0) return; gwy_clear(key, sizeof(key)); doc = xmlReadMemory(scanXmlContent, contentSize, "scan.xml", NULL, 0); if (doc == NULL) goto fail; context = xmlXPathNewContext(doc); if (context == NULL) goto fail; pathObj = xmlXPathEvalExpression("/Scan/Channels/Channel", context); if (pathObj == NULL) { xmlXPathFreeContext(context); goto fail; } /*There must be at least one channel*/ if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) { xmlXPathFreeObject(pathObj); xmlXPathFreeContext(context); err_NO_DATA(error); return; } nodeset = pathObj->nodesetval; if (nodeset->nodeNr <= 0) goto fail; for (i = 0; i < nodeset->nodeNr; i++) { cur = nodeset->nodeTab[i]->xmlChildrenNode; while (cur) { /*Label*/ if (gwy_strequal((gchar*)cur->name, "Label")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); g_snprintf(key, sizeof(key), "/%d/data/title", i); gwy_container_set_string_by_name(container, key, g_strdup(buffer)); xmlFree(buffer); } /*Factor*/ if (gwy_strequal((gchar*)cur->name, "ConversionFactor")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); scaleFactor = g_ascii_strtod((gchar*)buffer, NULL); xmlFree(buffer); } /*Unit*/ if (gwy_strequal((gchar*)cur->name, "DataUnit")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); zUnitString = g_strdup((gchar*)buffer); zUnit = gwy_si_unit_new_parse(zUnitString, &power10); xmlFree(buffer); g_object_unref(zUnit); } /*Binary file name*/ if (gwy_strequal((gchar*)cur->name, "BINFile")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); binFileName = g_strdup((gchar*)buffer); xmlFree(buffer); } cur = cur->next; } scaleFactor *= pow(10.0, power10); dfield = apedax_get_data_field(uFile, binFileName, scanSize, zUnitString, scaleFactor, error); if (dfield) { g_snprintf(key, sizeof(key), "/%d/data", i); gwy_container_set_object_by_name(container, key, dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(container, i, NULL, filename); tmp = gwy_container_duplicate(meta); g_snprintf(key, sizeof(key), "/%d/meta", i); gwy_container_set_object_by_name(container, key, tmp); g_object_unref(tmp); } } xmlXPathFreeObject(pathObj); xmlXPathFreeContext(context); xmlFreeDoc(doc); return; fail: err_FILE_TYPE(error, FILE_TYPE); if (doc) xmlFreeDoc(doc); return; }
static gint extr_path_dialogue(ExtrPathArgs *args, GwySelection *selection) { GtkDialog *dialogue; GtkTable *table; GtkWidget *check, *label; ExtrPathControls controls; gint response, row, npts = 0; gchar buf[16]; gwy_clear(&controls, 1); controls.args = args; controls.selection = selection; if (selection) npts = gwy_selection_get_data(selection, NULL); dialogue = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Extract " "Path Selection"), NULL, 0, NULL)); gtk_dialog_add_button(dialogue, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); gtk_dialog_add_button(dialogue, GTK_STOCK_OK, GTK_RESPONSE_OK); gtk_dialog_set_default_response(dialogue, GTK_RESPONSE_OK); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialogue), GWY_HELP_DEFAULT); table = GTK_TABLE(gtk_table_new(5, 4, FALSE)); gtk_table_set_row_spacings(table, 2); gtk_table_set_col_spacings(table, 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), GTK_WIDGET(table), FALSE, FALSE, 4); row = 0; if (selection) { label = gtk_label_new(_("Number of path points:")); gtk_table_attach(table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); g_snprintf(buf, sizeof(buf), "%d", npts); label = gtk_label_new(buf); gtk_table_attach(table, label, 1, 3, row, row+1, GTK_FILL, 0, 0, 0); } else { label = gtk_label_new(_("There is no path selection.")); gtk_table_attach(table, label, 0, 4, row, row+1, GTK_FILL, 0, 0, 0); } row++; gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); check = create_output_checkbutton(_("X position"), &args->x, &controls); gtk_table_attach(table, check, 0, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; check = create_output_checkbutton(_("Y position"), &args->y, &controls); gtk_table_attach(table, check, 0, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; check = create_output_checkbutton(_("X tangent"), &args->vx, &controls); gtk_table_attach(table, check, 0, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; check = create_output_checkbutton(_("Y tangent"), &args->vy, &controls); gtk_table_attach(table, check, 0, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; gtk_dialog_set_response_sensitive(dialogue, GTK_RESPONSE_OK, npts > 1); gtk_widget_show_all(GTK_WIDGET(dialogue)); do { response = gtk_dialog_run(dialogue); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(GTK_WIDGET(dialogue)); case GTK_RESPONSE_NONE: return FALSE; case GTK_RESPONSE_OK: break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); gtk_widget_destroy(GTK_WIDGET(dialogue)); return response == GTK_RESPONSE_OK; }
static gboolean mif_read_image_header(MIFImageHeader *header, const guchar **p, gsize size, guint file_version, GError **error) { const guchar *buffer = *p; guint i; gwy_clear(header, 1); if (size < IMAGE_HEADER_START_SIZE) return err_IMAGE_HEADER_TOO_SHORT(error); get_CHARARRAY(header->time, p); get_CHARARRAY(header->title, p); get_CHARARRAY(header->comment, p); gwy_debug("image <%.*s>", (guint)sizeof(header->title), header->title); if (!mif_read_scan_setup(&header->setup, p, size - (*p - buffer), file_version, error)) return FALSE; if (!mif_read_image_configuration(&header->configuration, p, size - (*p - buffer), file_version, error)) return FALSE; if (file_version == 0x107) { /* TODO: Check size */ header->tunnel_current = gwy_get_gfloat_le(p); gwy_debug("tunnel_current: %g", header->tunnel_current); header->bias_voltage = gwy_get_gfloat_le(p); gwy_debug("bias_voltage: %g", header->bias_voltage); header->force = gwy_get_gfloat_le(p); gwy_debug("force: %g", header->force); header->as_measured = *((*p)++); gwy_debug_bool(header, as_measured); header->n_curves = gwy_get_guint32_le(p); gwy_debug("n_curves: %u", header->n_curves); for (i = 0; i < MAX_CURVES; i++) { header->curve_points[i].x = gwy_get_guint32_le(p); header->curve_points[i].y = gwy_get_guint32_le(p); } header->low_fraction = gwy_get_gfloat_le(p); header->high_fraction = gwy_get_gfloat_le(p); gwy_debug("low_fraction: %g, high_fraction: %g", header->low_fraction, header->high_fraction); if (!mif_read_axis_info(&header->z_axis, p, size - (*p - buffer), file_version, error)) return FALSE; if (!mif_read_id(&header->id.primary, p, size - (*p - buffer), error) || !mif_read_id(&header->id.secondary, p, size - (*p - buffer), error)) return FALSE; } else { g_return_val_if_reached(FALSE); } return TRUE; }
static GwyContainer* omicron_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { OmicronFile ofile; GwyContainer *container = NULL, *meta; gchar *text = NULL; GError *err = NULL; GwyDataField *dfield = NULL; GwySpectra *spectra = NULL; gchar key[32]; guint i; /* @text must not be destroyed while @ofile is still in used because * all strings are only references there */ if (!g_file_get_contents(filename, &text, NULL, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&ofile, 1); ofile.filename = filename; if (!omicron_read_header(text, &ofile, error)) goto fail; if (!ofile.topo_channels || !ofile.topo_channels->len) { err_NO_DATA(error); goto fail; } container = gwy_container_new(); /* First Load the Topographic Data */ for (i = 0; i < ofile.topo_channels->len; i++) { OmicronTopoChannel *channel; channel = g_ptr_array_index(ofile.topo_channels, i); dfield = omicron_read_data(&ofile, channel, error); if (!dfield) { gwy_object_unref(container); goto fail; } g_snprintf(key, sizeof(key), "/%u/data", i); gwy_container_set_object_by_name(container, key, dfield); g_object_unref(dfield); if (channel->name) { gchar *s; g_snprintf(key, sizeof(key), "/%u/data/title", i); if (channel->scandir == SCAN_FORWARD) s = g_strdup_printf("%s (Forward)", channel->name); else if (channel->scandir == SCAN_BACKWARD) s = g_strdup_printf("%s (Backward)", channel->name); else s = g_strdup(channel->name); gwy_container_set_string_by_name(container, key, s); } if ((meta = omicron_make_meta(&ofile))) { g_snprintf(key, sizeof(key), "/%u/meta", i); gwy_container_set_object_by_name(container, key, meta); g_object_unref(meta); } } /* Then load the spectroscopy data. */ /* * There are two types of spectroscopy file: * * a) Single Point Spectroscopy Files * Single point which is stored by SCALA as an ascii file. Any number of * single point spectrums may be aquired, but the number is normally * quite small. These files are identified by their filename *.cs[0..3] * * b) Binary Spectroscopy Files * When large numbers of spectra are aquired on a regular grid they are * stored in BE binary. These data are aquired during the scan, and so * can be aquired during the forward scan or the backward scan. * * Forwards scan files can be indentified from their filename *.sf[0..3] * Backward scan files can be indentified from their filename *.sb[0..3] */ if (ofile.spectro_channels) { for (i = 0; i < ofile.spectro_channels->len; i++) { OmicronSpectroChannel *channel; channel = g_ptr_array_index(ofile.spectro_channels, i); if (omicron_has_extension(channel->filename, "cs")) { gchar *t; GQuark quark; spectra = omicron_read_cs_data(&ofile, channel, error); if (!spectra) { gwy_object_unref(container); goto fail; } if (!gwy_spectra_get_n_spectra(spectra)) { gwy_debug("Spectra %u is empty, ignoring", i); g_object_unref(spectra); continue; } /* FIXME */ t = g_strconcat(channel->chan, "-", channel->param, NULL); gwy_spectra_set_title(spectra, t); g_free(t); quark = gwy_app_get_spectra_key_for_id(i); gwy_container_set_object(container, quark, spectra); g_object_unref(spectra); } else if (omicron_has_extension(channel->filename, "sf") || omicron_has_extension(channel->filename, "sb")) { /* FIXME */ } else { g_warning("Cannot determine spectra type of %s", channel->filename); } } } fail: omicron_file_free(&ofile); g_free(text); return container; }
static GwyContainer* oldmda_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; OldMDAFile mdafile; gchar *head, *buffer = NULL; gchar *buffer2 = NULL; gchar *dataname = NULL, *dname; GMarkupParser parser = { start_element, end_element, parse_text, NULL, NULL }; GMarkupParseContext *context; gsize size, size2; MDAXMLParams params; GError *err = NULL; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } gwy_clear(&mdafile, 1); head = g_strndup(buffer, 1024); if (!check_magic(head)) { err_FILE_TYPE(error, "NTMDT old MDA"); g_free(head); goto fail; } g_free(head); params.xdata = g_array_new(FALSE, TRUE, sizeof(gdouble)); params.numaxes = 0; params.axes = g_array_new(FALSE, FALSE, sizeof(MDAAxis)); params.flag = MDA_XML_NONE; context = g_markup_parse_context_new(&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, ¶ms, NULL); if (!g_markup_parse_context_parse(context, buffer, size, &err) || !g_markup_parse_context_end_parse(context, &err)) { g_clear_error(&err); g_markup_parse_context_free(context); } else { g_markup_parse_context_free(context); } if (params.axes->len != 4) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Incorrect number of axes in parameter file.")); goto fail; } oldmda_read_params(¶ms, &mdafile); dname = g_strdelimit(params.dataname, "\\/", G_DIR_SEPARATOR); if (!(dataname = oldmda_find_data_name(filename, dname))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("No corresponding data file was found for header file.")); goto fail; } if (!g_file_get_contents(dataname, &buffer2, &size2, &err)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO, _("Cannot load data file: %s"), err->message); g_clear_error(&err); goto fail; } if ((size2 != params.arraysize * params.datacellmemsize) || (params.arraysize != mdafile.xres * mdafile.yres * mdafile.zres)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO, _("Data file is too short.")); g_clear_error(&err); goto fail2; } container = gwy_container_new(); mdafile.data = container; mdafile.filename = dataname; oldmda_read_data(&mdafile, buffer2); fail2: g_free(buffer2); fail: oldmda_free(¶ms); g_free(buffer); return container; }
static gboolean noise_synth_dialog(NoiseSynthArgs *args, GwyDimensionArgs *dimsargs, GwyContainer *data, GwyDataField *dfield_template, gint id) { GtkWidget *dialog, *table, *vbox, *hbox, *notebook, *label; NoiseSynthControls controls; GwyDataField *dfield; GwyPixmapLayer *layer; gboolean finished; gint response; gint row; gwy_clear(&controls, 1); controls.in_init = TRUE; controls.args = args; dialog = gtk_dialog_new_with_buttons(_("Random Noise"), NULL, 0, _("_Reset"), RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); controls.dialog = dialog; hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 4); vbox = gtk_vbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4); controls.mydata = gwy_container_new(); dfield = gwy_data_field_new(PREVIEW_SIZE, PREVIEW_SIZE, dimsargs->measure*PREVIEW_SIZE, dimsargs->measure*PREVIEW_SIZE, TRUE); gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield); controls.noise = gwy_data_field_new_alike(dfield, FALSE); if (dfield_template) { gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE, GWY_DATA_ITEM_PALETTE, 0); controls.surface = gwy_synth_surface_for_preview(dfield_template, PREVIEW_SIZE); controls.zscale = gwy_data_field_get_rms(dfield_template); } controls.view = gwy_data_view_new(controls.mydata); layer = gwy_layer_basic_new(); g_object_set(layer, "data-key", "/0/data", "gradient-key", "/0/base/palette", NULL); gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer); gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), gwy_synth_instant_updates_new(&controls, &controls.update_now, &controls.update, &args->update), FALSE, FALSE, 0); g_signal_connect_swapped(controls.update_now, "clicked", G_CALLBACK(preview), &controls); gtk_box_pack_start(GTK_BOX(vbox), gwy_synth_random_seed_new(&controls, &controls.seed, &args->seed), FALSE, FALSE, 0); controls.randomize = gwy_synth_randomize_new(&args->randomize); gtk_box_pack_start(GTK_BOX(vbox), controls.randomize, FALSE, FALSE, 0); notebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 4); g_signal_connect_swapped(notebook, "switch-page", G_CALLBACK(page_switched), &controls); controls.dims = gwy_dimensions_new(dimsargs, dfield_template); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gwy_dimensions_get_widget(controls.dims), gtk_label_new(_("Dimensions"))); if (controls.dims->add) g_signal_connect_swapped(controls.dims->add, "toggled", G_CALLBACK(noise_synth_invalidate), &controls); table = gtk_table_new(6 + (dfield_template ? 1 : 0), 4, FALSE); controls.table = GTK_TABLE(table); gtk_table_set_row_spacings(controls.table, 2); gtk_table_set_col_spacings(controls.table, 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, gtk_label_new(_("Generator"))); row = 0; controls.distribution = distribution_selector_new(&controls); gwy_table_attach_hscale(table, row, _("_Distribution:"), NULL, GTK_OBJECT(controls.distribution), GWY_HSCALE_WIDGET); row++; label = gtk_label_new(_("Direction:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.direction = gwy_radio_buttons_createl(G_CALLBACK(direction_type_changed), &controls, args->direction, _("S_ymmetrical"), NOISE_DIRECTION_BOTH, _("One-sided _positive"), NOISE_DIRECTION_UP, _("One-sided _negative"), NOISE_DIRECTION_DOWN, NULL); row = gwy_radio_buttons_attach_to_table(controls.direction, GTK_TABLE(table), 3, row); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); row = gwy_synth_attach_height(&controls, row, &controls.sigma, &args->sigma, _("_RMS:"), NULL, &controls.sigma_units); if (dfield_template) { controls.sigma_init = gtk_button_new_with_mnemonic(_("_Like Current Channel")); g_signal_connect_swapped(controls.sigma_init, "clicked", G_CALLBACK(sigma_init_clicked), &controls); gtk_table_attach(GTK_TABLE(table), controls.sigma_init, 1, 3, row, row+1, GTK_FILL, 0, 0, 0); row++; } gtk_widget_show_all(dialog); controls.in_init = FALSE; /* Must be done when widgets are shown, see GtkNotebook docs */ gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), args->active_page); update_values(&controls); noise_synth_invalidate(&controls); finished = FALSE; while (!finished) { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_OK: gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: finished = TRUE; break; case RESPONSE_RESET: { gboolean temp = args->update; gint temp2 = args->active_page; *args = noise_synth_defaults; args->active_page = temp2; args->update = temp; } controls.in_init = TRUE; update_controls(&controls, args); controls.in_init = FALSE; if (args->update) preview(&controls); break; default: g_assert_not_reached(); break; } } if (controls.sid) { g_source_remove(controls.sid); controls.sid = 0; } g_object_unref(controls.mydata); gwy_object_unref(controls.surface); gwy_object_unref(controls.noise); gwy_dimensions_free(controls.dims); return response == GTK_RESPONSE_OK; }
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 gboolean read_aist_raster(const guchar **p, gsize *size, AistContext *context) { AistRaster raster; GwyDataField *dfield, *mfield; GwySIUnit *xyunit, *zunit; gboolean ok = FALSE; guint i, j, n, len; const guchar *data; gchar *s; gchar key[32]; gdouble *d; gdouble qxy, qz; gwy_clear(&raster, 1); gwy_debug("reading common"); if (!read_aist_common(p, size, &raster.common)) goto fail; gwy_debug("reading raster"); if (!read_qt_int(p, size, &raster.xres) || !read_qt_int(p, size, &raster.yres) || !read_qt_double(p, size, &raster.left) || !read_qt_double(p, size, &raster.right) || !read_qt_double(p, size, &raster.top) || !read_qt_double(p, size, &raster.bottom) || !read_qt_string(p, size, &raster.xunits) || !read_qt_string(p, size, &raster.yunits) || !read_qt_string(p, size, &raster.zunits)) goto fail; if (!read_qt_byte_array(p, size, &len, &data)) goto fail; n = raster.xres * raster.yres; if (len != n*sizeof(gdouble)) goto fail; xyunit = extract_units(raster.xunits, &qxy); zunit = extract_units(raster.zunits, &qz); dfield = gwy_data_field_new(raster.xres, raster.yres, qxy*fabs(raster.right - raster.left), qxy*fabs(raster.bottom - raster.top), FALSE); gwy_data_field_set_si_unit_xy(dfield, xyunit); gwy_data_field_set_si_unit_z(dfield, zunit); /* Apparently this is not generally wanted. gwy_data_field_set_xoffset(dfield, qxy*MIN(raster.left, raster.right)); gwy_data_field_set_yoffset(dfield, qxy*MIN(raster.top, raster.bottom)); */ g_object_unref(xyunit); g_object_unref(zunit); d = gwy_data_field_get_data(dfield); for (i = 0; i < raster.yres; i++) { for (j = 0; j < raster.xres; j++) { d[(raster.yres-1 - i)*raster.xres + j] = qz*gwy_get_gdouble_le(&data); } } g_snprintf(key, sizeof(key), "/%d/data", context->channel_id); gwy_container_set_object_by_name(context->container, key, dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(context->container, context->channel_id, NULL, context->filename); if ((s = strchr(raster.common.name, '['))) s = g_strchomp(g_strndup(raster.common.name, s - raster.common.name)); else s = g_strdup(raster.common.name); g_snprintf(key, sizeof(key), "/%d/data/title", context->channel_id); gwy_container_set_string_by_name(context->container, key, s); g_snprintf(key, sizeof(key), "/%d/mask", context->channel_id); context->channel_id++; /* At this moment we consider the loading successful. */ ok = TRUE; /* The mask raster is byte-valued. It contains nonzeroes in points that * were measured (the opposite of how we normally create masks upon * import). */ if (read_qt_byte_array(p, size, &len, &data)) { if (len == raster.xres*raster.yres) { mfield = make_mask_field(dfield, data); if (mfield) { gwy_app_channel_remove_bad_data(dfield, mfield); gwy_container_set_object_by_name(context->container, key, mfield); g_object_unref(mfield); } } /* Here's something called view data. It means the data was processed * (by whatever means) hence we are not interesed in it. */ read_qt_byte_array(p, size, &len, &data); } fail: free_aist_common(&raster.common); g_free(raster.xunits); g_free(raster.yunits); g_free(raster.zunits); return ok; }
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 gboolean merge_dialog(MergeArgs *args) { MergeControls controls; GtkWidget *dialog, *table, *combo, *check; GwyDataChooser *chooser; gint response, row; gboolean ok; gwy_clear(&controls, 1); controls.args = args; dialog = gtk_dialog_new_with_buttons(_("Merge Data"), NULL, 0, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); controls.dialog = dialog; gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); table = gtk_table_new(6, 4, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 4); row = 0; /* Merge with */ controls.op2 = gwy_data_chooser_new_channels(); chooser = GWY_DATA_CHOOSER(controls.op2); g_object_set_data(G_OBJECT(chooser), "dialog", dialog); gwy_data_chooser_set_active_id(chooser, &args->op2); gwy_data_chooser_set_filter(chooser, merge_data_filter, args, NULL); gwy_data_chooser_get_active_id(chooser, &args->op2); g_signal_connect_swapped(chooser, "changed", G_CALLBACK(merge_data_changed), &controls); merge_data_changed(&controls, chooser); gwy_table_attach_hscale(table, row, _("_Merge with:"), NULL, GTK_OBJECT(chooser), GWY_HSCALE_WIDGET); row++; /* Parameters */ combo = gwy_enum_combo_box_new(directions, G_N_ELEMENTS(directions), G_CALLBACK(merge_direction_changed), &controls, args->direction, TRUE); gwy_table_attach_hscale(table, row, _("_Put second operand:"), NULL, GTK_OBJECT(combo), GWY_HSCALE_WIDGET); row++; combo = gwy_enum_combo_box_new(modes, G_N_ELEMENTS(modes), G_CALLBACK(merge_mode_changed), &controls, args->mode, TRUE); gwy_table_attach_hscale(table, row, _("_Align second operand:"), NULL, GTK_OBJECT(combo), GWY_HSCALE_WIDGET); row++; combo = gwy_enum_combo_box_new(boundaries, G_N_ELEMENTS(boundaries), G_CALLBACK(merge_boundary_changed), &controls, args->boundary, TRUE); controls.boundary = combo; gwy_table_attach_hscale(table, row, _("_Boundary treatment:"), NULL, GTK_OBJECT(combo), GWY_HSCALE_WIDGET); row++; check = gtk_check_button_new_with_mnemonic(_("Crop result to _avoid " "outside pixels")); controls.crop_to_rectangle = check; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), args->crop_to_rectangle); gtk_table_attach(GTK_TABLE(table), check, 0, 3, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(check, "toggled", G_CALLBACK(crop_to_rectangle_changed), &controls); row++; check = gtk_check_button_new_with_mnemonic(_("Add _mask of outside pixels")); controls.create_mask = check; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), args->create_mask); gtk_table_attach(GTK_TABLE(table), check, 0, 3, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(check, "toggled", G_CALLBACK(create_mask_changed), &controls); row++; update_sensitivity(&controls); gtk_widget_show_all(dialog); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_NONE: gtk_widget_destroy(dialog); return FALSE; break; case GTK_RESPONSE_OK: ok = TRUE; break; default: g_assert_not_reached(); break; } } while (!ok); gtk_widget_destroy(dialog); return TRUE; }
static GwyContainer* plt_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; GwyDataField *dfield = NULL; GwyTextHeaderParser parser; GwySIUnit *xunit, *yunit, *zunit; gchar *p, *value, *buffer = NULL; GHashTable *hash = NULL; gsize size; GError *err = NULL; G_GNUC_UNUSED gdouble xreal, yreal, zreal; gint i, xres, yres; gdouble *data; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } if (strncmp(buffer, MAGIC1, MIN(size, sizeof(MAGIC1)-1))) { err_FILE_TYPE(error, "Nanosurf PLT"); goto fail; } /* Find the first line not starting with '#' */ for (p = buffer; (p - buffer) + 1 < size; p++) { if ((p[0] == '\n' || p[0] == '\r') && (p[1] != '\n' && p[1] != '#')) { break; } } *p = '\0'; p++; gwy_clear(&parser, 1); parser.line_prefix = "#"; parser.key_value_separator = ":"; hash = gwy_text_header_parse(buffer, &parser, NULL, NULL); if (!require_keys(hash, error, "Channel", "Lines", "Points", "XRange", "YRange", "ZRange", NULL)) goto fail; xres = atoi(g_hash_table_lookup(hash, "Points")); yres = atoi(g_hash_table_lookup(hash, "Lines")); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; value = g_hash_table_lookup(hash, "XRange"); xreal = g_ascii_strtod(value, &value); xunit = gwy_si_unit_new(value); value = g_hash_table_lookup(hash, "YRange"); yreal = g_ascii_strtod(value, &value); yunit = gwy_si_unit_new(value); value = g_hash_table_lookup(hash, "ZRange"); zreal = g_ascii_strtod(value, &value); zunit = gwy_si_unit_new(value); /* 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; } if (!gwy_si_unit_equal(xunit, yunit)) g_warning("X and Y units differ, using X"); dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_si_unit_xy(dfield, xunit); gwy_data_field_set_si_unit_z(dfield, zunit); g_object_unref(xunit); g_object_unref(yunit); g_object_unref(zunit); data = gwy_data_field_get_data(dfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = g_ascii_strtod(value, &p); value = p; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if ((value = g_hash_table_lookup(hash, "Channel"))) 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: g_free(buffer); g_hash_table_destroy(hash); return container; }
static void facets_dialog(FacetsArgs *args, GwyContainer *data, GwyContainer *fdata, GwyDataField *dfield, GwyDataField *mfield, gint id, GQuark mquark) { GtkWidget *dialog, *table, *hbox, *hbox2, *vbox, *label, *scale, *button; GtkWidget *spin; FacetsControls controls; gint response; GwySelection *selection; gint row; gwy_clear(&controls, 1); controls.args = args; dialog = gtk_dialog_new_with_buttons(_("Mark Facets"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, gwy_sgettext("verb|_Mark"), RESPONSE_PREVIEW, _("_Reset"), RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); controls.dialog = dialog; /* Shallow-copy stuff to temporary container */ controls.fdata = fdata; controls.mydata = gwy_container_new(); gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield); gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE, GWY_DATA_ITEM_PALETTE, GWY_DATA_ITEM_RANGE, GWY_DATA_ITEM_MASK_COLOR, GWY_DATA_ITEM_REAL_SQUARE, 0); hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 4); controls.view = create_preview(controls.mydata, 0, PREVIEW_SIZE, TRUE); gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4); selection = create_vector_layer(GWY_DATA_VIEW(controls.view), 0, "Point", TRUE); g_signal_connect(selection, "changed", G_CALLBACK(preview_selection_updated), &controls); vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); hbox2 = gtk_hbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0); /* Slope view */ controls.fview = create_preview(controls.fdata, 0, FDATA_RES, TRUE); gtk_box_pack_start(GTK_BOX(hbox2), controls.fview, FALSE, FALSE, 0); selection = create_vector_layer(GWY_DATA_VIEW(controls.fview), 0, "Point", TRUE); g_signal_connect(selection, "changed", G_CALLBACK(facet_view_selection_updated), &controls); /* Info table */ table = gtk_table_new(7, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(hbox2), table, TRUE, TRUE, 4); row = 0; /* TRANSLATORS: The direction or line orthogonal to something. */ label = gwy_label_new_header(_("Normal")); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.theta_label = add_angle_label(table, _("θ:"), &row); controls.phi_label = add_angle_label(table, _("φ:"), &row); button = gtk_button_new_with_mnemonic(_("_Find Maximum")); gtk_table_attach(GTK_TABLE(table), button, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(button, "clicked", G_CALLBACK(facet_view_reset_maximum), &controls); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; label = gwy_label_new_header(_("Mean Normal")); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.mtheta_label = add_angle_label(table, _("θ:"), &row); controls.mphi_label = add_angle_label(table, _("φ:"), &row); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); label = gtk_label_new_with_mnemonic(_("Facet plane size:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.kernel_size = gtk_adjustment_new(args->kernel_size, 0.0, MAX_PLANE_SIZE, 1.0, 1.0, 0); spin = gtk_spin_button_new(GTK_ADJUSTMENT(controls.kernel_size), 0.0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin); gtk_table_attach(GTK_TABLE(table), spin, 0, 1, row, row+1, 0, 0, 0, 0); g_signal_connect(controls.kernel_size, "value-changed", G_CALLBACK(facet_view_recompute), &controls); row++; table = gtk_table_new(4 + 2*(!!mfield), 4, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 4); row = 0; controls.tolerance = gtk_adjustment_new(args->tolerance*180.0/G_PI, 0.0, 15.0, 0.01, 0.1, 0); scale = gwy_table_attach_hscale(table, row++, _("_Tolerance:"), _("deg"), controls.tolerance, 0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(scale), 3); g_signal_connect(controls.tolerance, "value-changed", G_CALLBACK(facets_tolerance_changed), &controls); if (mfield) { gwy_container_set_object_by_name(controls.fdata, "/1/mask", mfield); controls.combine = gtk_check_button_new_with_mnemonic(_("Com_bine with " "existing mask")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.combine), args->combine); gtk_table_attach(GTK_TABLE(table), controls.combine, 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); g_signal_connect(controls.combine, "toggled", G_CALLBACK(combine_changed), &controls); row++; controls.combine_type = gwy_enum_combo_box_new(gwy_merge_type_get_enum(), -1, G_CALLBACK(combine_type_changed), &controls, args->combine_type, TRUE); gwy_table_attach_hscale(table, row, _("Operation:"), NULL, GTK_OBJECT(controls.combine_type), GWY_HSCALE_WIDGET); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; } controls.color_button = create_mask_color_button(controls.mydata, dialog, 0); gwy_table_attach_hscale(table, row, _("_Mask color:"), NULL, GTK_OBJECT(controls.color_button), GWY_HSCALE_WIDGET_NO_EXPAND); row++; if (!gwy_si_unit_equal(gwy_data_field_get_si_unit_xy(dfield), gwy_data_field_get_si_unit_z(dfield))) { gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); label = gtk_label_new(_("Warning: Lateral and value units differ. " "Angles are not physically meaningful.")); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; } gtk_widget_show_all(dialog); facet_view_select_angle(&controls, args->theta0, args->phi0); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: g_object_unref(controls.mydata); facets_save_args(gwy_app_settings_get(), args); return; break; case GTK_RESPONSE_OK: break; case RESPONSE_RESET: args->tolerance = facets_defaults.tolerance; args->kernel_size = facets_defaults.kernel_size; facets_dialog_update_controls(&controls, args); break; case RESPONSE_PREVIEW: preview(&controls, args); update_average_angle(&controls, args); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE, GWY_DATA_ITEM_MASK_COLOR, 0); gtk_widget_destroy(dialog); g_object_unref(controls.mydata); run_noninteractive(args, data, fdata, dfield, mfield, mquark); facets_save_args(gwy_app_settings_get(), args); gwy_app_channel_log_add_proc(data, id, id); }
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 GwyContainer* pt3file_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { PicoHarpFile pt3file; GwyContainer *meta, *container = NULL; GwyDataField *dfield = NULL; GwyGraphModel *gmodel = NULL; guchar *buffer = NULL; const guchar *p; gsize header_len, size = 0; GError *err = NULL; LineTrigger *linetriggers = NULL; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&pt3file, 1); if (!(header_len = pt3file_read_header(buffer, size, &pt3file, error))) goto fail; if (err_SIZE_MISMATCH (error, header_len + pt3file.number_of_records*sizeof(guint32), size, FALSE)) goto fail; if (pt3file.measurement_mode != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("T2 measurement mode is not implemented.")); goto fail; } if (pt3file.imaging.common.instrument != PICO_HARP_PIE710 && pt3file.imaging.common.instrument != PICO_HARP_KDT180) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only PI E710 and KDT180-100-Im imaging formats are " "implemented.")); goto fail; } /* Scan the records and find the line triggers */ p = buffer + header_len; if (!(linetriggers = pt3file_scan_line_triggers(&pt3file, p, error))) goto fail; container = gwy_container_new(); dfield = pt3file_extract_counts(&pt3file, linetriggers, p); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Photon count")); meta = pt3file_get_metadata(&pt3file); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); gmodel = pt3file_extract_decay(&pt3file, p); gwy_container_set_object_by_name(container, "/0/graph/graph/1", gmodel); g_object_unref(gmodel); fail: g_free(linetriggers); gwy_file_abandon_contents(buffer, size, NULL); return container; }
static void start_element(G_GNUC_UNUSED GMarkupParseContext *context, const gchar *element_name, G_GNUC_UNUSED const gchar **attribute_names, G_GNUC_UNUSED const gchar **attribute_values, gpointer user_data, G_GNUC_UNUSED GError **error) { const gchar **name_cursor = attribute_names; const gchar **value_cursor = attribute_values; MDAAxis axis; gchar *value; MDAXMLParams *params = (MDAXMLParams *)user_data; if (params->flag != MDA_XML_NONE) { /* error */ } else { if (gwy_strequal(element_name, "ArraySize")) { params->flag = MDA_XML_ARRAYSIZE; } else if (gwy_strequal(element_name, "DataCellMemSize")) { params->flag = MDA_XML_DATACELL_MEMSIZE; } else if (gwy_strequal(element_name, "MinIndex")) { params->flag = MDA_XML_MININDEX; } else if (gwy_strequal(element_name, "MaxIndex")) { params->flag = MDA_XML_MAXINDEX; } else if (gwy_strequal(element_name, "Name")) { params->flag = MDA_XML_NAME; } else if (gwy_strequal(element_name, "Data")) { params->flag = MDA_XML_DATANAME; } else if (gwy_strequal(element_name, "Calibration")) { params->numaxes++; gwy_clear(&axis, 1); while (*name_cursor) { if (gwy_strequal(*name_cursor, "UnitName")) { axis.unitname = g_strdup(*value_cursor); } else if (gwy_strequal(*name_cursor, "Bias")) { value = g_strdup(*value_cursor); axis.bias = g_ascii_strtod(g_strdelimit(value, ",.", '.'), NULL); g_free(value); } else if (gwy_strequal(*name_cursor, "Scale")) { value = g_strdup(*value_cursor); axis.scale = g_ascii_strtod(g_strdelimit(value, ",.", '.'), NULL); g_free(value); } name_cursor++; value_cursor++; } g_array_append_val(params->axes, axis); } else if (gwy_strequal(element_name, "Array")) { params->flag = MDA_XML_DATAARRAY; while (*name_cursor) { if (gwy_strequal(*name_cursor, "Count")) params->res = atoi(*value_cursor); name_cursor++; value_cursor++; } } } }
static GwyContainer* burleigh_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwySIUnit *unit; GwyContainer *container = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; GError *err = NULL; IMGFile imgfile; GwyDataField *dfield; gdouble *data; const gint16 *d; gdouble zoom; guint i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE_MIN + 2) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } gwy_clear(&imgfile, 1); p = buffer; imgfile.version = gwy_get_gfloat_le(&p); imgfile.version_int = GWY_ROUND(10*imgfile.version); if (imgfile.version_int == 21) { d = burleigh_load_v21(&imgfile, buffer, size, error); if (!d) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File format version %.1f is not supported."), imgfile.version); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } zoom = burleigh_get_zoom_v21(&imgfile); if (err_DIMENSION(error, imgfile.xres) || err_DIMENSION(error, imgfile.yres)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } dfield = gwy_data_field_new(imgfile.xres, imgfile.yres, Angstrom*imgfile.xrange/zoom, Angstrom*imgfile.yrange/zoom, FALSE); data = gwy_data_field_get_data(dfield); for (i = 0; i < imgfile.xres*imgfile.yres; i++) data[i] = GINT16_FROM_LE(d[i])*imgfile.zrange/4095.0; gwy_file_abandon_contents(buffer, size, NULL); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); container = gwy_container_new(); switch (imgfile.data_type) { case BURLEIGH_CURRENT: unit = gwy_si_unit_new("A"); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Current")); gwy_data_field_multiply(dfield, Picoampere); break; case BURLEIGH_TOPOGRAPHY: unit = gwy_si_unit_new("m"); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Topography")); gwy_data_field_multiply(dfield, Angstrom); break; default: unit = gwy_si_unit_new("m"); break; } gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(container, 0, NULL, filename); return container; }
static GwyContainer* unisoku_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { UnisokuFile ufile; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gchar *text = NULL; gsize i, size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gchar *data_name; if (!g_file_get_contents(filename, &text, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } for (i = 0; i < size; i++) { if (!text[i]) text[i] = ' '; } gwy_clear(&ufile, 1); if (!unisoku_read_header(text, &ufile, error)) { unisoku_file_free(&ufile); g_free(text); return NULL; } g_free(text); if (ufile.data_type < UNISOKU_UINT8 || ufile.data_type > UNISOKU_FLOAT || type_sizes[ufile.data_type] == 0) { err_DATA_TYPE(error, ufile.data_type); unisoku_file_free(&ufile); return NULL; } if (!(data_name = unisoku_find_data_name(filename))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("No corresponding data file was found for header file.")); unisoku_file_free(&ufile); return NULL; } if (!gwy_file_get_contents(data_name, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); unisoku_file_free(&ufile); g_free(data_name); return NULL; } dfield = unisoku_read_data_field(buffer, size, &ufile, error); gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) { unisoku_file_free(&ufile); g_free(data_name); return NULL; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_app_channel_title_fall_back(container, 0); meta = unisoku_get_metadata(&ufile); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, data_name); unisoku_file_free(&ufile); g_free(data_name); return container; }