/** * file_register_plugins: * @plugins: Plug-in list to eventually add the plug-in to. * @file: Plug-in file (full path). * @buffer: The output from "plugin register". * * Parse output from "plugin register" and eventually add it to the * plugin-list. * * Returns: The new plug-in list, with the plug-in eventually prepended. **/ static GList* file_register_plugins(GList *plugins, const gchar *file, gchar *buffer) { FilePluginInfo *info; gchar *pname = NULL, *file_desc = NULL, *run_modes = NULL, *glob = NULL; GwyFileOperationType run; gwy_debug("buffer: <<<%s>>>", buffer); while (buffer) { if ((pname = gwy_str_next_line(&buffer)) && *pname && (file_desc = gwy_str_next_line(&buffer)) && *file_desc && (glob = gwy_str_next_line(&buffer)) && *glob && (run_modes = gwy_str_next_line(&buffer)) && (run = gwy_string_to_flags(run_modes, file_op_names, -1, NULL))) { info = g_new0(FilePluginInfo, 1); info->name = g_strdup(pname); info->description = g_strdup(file_desc); if (gwy_file_func_register(info->name, info->description, &file_plugin_proxy_detect, (run & GWY_FILE_OPERATION_LOAD) ? file_plugin_proxy_load : NULL, NULL, (run & GWY_FILE_OPERATION_EXPORT) ? file_plugin_proxy_export : NULL)) { info->file = g_strdup(file); info->run = run; info->glob = g_strdup(glob); info->pattern = file_patternize_globs(glob); info->specificity = file_glob_specificities(glob); plugins = g_list_prepend(plugins, info); } else { g_free((gpointer)info->name); g_free((gpointer)info->description); g_free(info); } } else if (pname && *pname) { g_warning("failed; " "pname = %s, file_desc = %s, run_modes = %s, glob = %s", pname, file_desc, run_modes, glob); } while (buffer && *buffer) gwy_str_next_line(&buffer); } return plugins; }
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 GwyResource* gwy_gl_material_parse(const gchar *text, gboolean is_const) { GwyGLMaterial *gl_material = NULL; GwyRGBA ambient, diffuse, specular, emission; gdouble shininess; GwyGLMaterialClass *klass; gchar *str, *p, *line, *end; g_return_val_if_fail(text, NULL); klass = g_type_class_peek(GWY_TYPE_GL_MATERIAL); g_return_val_if_fail(klass, NULL); p = str = g_strdup(text); if (!(line = gwy_str_next_line(&p)) || !gwy_gl_material_parse_component(line, &ambient)) goto fail; if (!(line = gwy_str_next_line(&p)) || !gwy_gl_material_parse_component(line, &diffuse)) goto fail; if (!(line = gwy_str_next_line(&p)) || !gwy_gl_material_parse_component(line, &specular)) goto fail; if (!(line = gwy_str_next_line(&p)) || !gwy_gl_material_parse_component(line, &emission)) goto fail; if (!(line = gwy_str_next_line(&p))) goto fail; shininess = g_ascii_strtod(line, &end); if (end == line) { line = NULL; goto fail; } gwy_gl_material_set_rgba(&ambient, &ambient); gwy_gl_material_set_rgba(&diffuse, &diffuse); gwy_gl_material_set_rgba(&specular, &specular); gwy_gl_material_set_rgba(&emission, &emission); shininess = CLAMP(shininess, 0.0, 1.0); gl_material = gwy_gl_material_new("", &ambient, &diffuse, &specular, &emission, shininess, is_const); fail: if (!line) g_warning("Cannot parse GL material."); g_free(str); return (GwyResource*)gl_material; }
/** * proc_register_plugins: * @plugins: Plug-in list to eventually add the plug-in to. * @file: Plug-in file (full path). * @buffer: The output from "plugin register". * * Parse output from "plugin register" and eventually add it to the * plugin-list. * * Returns: The new plug-in list, with the plug-in eventually prepended. **/ static GList* proc_register_plugins(GList *plugins, const gchar *file, gchar *buffer) { ProcPluginInfo *info; gchar *pname = NULL, *menu_path = NULL, *run_modes = NULL; GwyRunType run; gwy_debug("buffer: <<<%s>>>", buffer); while (buffer) { if ((pname = gwy_str_next_line(&buffer)) && *pname && (menu_path = gwy_str_next_line(&buffer)) && menu_path[0] == '/' && (run_modes = gwy_str_next_line(&buffer)) && (run = gwy_string_to_flags(run_modes, run_mode_names, -1, NULL))) { info = g_new(ProcPluginInfo, 1); info->name = g_strdup(pname); info->menu_path = g_strconcat(_("/_Plug-Ins"), menu_path, NULL); info->tooltip = g_strdup_printf(_("Run plug-in %s"), menu_path+1); info->run = run; if (gwy_process_func_register(info->name, proc_plugin_proxy_run, info->menu_path, NULL, info->run, GWY_MENU_FLAG_DATA, info->tooltip)) { info->file = g_strdup(file); plugins = g_list_prepend(plugins, info); } else { g_free((gpointer)info->name); g_free((gpointer)info->menu_path); g_free((gpointer)info->tooltip); g_free(info); } } else if (pname && *pname) { g_warning("failed; " "pname = %s, menu_path = %s, run_modes = %s", pname, menu_path, run_modes); } while (buffer && *buffer) gwy_str_next_line(&buffer); } return plugins; }
static GwySurface* read_xyz_points(gchar *p) { GwySurface *surface; GArray *points; gchar *line, *end; char comma_fix_char = 0; points = g_array_new(FALSE, FALSE, sizeof(GwyXYZ)); for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { GwyXYZ pt; if (!line[0] || line[0] == '#') continue; if (!comma_fix_char) { comma_fix_char = figure_out_comma_fix_char(line); if (!comma_fix_char) continue; } for (end = line; *end; end++) { if (*end == ';') *end = ' '; else if (*end == ',') *end = comma_fix_char; } if (!(pt.x = g_ascii_strtod(line, &end)) && end == line) continue; line = end; while (g_ascii_isspace(*line)) line++; if (!(pt.y = g_ascii_strtod(line, &end)) && end == line) continue; line = end; while (g_ascii_isspace(*line)) line++; if (!(pt.z = g_ascii_strtod(line, &end)) && end == line) continue; g_array_append_val(points, pt); } surface = gwy_surface_new_from_data((GwyXYZ*)points->data, points->len); g_array_free(points, TRUE); return surface; }
static gchar* sdfile_next_line(gchar **buffer, const gchar *key, GError **error) { guint klen; gchar *value, *line; do { line = gwy_str_next_line(buffer); } while (line && line[0] == ';'); if (!line) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when looking for `%s' field."), key); return NULL; } klen = strlen(key); if (strncmp(line, key, klen) != 0 || !g_ascii_isspace(line[klen])) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Invalid line found when looking for `%s' field."), key); return NULL; } value = line + klen; g_strstrip(value); if (value[0] == '=') { value++; g_strstrip(value); } return value; }
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 gboolean parse_dim(gchar **p, const gchar *name, gint *value, GError **error) { gchar *vp, *line; line = gwy_str_next_line(p); if (!line) { err_MISSING_FIELD(error, name); return FALSE; } vp = strchr(line, ':'); if (!vp) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); return FALSE; } *vp = '\0'; vp++; gwy_debug("<%s> = <%s>", name, vp); if (!gwy_strequal(line, name)) { err_MISSING_FIELD(error, name); return FALSE; } *value = strtol(vp, NULL, 10); if (err_DIMENSION(error, *value)) return FALSE; return TRUE; }
static GHashTable* parse_comment(gchar *text) { gchar *line, *value, *p = text; GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal); for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { if (g_str_has_prefix(line, "Date :") || g_str_has_prefix(line, "Time :")) value = line + 6; else if (!(value = strchr(line, '='))) continue; *value = '\0'; value++; g_strstrip(line); g_strstrip(value); g_hash_table_insert(hash, line, value); gwy_debug("<%s> = <%s>", line, value); } return hash; }
static gboolean parse_scale(gchar **p, const gchar *name, double *value, GwySIUnit **units, GError **error) { gint power10; gchar *vp, *line; line = gwy_str_next_line(p); if (!line) { err_MISSING_FIELD(error, name); return FALSE; } vp = strchr(line, ':'); if (!vp) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); return FALSE; } *vp = '\0'; vp++; gwy_debug("<%s> = <%s>", name, vp); if (!gwy_strequal(line, name)) { err_MISSING_FIELD(error, name); return FALSE; } *value = g_ascii_strtod(vp, &vp); *units = gwy_si_unit_new_parse(vp, &power10); *value *= pow10(power10); if (!*value) { g_warning("%s is 0.0, fixing to 1.0", name); *value = 1.0; } return TRUE; }
static GwyContainer* int_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta; GwyDataField *dfield = NULL, *mfield = NULL; CodeVGridDataType type; gchar *line, *p, *comment, *end, *buffer = NULL; const gchar *unit, *title; gchar **fields = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal; gint i, xres, yres, no_data_value = 32767; guint fi; gdouble scale_size, wavelength, q = 1.0, x_scale = 1.0; gboolean nearest_neighbour = FALSE; gdouble *data, *mdata; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } /* Skip comments. */ p = buffer; for (line = gwy_str_next_line(&p); line && line[0] == '!'; line = gwy_str_next_line(&p)) { gwy_debug("comment <%s>", line); } if (!line) { err_FILE_TYPE(error, "Code V INT"); goto fail; } /* The title. */ comment = line; if (!(line = gwy_str_next_line(&p))) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("comment <%s>", comment); fields = split_line_in_place(line); if (!fields || g_strv_length(fields) < 8 || !gwy_strequal(fields[0], "GRD") || !(xres = atoi(fields[1])) || !(yres = atoi(fields[2])) || !(type = gwy_stramong(fields[3], "SUR", "WFR", "FIL", "THV", "BIR", "CAO", NULL)) || !gwy_strequal(fields[4], "WVL") || (!(wavelength = g_ascii_strtod(fields[5], &end)) && end == fields[5])) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("type %u (%s)", type, fields[3]); gwy_debug("xres %d, yres %d", xres, yres); gwy_debug("wavelength %g", wavelength); fi = 6; if (gwy_strequal(fields[fi], "NNB")) { nearest_neighbour = TRUE; fi++; } gwy_debug("nearest_neighbour %d", nearest_neighbour); if (!fields[fi] || !gwy_strequal(fields[fi], "SSZ")) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; if (!(scale_size = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("scale_size %g", scale_size); if (!scale_size) { g_warning("Zero SSZ, fixing to 1.0"); scale_size = 1.0; } fi++; if (fields[fi] && gwy_strequal(fields[fi], "NDA")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } no_data_value = atoi(fields[fi]); fi++; } gwy_debug("no_data_value %d", no_data_value); if (fields[fi] && gwy_strequal(fields[fi], "XSC")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } if (!(x_scale = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; } gwy_debug("x_scale %g", x_scale); if (!x_scale) { g_warning("Zero XSC, fixing to 1.0"); x_scale = 1.0; } /* There may be more stuff but we do not know anything about it. */ if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; yreal = 1.0; xreal = x_scale*yreal; dfield = gwy_data_field_new(xres, yres, xreal, yreal, TRUE); if (type == CODEV_INT_SURFACE_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Surface"; } else if (type == CODEV_INT_WAVEFRONT_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Wavefront"; } else { g_warning("Don't know how to convert this grid data type to physical " "units."); title = fields[3]; } gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), unit); mfield = gwy_data_field_new_alike(dfield, TRUE); data = gwy_data_field_get_data(dfield); mdata = gwy_data_field_get_data(mfield); for (i = 0; i < xres*yres; i++, p = end) { gint value = strtol(p, &end, 10); if (value != no_data_value && (type != CODEV_INT_INTENSITY_FILTER || value >= 0)) { mdata[i] = 1.0; data[i] = q*value; } } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) gwy_object_unref(mfield); container = gwy_container_new(); /* gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); from F. Riguet : apparently no flip is needed (the raw data import module gives the correct orientation without further flipping) */ gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); gwy_app_channel_check_nonsquare(container, 0); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); if (mfield) { /* gwy_data_field_invert(mfield, FALSE, TRUE, FALSE); */ gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } meta = gwy_container_new(); gwy_container_set_string_by_name(meta, "Comment", g_strdup(comment)); gwy_container_set_string_by_name(meta, "Interpolation", g_strdup(nearest_neighbour ? "NNB" : "Linear")); gwy_container_set_string_by_name(meta, "Wavelength", g_strdup_printf("%g μm", wavelength)); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: g_free(fields); g_free(buffer); return container; }
static GHashTable* read_hash(gchar *buffer, gint *text_data_start, GError **error) { enum { WHATEVER = 0, PROCESS_PROFILE, COMMENT, } next_is; GHashTable *hash; gchar *p, *line, *value; GString *key; *text_data_start = 0; p = buffer; hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); line = gwy_str_next_line(&p); /* Version 4 text data. */ if (gwy_strequal(line, MAGIC_ASCII)) line = gwy_str_next_line(&p); key = g_string_new(NULL); g_hash_table_insert(hash, g_strdup("Version"), line + MAGIC_SIZE); next_is = WHATEVER; while ((line = gwy_str_next_line(&p))) { guint len; gchar *rb; if (line[0] == '/') line++; if (line[0] == '\x1a') { /* Apparently a binary data marker */ *text_data_start = 0; break; } g_strstrip(line); /* sections */ if (line[0] == '[' && (rb = strchr(line, ']'))) { *rb = '\0'; line++; g_strstrip(line); gwy_debug("section %s", line); g_string_assign(key, line); g_string_append(key, "::"); if (gwy_strequal(line, "PROCESS PROFILE")) { next_is = PROCESS_PROFILE; continue; } if (gwy_strequal(line, "COMMENT")) { next_is = COMMENT; continue; } if (g_str_has_prefix(line, "DATA ")) { line += strlen("DATA"); *text_data_start = p - buffer; break; } next_is = WHATEVER; /* Other sectioning seems too be uninteresting. */ continue; } if (next_is == PROCESS_PROFILE) { g_hash_table_insert(hash, g_strdup("ProcessProfile"), line); next_is = WHATEVER; continue; } if (next_is == COMMENT) { g_hash_table_insert(hash, g_strdup("Comment"), line); next_is = WHATEVER; continue; } next_is = WHATEVER; value = strchr(line, ':'); if (!value) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); g_hash_table_destroy(hash); return NULL; } *value = '\0'; value++; g_strstrip(line); g_strstrip(value); len = key->len; g_string_append(key, line); gwy_debug("%s = %s", key->str, value); g_hash_table_replace(hash, g_strdup(key->str), value); g_string_truncate(key, len); } if (*text_data_start) { g_strstrip(line); if (!g_str_has_prefix(line, "Unit(") || !g_str_has_suffix(line, ")")) { g_warning("Cannot parse DATA unit: %s", line); g_hash_table_insert(hash, g_strdup("DATA Unit"), "1"); } else { line += strlen("Unit("); line[strlen(line)-1] = '\0'; g_hash_table_insert(hash, g_strdup("DATA Unit"), line); } } return hash; }
static GHashTable* read_hash(gchar **buffer, GError **error) { GHashTable *hash; NanoscopeValue *value; gchar *line, *colon; line = gwy_str_next_line(buffer); if (line[0] != '\\' || line[1] != '*') return NULL; if (gwy_strequal(line, "\\*File list end")) { gwy_debug("FILE LIST END"); return NULL; } hash = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(hash, "#self", line + 2); /* self */ gwy_debug("hash table <%s>", line + 2); while ((*buffer)[0] == '\\' && (*buffer)[1] && (*buffer)[1] != '*') { line = gwy_str_next_line(buffer) + 1; if (!line || !line[0] || !line[1] || !line[2]) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Truncated header line.")); goto fail; } colon = line; if (line[0] == '@' && g_ascii_isdigit(line[1]) && line[2] == ':') colon = line+3; colon = strchr(colon, ':'); if (!colon || !g_ascii_isspace(colon[1])) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); goto fail; } *colon = '\0'; do { colon++; } while (g_ascii_isspace(*colon)); value = parse_value(line, colon); if (value) g_hash_table_insert(hash, line, value); } /* Fix random stuff in Nanoscope E files */ if ((value = g_hash_table_lookup(hash, "Samps/line")) && !g_hash_table_lookup(hash, "Number of lines") && value->hard_value_units && g_ascii_isdigit(value->hard_value_units[0])) { NanoscopeValue *val; val = g_new0(NanoscopeValue, 1); val->hard_value = g_ascii_strtod(value->hard_value_units, NULL); val->hard_value_str = value->hard_value_units; g_hash_table_insert(hash, "Number of lines", val); } return hash; fail: g_hash_table_destroy(hash); return NULL; }
static GwyContainer* text_dump_import(gchar *buffer, gsize size, const gchar *filename, GError **error) { gchar *val, *key, *pos, *line, *title; GwyContainer *data; GwyDataField *dfield; gdouble xreal, yreal; gint xres, yres, id; GwySIUnit *uxy, *uz; const guchar *s; gdouble *d; gsize n; data = gwy_container_new(); pos = buffer; while ((line = gwy_str_next_line(&pos)) && *line) { val = strchr(line, '='); if (!val || *line != '/') { g_warning("Garbage key: %s", line); continue; } if ((gsize)(val - buffer) + 1 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when value was expected.")); goto fail; } *val = '\0'; val++; if (!gwy_strequal(val, "[") || !pos || *pos != '[') { gwy_debug("<%s>=<%s>", line, val); if (*val) gwy_container_set_string_by_name(data, line, g_strdup(val)); else gwy_container_remove_by_name(data, line); continue; } g_assert(pos && *pos == '['); pos++; dfield = NULL; gwy_container_gis_object_by_name(data, line, &dfield); id = 0; sscanf(line, "/%d", &id); /* get datafield parameters from already read values, failing back * to values of original data field */ key = g_strconcat(line, "/xres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xres = atoi(s); else if (dfield) xres = gwy_data_field_get_xres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field width.")); goto fail; } g_free(key); key = g_strconcat(line, "/yres", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yres = atoi(s); else if (dfield) yres = gwy_data_field_get_yres(dfield); else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data field height.")); goto fail; } g_free(key); key = g_strconcat(line, "/xreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) xreal = g_ascii_strtod(s, NULL); else if (dfield) xreal = gwy_data_field_get_xreal(dfield); else { g_warning("Missing real data field width."); xreal = 1.0; /* 0 could cause troubles */ } g_free(key); key = g_strconcat(line, "/yreal", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) yreal = g_ascii_strtod(s, NULL); else if (dfield) yreal = gwy_data_field_get_yreal(dfield); else { g_warning("Missing real data field height."); yreal = 1.0; /* 0 could cause troubles */ } g_free(key); if (!(xres > 0 && yres > 0 && xreal > 0 && yreal > 0)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Data field dimensions are not positive numbers.")); goto fail; } key = g_strconcat(line, "/unit-xy", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uxy = gwy_si_unit_new((const gchar*)s); else if (dfield) { uxy = gwy_data_field_get_si_unit_xy(dfield); uxy = gwy_si_unit_duplicate(uxy); } else { g_warning("Missing lateral units."); uxy = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/unit-z", NULL); if (gwy_container_gis_string_by_name(data, key, &s)) uz = gwy_si_unit_new((const gchar*)s); else if (dfield) { uz = gwy_data_field_get_si_unit_z(dfield); uz = gwy_si_unit_duplicate(uz); } else { g_warning("Missing value units."); uz = gwy_si_unit_new("m"); } g_free(key); key = g_strconcat(line, "/title", NULL); title = NULL; gwy_container_gis_string_by_name(data, key, (const guchar**)&title); /* We got the contained string but that would disappear. */ title = g_strdup(title); g_free(key); n = xres*yres*sizeof(gdouble); if ((gsize)(pos - buffer) + n + 3 > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached inside a data field.")); goto fail; } dfield = GWY_DATA_FIELD(gwy_data_field_new(xres, yres, xreal, yreal, FALSE)); gwy_data_field_set_si_unit_xy(dfield, GWY_SI_UNIT(uxy)); gwy_object_unref(uxy); gwy_data_field_set_si_unit_z(dfield, GWY_SI_UNIT(uz)); gwy_object_unref(uz); d = gwy_data_field_get_data(dfield); #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) memcpy(d, pos, n); #else gwy_memcpy_byte_swap(pos, (guint8*)d, sizeof(gdouble), xres*yres, sizeof(gdouble)-1); #endif pos += n; val = gwy_str_next_line(&pos); if (!gwy_strequal(val, "]]")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing end of data field marker.")); gwy_object_unref(dfield); goto fail; } gwy_container_remove_by_prefix(data, line); gwy_container_set_object_by_name(data, line, dfield); g_object_unref(dfield); if (title) { key = g_strconcat(line, "/title", NULL); gwy_container_set_string_by_name(data, key, title); g_free(key); } gwy_file_channel_import_log_add(data, id, NULL, filename); } return data; fail: gwy_container_remove_by_prefix(data, NULL); g_object_unref(data); return NULL; }
static GwyDataField* sdfile_read_data_text(SDFile *sdfile, GError **error) { gint i, n; GwyDataField *dfield; gdouble *data; gchar *p, *end, *line; dfield = gwy_data_field_new(sdfile->xres, sdfile->yres, sdfile->xres * sdfile->xscale, sdfile->yres * sdfile->yscale, FALSE); data = gwy_data_field_get_data(dfield); n = sdfile->xres * sdfile->yres; switch (sdfile->data_type) { case SDF_UINT8: case SDF_SINT8: case SDF_UINT16: case SDF_SINT16: case SDF_UINT32: case SDF_SINT32: p = sdfile->data; for (i = 0; i < n; i++) { data[i] = strtol(p, (gchar**)&end, 10); if (p == end) { g_object_unref(dfield); g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when reading sample #%d " "of %d"), i, n); return NULL; } p = end; } break; case SDF_FLOAT: case SDF_DOUBLE: p = sdfile->data; for (i = 0; i < n; i++) { data[i] = g_ascii_strtod(p, (gchar**)&end); if (p == end) { g_object_unref(dfield); g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when reading sample #%d " "of %d"), i, n); return NULL; } p = end; } break; default: g_return_val_if_reached(NULL); break; } /* Find out if there is anything beyond the end-of-data-marker */ while (*end && *end != '*') end++; if (!*end) { gwy_debug("Missing end-of-data marker `*' was ignored"); return dfield; } do { end++; } while (g_ascii_isspace(*end)); if (!*end) return dfield; /* Read the extra stuff */ end--; sdfile->extras = g_hash_table_new(g_str_hash, g_str_equal); while ((line = gwy_str_next_line(&end))) { g_strstrip(line); if (!*line || *line == ';') continue; for (p = line; g_ascii_isalnum(*p); p++) ; if (!*p || (*p != '=' && !g_ascii_isspace(*p))) continue; *p = '\0'; p++; while (*p == '=' || g_ascii_isspace(*p)) p++; if (!*p) continue; g_strstrip(p); gwy_debug("extra: <%s> = <%s>", line, p); g_hash_table_insert(sdfile->extras, line, p); } return dfield; }
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 unisoku_read_header(gchar *buffer, UnisokuFile *ufile, GError **error) { gchar *line; gint type1, type2; line = gwy_str_next_line(&buffer); if (!line) return FALSE; NEXT(buffer, line, error); /* garbage */ NEXT(buffer, line, error); if (unisoku_sscanf(line, "i", &ufile->format_version) != 1) { err_UNSUPPORTED(error, _("format version")); return FALSE; } NEXT(buffer, line, error); ufile->date = g_strdup(line); NEXT(buffer, line, error); ufile->time = g_strdup(line); NEXT(buffer, line, error); ufile->sample_name = g_strdup(line); NEXT(buffer, line, error); ufile->remark = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &ufile->ascii_flag, &type1) != 2) { err_INVALID(error, _("format flags")); return FALSE; } ufile->data_type = type1; NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &ufile->xres, &ufile->yres) != 2) { err_INVALID(error, _("resolution")); return FALSE; } if (err_DIMENSION(error, ufile->xres) || err_DIMENSION(error, ufile->yres)) return FALSE; NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &type1, &type2) != 2) { /* FIXME */ g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing or invalid some integers heaven knows what " "they mean but that should be here.")); return FALSE; } ufile->dim_x = type1; ufile->dim_y = type2; NEXT(buffer, line, error); ufile->unit_x = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddi", &ufile->start_x, &ufile->end_x, &ufile->log_flag_x) != 3) { err_INVALID(error, _("x scale parameters")); return FALSE; } NEXT(buffer, line, error); ufile->unit_y = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddii", &ufile->start_y, &ufile->end_y, &ufile->ineq_flag, &ufile->log_flag_y) != 4) { err_INVALID(error, _("y scale parameters")); return FALSE; } /* Use negated positive conditions to catch NaNs */ if (!(ufile->end_x - ufile->start_x > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); ufile->start_x = 0.0; ufile->end_x = 1.0; } if (!(ufile->end_y - ufile->start_y > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); ufile->start_y = 0.0; ufile->end_y = 1.0; } NEXT(buffer, line, error); ufile->unit_z = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddddi", &ufile->max_raw_z, &ufile->min_raw_z, &ufile->max_z, &ufile->min_z, &ufile->log_flag_z) != 5) { err_INVALID(error, _("z scale parameters")); return FALSE; } NEXT(buffer, line, error); if (unisoku_sscanf(line, "dddi", &ufile->stm_voltage, &ufile->stm_current, &ufile->scan_time, &ufile->accum) != 4) { err_INVALID(error, _("data type parameters")); return FALSE; } NEXT(buffer, line, error); /* reserved */ NEXT(buffer, line, error); ufile->stm_voltage_unit = g_strdup(line); NEXT(buffer, line, error); ufile->stm_current_unit = g_strdup(line); NEXT(buffer, line, error); ufile->ad_name = g_strdup(line); /* There is more stuff after that, but heaven knows what it means... */ return TRUE; }
static GwyContainer* sly_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta = NULL; gchar *buffer = NULL; GError *err = NULL; GHashTable *hash = NULL; gchar *p, *line, *value; guint expecting_data = 0; SensolyticsChannel *channels = NULL; Dimensions dimensions; gint ndata = 0, i; if (!g_file_get_contents(filename, &buffer, NULL, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = buffer; line = gwy_str_next_line(&p); g_strstrip(line); if (!gwy_strequal(line, MAGIC)) { err_FILE_TYPE(error, "Sensolytics"); goto fail; } hash = g_hash_table_new(g_str_hash, g_str_equal); for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { if (!line[0]) continue; if (expecting_data) { expecting_data--; /* The columns are comma-separated and numbers use decimal points. * Do not tempt the number parsing functions more than necessary * and fix commas to tab characters. */ g_strdelimit(line, ",", '\t'); /* Ignore X, Y and Z, each is two values */ for (i = 0; i < 6; i++) g_ascii_strtod(line, &line); for (i = 0; i < ndata; i++) channels[i].data[expecting_data] = channels[i].q * g_ascii_strtod(line, &line); } else { g_strstrip(line); if (line[0] != '#') { g_warning("Comment line does not start with #."); continue; } do { line++; } while (g_ascii_isspace(*line)); if (g_str_has_prefix(line, "X [")) { if (channels) { g_warning("Multiple data headers!?"); continue; } if (!read_dimensions(hash, &ndata, &dimensions, error) || !(channels = create_fields(hash, line, ndata, &dimensions))) goto fail; expecting_data = dimensions.xres * dimensions.yres; continue; } value = strchr(line, ':'); if (!value) { if (!gwy_strequal(line, "ArrayScan")) g_warning("Non-parameter-like line %s", line); continue; } *value = '\0'; g_strchomp(line); do { value++; } while (g_ascii_isspace(*value)); if (gwy_strequal(line, "Warning")) continue; gwy_debug("<%s>=<%s>", line, value); g_hash_table_insert(hash, line, value); } } if (!channels) { err_NO_DATA(error); goto fail; } container = gwy_container_new(); for (i = 0; i < ndata; i++) { GQuark key = gwy_app_get_data_key_for_id(i); gwy_data_field_invert(channels[i].dfield, FALSE, TRUE, FALSE); gwy_container_set_object(container, key, channels[i].dfield); gwy_app_channel_check_nonsquare(container, i); if (channels[i].name) { gchar *s = g_strconcat(g_quark_to_string(key), "/title", NULL); gwy_container_set_string_by_name(container, s, g_strdup(channels[i].name)); g_free(s); } else gwy_app_channel_title_fall_back(container, i); gwy_file_channel_import_log_add(container, i, NULL, filename); } meta = get_meta(hash); clone_meta(container, meta, ndata); g_object_unref(meta); fail: g_free(buffer); if (hash) g_hash_table_destroy(hash); if (channels) { for (i = 0; i < ndata; i++) g_object_unref(channels[i].dfield); g_free(channels); } return container; }
static gboolean omicron_read_header(gchar *buffer, OmicronFile *ofile, GError **error) { gchar *line, *val, *comment; ofile->meta = g_hash_table_new(g_str_hash, g_str_equal); while ((line = gwy_str_next_line(&buffer))) { /* FIXME: This strips 2nd and following lines from possibly multiline * fields like Comment. */ if (!line[0] || line[0] == ';' || g_ascii_isspace(line[0])) continue; val = strchr(line, ':'); if (!val) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); return FALSE; } if (val == line) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Header line starts with a colon.")); return FALSE; } *val = '\0'; val++; g_strstrip(line); comment = strchr(val, ';'); if (comment) { /* If the coment has the form ;[units], move the [units] part after * the number. */ if (comment[1] == '[' && (g_ascii_isalpha(comment[2]) || comment[2] == '%')) { gchar *c, *s = comment-1; while (g_ascii_isspace(*s)) s--; s++; c = comment + 1; *c = ' '; while (*c && *c != ']') *(s++) = *(c++); *s = '\0'; } else *comment = '\0'; comment++; g_strstrip(comment); } g_strstrip(val); if (gwy_strequal(line, "Topographic Channel")) { OmicronTopoChannel *channel; gwy_debug("Topographic Channel found (type %c)", val[0]); channel = g_new0(OmicronTopoChannel, 1); channel->type = val[0]; if (!omicron_read_topo_header(&buffer, channel, error)) { g_free(channel); return FALSE; } if (!ofile->topo_channels) ofile->topo_channels = g_ptr_array_new(); g_ptr_array_add(ofile->topo_channels, channel); } else if (gwy_strequal(line, "Spectroscopy Channel")) { OmicronSpectroChannel *channel; gwy_debug("Spectroscopic Channel found (chan %s)", val); channel = g_new0(OmicronSpectroChannel, 1); channel->chan = val; if (!omicron_read_spectro_header(&buffer, channel, error)) { g_free(channel); return FALSE; } if (!ofile->spectro_channels) ofile->spectro_channels = g_ptr_array_new(); g_ptr_array_add(ofile->spectro_channels, channel); } else { gwy_debug("<%s> = <%s>", line, val); g_hash_table_insert(ofile->meta, line, val); } } GET_FIELD(ofile->meta, val, "Image Size in X", error); ofile->xres = abs(atoi(val)); GET_FIELD(ofile->meta, val, "Image Size in Y", error); ofile->yres = abs(atoi(val)); if (err_DIMENSION(error, ofile->xres) || err_DIMENSION(error, ofile->yres)) return FALSE; GET_FIELD(ofile->meta, val, "Field X Size in nm", error); ofile->xreal = g_ascii_strtod(val, NULL); GET_FIELD(ofile->meta, val, "Field Y Size in nm", error); ofile->yreal = g_ascii_strtod(val, NULL); /* Use negated positive conditions to catch NaNs */ if (!((ofile->xreal = fabs(ofile->xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); ofile->xreal = 1.0; } if (!((ofile->yreal = fabs(ofile->yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); ofile->yreal = 1.0; } ofile->xreal *= Nanometer; ofile->yreal *= Nanometer; return TRUE; }
static void gfilter_load_args(GwyContainer *container, GFilterArgs *args) { GwyInventory *inventory; gchar *filename, *buffer; gsize size; guint i; inventory = gwy_grain_values(); *args = gfilter_defaults; gwy_container_gis_boolean_by_name(container, update_key, &args->update); gwy_container_gis_int32_by_name(container, expanded_key, &args->expanded); gwy_container_gis_enum_by_name(container, logical_key, &args->logical); for (i = 0; i < NQUANTITIES; i++) { RangeRecord *rr = args->ranges + i; gchar buf[sizeof(quantity_key) + 10]; g_snprintf(buf, sizeof(buf), "%s%u", quantity_key, i+1); gwy_container_gis_string_by_name(container, buf, (const guchar**)&rr->quantity); } args->ranges_history = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, range_record_free); filename = g_build_filename(gwy_get_user_dir(), "grain_filter", "ranges", NULL); if (g_file_get_contents(filename, &buffer, &size, NULL)) { gchar *p = buffer, *line; for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { g_strstrip(line); if (*line) { GwyGrainValue *gvalue; RangeRecord *rr; gchar *s = line, *end; gdouble lower, upper; lower = g_ascii_strtod(s, &end); s = end; upper = g_ascii_strtod(s, &end); if (end == s) { g_warning("Invalid grain_filter range record: %s.", line); continue; } s = end; g_strstrip(s); if (!(gvalue = gwy_inventory_get_item(inventory, s))) { g_warning("Invalid grain_filter range record: %s.", line); continue; } rr = g_slice_new(RangeRecord); rr->lower = lower; rr->upper = upper; rr->quantity = gwy_resource_get_name(GWY_RESOURCE(gvalue)); g_hash_table_insert(args->ranges_history, (gpointer)rr->quantity, rr); } } g_free(buffer); } g_free(filename); gfilter_sanitize_args(args); }
static GwySpectra* omicron_read_cs_data(OmicronFile *ofile, OmicronSpectroChannel *channel, GError **error) { GError *err = NULL; GwyDataLine *dline; GwySIUnit *siunit = NULL, *coord_unit = NULL; GwySpectra *spectra = NULL; GPtrArray *spectrum = NULL; gchar *filename; gdouble *data, x, y; gdouble *coords = NULL; gchar *buffer; gdouble scale; guint i, j; gint power10 = 0; gint ncurves = 0; gchar* line; filename = omicron_fix_file_name(ofile->filename, channel->filename, error); if (!filename) return NULL; gwy_debug("Succeeded with <%s>", filename); if (!g_file_get_contents(filename, &buffer, NULL , &err)) { g_free(filename); err_GET_FILE_CONTENTS(error, &err); return NULL; } g_free(filename); scale = channel->resolution; /* can also be extracted from min&max raw and phys settings */ while ((line = gwy_str_next_line(&buffer))) { if (strstr(line, ";n_curves")) { /* Find number of curves this should appear first in file */ ncurves = g_ascii_strtod(strchr(line, ':')+1, NULL); } if (strstr(line, "BEGIN COORD")) { /* Read in cordinates Spectroscopy Curves */ i = 0; coord_unit = gwy_si_unit_new_parse("nm", &power10); while ((line = gwy_str_next_line(&buffer))) { gchar *val2; if (strstr(line, "END")) { if (i != ncurves) { gwy_debug("Less coords than ncurves"); } break; } if (i == ncurves) { g_critical("More coords than ncurves."); break; } if (!coords) { if (!(coords = g_new0(gdouble, ncurves*2))) { gwy_debug("Failed to allocate mem: coords"); return NULL; } } val2 = line+16; x = g_ascii_strtod(line, &val2) * pow10(power10); y = g_ascii_strtod(val2, NULL) * pow10(power10); gwy_debug("Coord %i: x:%g y:%g", i, x, y); coords[2*i] = x; coords[2*i+1] = y; i++; } /* i is set to 0 and used as a counter for the dline */ i = 0; } if (strstr(line, "BEGIN") && !strstr(line, "COORD")) { /* Read spectroscopy points */ dline = gwy_data_line_new(channel->npoints, channel->end - channel->start, FALSE); gwy_data_line_set_offset(dline, (channel->start)); data = gwy_data_line_get_data(dline); j = 0; while ((line = gwy_str_next_line(&buffer))) { gchar *val2; if (strstr(line, "END") || j >= channel->npoints) break; val2 = line+13; x = g_ascii_strtod(line, &val2); y = g_ascii_strtod(val2, NULL)*scale; data[j] = y; j++; } /* Set Units for the parameter (x) axis */ if ((channel->param[0] == 'V') || (channel->param[0] == 'E')) { siunit = gwy_si_unit_new("V"); power10 = 0; } else if (channel->param[0] == 'I') siunit = gwy_si_unit_new_parse("nA", &power10); else if (channel->param[0] == 'Z') siunit = gwy_si_unit_new_parse("nm", &power10); else { gwy_debug("Parameter unit not recognised"); } if (siunit) { gwy_data_line_set_si_unit_x(dline, siunit); g_object_unref(siunit); } if (power10) { gdouble offset = 0; gdouble realsize = 0; offset = gwy_data_line_get_offset(dline)*pow10(power10); realsize = gwy_data_line_get_real(dline)*pow10(power10); gwy_data_line_set_offset(dline, offset); gwy_data_line_set_real(dline, realsize); } /* Set Units for the Value (y) Axis */ siunit = gwy_si_unit_new_parse(channel->units, &power10); gwy_data_line_set_si_unit_y(dline, siunit); g_object_unref(siunit); if (power10) gwy_data_line_multiply(dline, pow10(power10)); if (!spectrum) spectrum = g_ptr_array_sized_new(ncurves); g_ptr_array_add(spectrum, dline); } } if (!spectrum) spectrum = g_ptr_array_new(); if (spectrum->len < ncurves) { gwy_debug("Less actual spectra than ncurves"); ncurves = spectrum->len; } if (spectrum->len > ncurves) { gwy_debug("More actual spectra than ncurves, " "remaining pos will be set at (0.0,0.0)"); coords = g_renew(gdouble, coords, spectrum->len*2); if (!coords) { g_critical("Could not reallocate mem for coords."); return NULL; } while (spectrum->len > ncurves) { coords[ncurves*2] = 0.0; coords[ncurves*2+1] = 0.0; ncurves++; } } spectra = gwy_spectra_new(); if (coord_unit) { gwy_spectra_set_si_unit_xy(spectra, coord_unit); g_object_unref(coord_unit); } for (i = 0; i < ncurves; i++) { dline = g_ptr_array_index(spectrum, i); gwy_spectra_add_spectrum(spectra, dline, coords[i*2], ofile->yreal - coords[i*2+1]); g_object_unref(dline); } g_ptr_array_free(spectrum, TRUE); g_free(coords); g_free(buffer); return spectra; }
static gboolean file_read_header(GPtrArray *ezdfile, gchar *buffer, GError **error) { EZDSection *section = NULL; gchar *p, *line; guint len; while ((line = gwy_str_next_line(&buffer))) { line = g_strstrip(line); if (!(len = strlen(line))) continue; if (line[0] == '[' && line[len-1] == ']') { section = g_new0(EZDSection, 1); g_ptr_array_add(ezdfile, section); line[len-1] = '\0'; section->name = g_strdup(line + 1); section->meta = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); gwy_debug("Section <%s>", section->name); continue; } if (!section) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Garbage before first header section.")); return FALSE; } /* Skip comments */ if (g_str_has_prefix(line, "--")) continue; p = strchr(line, '='); if (!p) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Malformed header line (missing =).")); return FALSE; } *p = '\0'; p++; if (gwy_strequal(line, "SaveMode")) { if (strcmp(p, "Binary")) g_warning("SaveMode is not Binary, this is not supported"); } else if (gwy_strequal(line, "SaveBits")) section->bitdepth = atol(p); else if (gwy_strequal(line, "SaveSign")) { section->sign = gwy_strequal(p, "Signed"); if (!section->sign) g_warning("SaveSign is not Signed, this is not supported"); } else if (gwy_strequal(line, "SaveOrder")) { if (gwy_strequal(p, "Intel")) section->byteorder = G_LITTLE_ENDIAN; else g_warning("SaveOrder is not Intel, this is not supported"); } else if (gwy_strequal(line, "Frame")) { if (gwy_strequal(p, "Scan forward")) section->direction = SCAN_FORWARD; else if (gwy_strequal(p, "Scan backward")) section->direction = SCAN_BACKWARD; } else if (gwy_strequal(line, "Points")) section->xres = atol(p); else if (gwy_strequal(line, "Lines")) section->yres = atol(p); /* FIXME: this is ugly, and incorrect for non-2D data */ else if (gwy_strequal(line, "Dim0Name")) section->xrange.name = g_strdup(p); else if (gwy_strequal(line, "Dim1Name")) section->yrange.name = g_strdup(p); else if (gwy_strequal(line, "Dim2Name")) section->zrange.name = g_strdup(p); else if (gwy_strequal(line, "Dim0Unit")) section->xrange.unit = g_strdup(p); else if (gwy_strequal(line, "Dim1Unit")) section->yrange.unit = g_strdup(p); else if (gwy_strequal(line, "Dim2Unit")) section->zrange.unit = g_strdup(p); else if (gwy_strequal(line, "Dim0Min")) section->xrange.min = g_ascii_strtod(p, NULL); else if (gwy_strequal(line, "Dim1Min")) section->yrange.min = g_ascii_strtod(p, NULL); else if (gwy_strequal(line, "Dim2Min")) section->zrange.min = g_ascii_strtod(p, NULL); else if (gwy_strequal(line, "Dim0Range")) section->xrange.range = g_ascii_strtod(p, NULL); else if (gwy_strequal(line, "Dim1Range")) section->yrange.range = g_ascii_strtod(p, NULL); else if (gwy_strequal(line, "Dim2Range")) section->zrange.range = g_ascii_strtod(p, NULL); else g_hash_table_replace(section->meta, g_strdup(line), g_strdup(p)); } return TRUE; }
/* NB: Buffer must be writable and nul-terminated, its initial part is * overwritten */ static gboolean sdfile_read_header_text(gchar **buffer, gsize *len, SDFile *sdfile, GError **error) { gchar *val, *p; /* We do not need exact lenght of the minimum file */ if (*len < SDF_MIN_TEXT_SIZE) { err_TOO_SHORT(error); return FALSE; } gwy_clear(sdfile, 1); p = *buffer; val = g_strstrip(gwy_str_next_line(&p)); strncpy(sdfile->version, val, sizeof(sdfile->version)); READ_STRING(p, "ManufacID", val, sdfile->manufacturer, error) READ_STRING(p, "CreateDate", val, sdfile->creation, error) READ_STRING(p, "ModDate", val, sdfile->modification, error) READ_INT(p, "NumPoints", val, sdfile->xres, TRUE, error) READ_INT(p, "NumProfiles", val, sdfile->yres, TRUE, error) READ_FLOAT(p, "Xscale", val, sdfile->xscale, TRUE, error) READ_FLOAT(p, "Yscale", val, sdfile->yscale, TRUE, error) READ_FLOAT(p, "Zscale", val, sdfile->zscale, TRUE, error) READ_FLOAT(p, "Zresolution", val, sdfile->zres, FALSE, error) READ_INT(p, "Compression", val, sdfile->compression, FALSE, error) READ_INT(p, "DataType", val, sdfile->data_type, FALSE, error) READ_INT(p, "CheckType", val, sdfile->check_type, FALSE, error) /* at least */ if (sdfile->data_type < SDF_NTYPES) sdfile->expected_size = 2*sdfile->xres * sdfile->yres; else sdfile->expected_size = -1; /* Skip possible extra header lines */ do { val = gwy_str_next_line(&p); if (!val) break; val = g_strstrip(val); if (g_ascii_isalpha(val[0])) { gwy_debug("Extra header line: <%s>\n", val); } } while (val[0] == ';' || g_ascii_isalpha(val[0])); if (!val || *val != '*') { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing data start marker (*).")); return FALSE; } *buffer = p; *len -= p - *buffer; sdfile->data = (gchar*)*buffer; return TRUE; }