示例#1
0
/**
 * 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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
/**
 * 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;
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
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;
}
示例#17
0
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;
}
示例#18
0
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;
}
示例#19
0
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;
}
示例#20
0
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);
}
示例#21
0
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;
}
示例#22
0
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;
}
示例#23
0
/* 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;
}