Example #1
0
static void
run_noninteractive(FacetsArgs *args,
                   GwyContainer *data,
                   GwyContainer *fdata,
                   GwyDataField *dfield,
                   GwyDataField *mfield,
                   GQuark mquark)
{
    GwyDataField *dtheta, *dphi, *mask;

    gwy_app_undo_qcheckpointv(data, 1, &mquark);
    mask = create_mask_field(dfield);

    dtheta = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/theta"));
    dphi = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/phi"));
    gwy_data_field_mark_facets(dtheta, dphi, args->theta0, args->phi0,
                               args->tolerance, mask);
    if (mfield && args->combine) {
        if (args->combine_type == GWY_MERGE_UNION)
            gwy_data_field_grains_add(mfield, mask);
        else if (args->combine_type == GWY_MERGE_INTERSECTION)
            gwy_data_field_grains_intersect(mfield, mask);
        gwy_data_field_data_changed(mfield);
    }
    else if (mfield) {
        gwy_data_field_copy(mask, mfield, FALSE);
        gwy_data_field_data_changed(mfield);
    }
    else {
        gwy_container_set_object(data, mquark, mask);
    }
    g_object_unref(mask);
}
Example #2
0
static void
rotate_counterclockwise_90(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3], *newfield;
    GQuark quarks[3];
    gint i, id;

    g_return_if_fail(run & BASICOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_KEY, quarks + 0,
                                     GWY_APP_MASK_FIELD_KEY, quarks + 1,
                                     GWY_APP_SHOW_FIELD_KEY, quarks + 2,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    clean_quarks(G_N_ELEMENTS(quarks), quarks, dfields);
    gwy_app_undo_qcheckpointv(data, G_N_ELEMENTS(quarks), quarks);
    for (i = 0; i < G_N_ELEMENTS(dfields); i++) {
        if (dfields[i]) {
            newfield = gwy_data_field_new_alike(dfields[i], FALSE);
            flip_xy(dfields[i], newfield, TRUE);
            gwy_container_set_object(data, quarks[i], newfield);
            g_object_unref(newfield);
        }
    }
    gwy_app_data_clear_selections(data, id);
    gwy_app_channel_log_add_proc(data, id, id);
}
Example #3
0
static void
presentation_logscale(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *sfield;
    GQuark squark;
    gdouble *d;
    gdouble min, max, m0;
    gint xres, yres, i, zeroes, id;

    g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_SHOW_FIELD_KEY, &squark,
                                     GWY_APP_SHOW_FIELD, &sfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    g_return_if_fail(dfield && squark);

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    gwy_app_undo_qcheckpointv(data, 1, &squark);
    if (!sfield) {
        sfield = gwy_data_field_duplicate(dfield);
        gwy_container_set_object(data, squark, sfield);
        g_object_unref(sfield);
    }
    else {
        gwy_data_field_resample(sfield, xres, yres, GWY_INTERPOLATION_NONE);
        gwy_data_field_copy(dfield, sfield, FALSE);
    }

    d = gwy_data_field_get_data(sfield);
    zeroes = 0;
    max = 0;
    min = G_MAXDOUBLE;
    for (i = 0; i < xres*yres; i++) {
        d[i] = ABS(d[i]);
        if (G_UNLIKELY(d[i] > max))
            max = d[i];
        if (d[i] == 0.0)
            zeroes++;
        else if (G_UNLIKELY(d[i] < min))
            min = d[i];
    }
    if (min == max || zeroes == xres*yres)
        return;

    if (!zeroes) {
        for (i = 0; i < xres*yres; i++)
            d[i] = log(d[i]);
    }
    else {
        m0 = log(min) - log(max/min)/512.0;
        for (i = 0; i < xres*yres; i++)
            d[i] = d[i] ? log(d[i]) : m0;
    }

    gwy_data_field_data_changed(sfield);
    gwy_app_channel_log_add_proc(data, id, id);
}
Example #4
0
static void
create_images(const X3PFile *x3pfile, GwyContainer *container)
{
    gint id;

    for (id = 0; id < x3pfile->zres; id++) {
        GwyContainer *meta;
        guint n = x3pfile->xres*x3pfile->yres, k;
        GwyDataField *dfield, *mask;
        const gboolean *valid = x3pfile->valid + id*n;
        GQuark quark;
        gchar buf[40];

        dfield = gwy_data_field_new(x3pfile->xres,
                                    x3pfile->yres,
                                    x3pfile->xres*x3pfile->dx,
                                    x3pfile->yres*x3pfile->dy,
                                    FALSE);
        memcpy(dfield->data, x3pfile->values + id*n, n*sizeof(gdouble));
        for (k = 0; k < n; k++) {
            if (!valid[k])
                dfield->data[k] = NAN;
        }

        quark = gwy_app_get_data_key_for_id(id);
        gwy_container_set_object(container, quark, dfield);

        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m");
        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), "m");
        gwy_app_channel_title_fall_back(container, id);
        gwy_app_channel_check_nonsquare(container, id);

        if ((mask = gwy_app_channel_mask_of_nans(dfield, TRUE))) {
            quark = gwy_app_get_mask_key_for_id(id);
            gwy_container_set_object(container, quark, mask);
            g_object_unref(mask);
        }
        g_object_unref(dfield);

        if ((meta = get_meta(x3pfile))) {
            g_snprintf(buf, sizeof(buf), "/%u/meta", id);
            gwy_container_set_object_by_name(container, buf, meta);
            g_object_unref(meta);
        }
    }
}
Example #5
0
static void
laplace(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *mfield, *buffer;
    GQuark dquark;
    gdouble error, cor, maxer, lastfrac, frac, starter;
    gint i, id;
    gboolean cancelled = FALSE;

    g_return_if_fail(run & LAPLACE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_MASK_FIELD, &mfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    g_return_if_fail(dfield && dquark && mfield);

    maxer = gwy_data_field_get_rms(dfield)/1.0e4;
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, id),
                       _("Laplace interpolation..."));

    dfield = gwy_data_field_duplicate(dfield);
    buffer = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_correct_average(dfield, mfield);

    cor = 0.2;
    error = 0.0;
    lastfrac = 0.0;
    starter = 0.0;
    for (i = 0; i < 5000; i++) {
        gwy_data_field_correct_laplace_iteration(dfield, mfield, buffer,
                                                 cor, &error);
        if (error < maxer)
            break;
        if (!i)
            starter = error;

        frac = log(error/starter)/log(maxer/starter);
        if ((i/(gdouble)(5000)) > frac)
            frac = i/(gdouble)(5000);
        if (lastfrac > frac)
            frac = lastfrac;

        if (!gwy_app_wait_set_fraction(frac)) {
            cancelled = TRUE;
            break;
        }
        lastfrac = frac;
    }
    gwy_app_wait_finish();
    if (!cancelled) {
        gwy_app_undo_qcheckpointv(data, 1, &dquark);
        gwy_container_set_object(data, dquark, dfield);
        gwy_app_channel_log_add_proc(data, id, id);
    }
    g_object_unref(dfield);
    g_object_unref(buffer);
}
Example #6
0
static void
create_merged_field(GwyContainer *data, gint id1,
                    GwyDataField *dfield1, GwyDataField *dfield2,
                    gint px1, gint py1, gint px2, gint py2,
                    GwyMergeBoundaryType boundary, GwyMergeDirectionType dir,
                    gboolean create_mask, gboolean crop_to_rectangle)
{
    GwyDataField *result, *outsidemask = NULL;
    gint newxres, newyres, newid;

    gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres);
    gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres);
    gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2);

    result = gwy_data_field_new_alike(dfield1, FALSE);

    newxres = MAX(dfield1->xres + px1, dfield2->xres + px2);
    newyres = MAX(dfield1->yres + py1, dfield2->yres + py2);

    gwy_data_field_resample(result, newxres, newyres, GWY_INTERPOLATION_NONE);
    if (create_mask && !crop_to_rectangle) {
        outsidemask = gwy_data_field_new_alike(result, FALSE);
        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(outsidemask),
                                    NULL);
    }
    put_fields(dfield1, dfield2, result, outsidemask,
               boundary, px1, py1, px2, py2);

    if (crop_to_rectangle) {
        GwyOrientation orientation = GWY_ORIENTATION_HORIZONTAL;
        if (dir == GWY_MERGE_DIRECTION_UP || dir == GWY_MERGE_DIRECTION_DOWN)
            orientation = GWY_ORIENTATION_VERTICAL;

        crop_result(result, dfield1, dfield2, orientation, px1, py1, px2, py2);
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_set_data_field_title(data, newid, _("Merged images"));
    gwy_app_sync_data_items(data, data, id1, newid,
                            FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            0);

    if (outsidemask) {
        if (gwy_data_field_get_max(outsidemask) > 0.0) {
            GQuark quark = gwy_app_get_mask_key_for_id(newid);
            gwy_container_set_object(data, quark, outsidemask);
        }
        g_object_unref(outsidemask);
    }

    gwy_app_channel_log_add_proc(data, -1, newid);
    g_object_unref(result);
}
Example #7
0
static void
run_noninteractive(GEdgeArgs *args,
                   GwyContainer *data,
                   GwyDataField *dfield,
                   GQuark mquark)
{
    GwyDataField *mfield;

    gwy_app_undo_qcheckpointv(data, 1, &mquark);
    mfield = create_mask_field(dfield);
    gedge_process(dfield, mfield, args);
    gwy_container_set_object(data, mquark, mfield);
    g_object_unref(mfield);
}
Example #8
0
static void
presentation_attach_do(const GwyAppDataId *source,
                       const GwyAppDataId *target)
{
    GwyContainer *sourcedata, *targetdata;
    GwyDataField *dfield;
    GQuark quark;

    sourcedata = gwy_app_data_browser_get(source->datano);
    targetdata = gwy_app_data_browser_get(target->datano);
    quark = gwy_app_get_data_key_for_id(source->id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(sourcedata, quark));
    dfield = gwy_data_field_duplicate(dfield);
    quark = gwy_app_get_show_key_for_id(target->id);
    gwy_app_undo_qcheckpointv(targetdata, 1, &quark);
    gwy_container_set_object(targetdata, quark, dfield);
    g_object_unref(dfield);
}
Example #9
0
static void
run_noninteractive(FacetsArgs *args,
                   GwyContainer *data,
                   GwyContainer *fdata,
                   GwyDataField *dfield,
                   GwyDataField *mfield,
                   GQuark mquark)
{
    GwyDataField *dtheta, *dphi;

    gwy_app_undo_qcheckpointv(data, 1, &mquark);
    if (!mfield) {
        mfield = create_mask_field(dfield);
        gwy_container_set_object(data, mquark, mfield);
        g_object_unref(mfield);
    }

    dtheta = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/theta"));
    dphi = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/phi"));
    gwy_data_field_mark_facets(dtheta, dphi, args->theta0, args->phi0,
                               args->tolerance, mfield);
    gwy_data_field_data_changed(mfield);
}
Example #10
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;
}
Example #11
0
static void
dwt_anisotropy(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield, *mask;
    GQuark dquark, mquark;
    GwyDataLine *wtcoefs;
    DWTAnisotropyArgs args;
    gboolean ok;
    gint xsize, ysize, newsize, limit, id, i;

    g_return_if_fail(run & DWT_ANISOTROPY_RUN_MODES);

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     GWY_APP_MASK_FIELD_KEY, &mquark,
                                     GWY_APP_MASK_FIELD, &mask,
                                     0);
    g_return_if_fail(dfield && dquark);

    xsize = gwy_data_field_get_xres(dfield);
    ysize = gwy_data_field_get_yres(dfield);
    if (xsize != ysize) {
        dialog = gtk_message_dialog_new
            (gwy_app_find_window_for_channel(data, id),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), _("DWT Anisotropy"));
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    dwt_anisotropy_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = dwt_anisotropy_dialog(&args);
        dwt_anisotropy_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    for (newsize = 1, i = xsize-1; i; i >>= 1, newsize <<= 1)
        ;

    dfield = gwy_data_field_new_resampled(dfield, newsize, newsize,
                                          args.interp);
    gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield));

    gwy_app_undo_qcheckpoint(data, dquark, mquark, 0);
    if (!mask) {
        mask = gwy_data_field_new_alike(dfield, FALSE);
        gwy_container_set_object(data, mquark, mask);
        g_object_unref(mask);
    }
    gwy_data_field_resample(mask, newsize, newsize, GWY_INTERPOLATION_NONE);

    wtcoefs = gwy_data_line_new(10, 10, TRUE);
    wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet);

    /*justo for sure clamp the lowlimit again*/
    limit = pow(2, CLAMP(args.lowlimit, 1, 20));
    gwy_data_field_dwt_mark_anisotropy(dfield, mask, wtcoefs, args.ratio,
                                       limit);

    gwy_data_field_resample(mask, xsize, ysize, GWY_INTERPOLATION_ROUND);
    g_object_unref(wtcoefs);
    g_object_unref(dfield);
    gwy_data_field_data_changed(mask);
    gwy_app_channel_log_add_proc(data, id, id);
}
Example #12
0
static GwyContainer*
sensofar_load(const gchar *filename,
              G_GNUC_UNUSED GwyRunType mode,
              GError **error)
{
    SensofarDataDesc data_desc;
    GwyContainer *container = NULL;
    GwyDataField *dfield, *mfield;
    GwyGraphModel *gmodel;
    guchar *buffer = NULL;
    gsize size = 0;
    GError *err = NULL;
    const guchar *p;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }
    if (size < HEADER_SIZE + 12) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("File header is truncated"));
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    /* Date block */
    p = buffer;
    memcpy(&data_desc.date.str, p, DATE_SIZE);
    data_desc.date.str[DATE_SIZE-1] = '\0';
    p += DATE_SIZE;
    data_desc.date.t = gwy_get_guint32_le(&p);

    /* Comment block */
    memcpy(&data_desc.user_comment, p, COMMENT_SIZE);
    data_desc.user_comment[COMMENT_SIZE-1] = '\0';
    p += COMMENT_SIZE;

    /* Calbration block */
    data_desc.axes_config.yres = gwy_get_guint32_le(&p);
    data_desc.axes_config.xres = gwy_get_guint32_le(&p);
    data_desc.axes_config.N_tall = gwy_get_guint32_le(&p);
    data_desc.axes_config.dy_multip = gwy_get_gfloat_le(&p);
    data_desc.axes_config.mppx = gwy_get_gfloat_le(&p);
    data_desc.axes_config.mppy = gwy_get_gfloat_le(&p);
    data_desc.axes_config.x_0 = gwy_get_gfloat_le(&p);
    data_desc.axes_config.y_0 = gwy_get_gfloat_le(&p);
    data_desc.axes_config.mpp_tall = gwy_get_gfloat_le(&p);
    data_desc.axes_config.z_0 = gwy_get_gfloat_le(&p);

    /* Measurement block */
    data_desc.measure_config.type = gwy_get_guint32_le(&p);
    data_desc.measure_config.algorithm = gwy_get_guint32_le(&p);
    data_desc.measure_config.method = gwy_get_guint32_le(&p);
    data_desc.measure_config.objective = gwy_get_guint32_le(&p);
    data_desc.measure_config.area = gwy_get_guint32_le(&p);
    data_desc.measure_config.xres_area = gwy_get_guint32_le(&p);
    data_desc.measure_config.yres_area = gwy_get_guint32_le(&p);
    data_desc.measure_config.xres = gwy_get_guint32_le(&p);
    data_desc.measure_config.yres = gwy_get_guint32_le(&p);
    data_desc.measure_config.na = gwy_get_guint32_le(&p);
    data_desc.measure_config.incr_z = gwy_get_gdouble_le(&p);
    data_desc.measure_config.range = gwy_get_gfloat_le(&p);
    data_desc.measure_config.n_planes = gwy_get_guint32_le(&p);
    data_desc.measure_config.tpc_umbral_F = gwy_get_guint32_le(&p);
    data_desc.measure_config.restore = gwy_get_gboolean8(&p);
    data_desc.measure_config.num_layers = *(p++);
    data_desc.measure_config.version = *(p++);
    data_desc.measure_config.config_hardware = *(p++);
    data_desc.measure_config.stack_im_num = *(p++);
    data_desc.measure_config.reserved = *(p++);
    p += 2; // struct padding
    data_desc.measure_config.factor_delmacio = gwy_get_guint32_le(&p);

    gwy_debug("File date=<%s>, data type=%d, xres=%d, yres=%d, version=%d", 
              data_desc.date.str, 
              data_desc.measure_config.type, 
              data_desc.measure_config.xres, 
              data_desc.measure_config.yres,
              data_desc.measure_config.version);

    switch (data_desc.measure_config.type) {
        case MES_TOPO:
        case MES_IMATGE:
        dfield = sensofar_read_data_field(&data_desc, &mfield,
                                          &p, size - (p - buffer), error);
        if (!dfield) {
            gwy_file_abandon_contents(buffer, size, NULL);
            return NULL;
        }

        container = gwy_container_new();
        gwy_container_set_object(container, gwy_app_get_data_key_for_id(0),
                                 dfield);
        g_object_unref(dfield);
        if (mfield) {
            gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0),
                                     mfield);
            g_object_unref(mfield);
        }
        gwy_app_channel_title_fall_back(container, 0);
        break;

        case MES_PERFIL:
        case MES_GRUIX:
        gmodel = sensofar_read_profile(&data_desc,
                                       &p, size - (p - buffer), error);
        if (!gmodel) {
            gwy_file_abandon_contents(buffer, size, NULL);
            return NULL;
        }

        container = gwy_container_new();
        gwy_container_set_object(container, gwy_app_get_graph_key_for_id(0),
                                 gmodel);
        g_object_unref(gmodel);
        break;

        default:
        err_DATA_TYPE(error, data_desc.measure_config.type);
        break;
    }

    return container;
}
Example #13
0
static GwyContainer*
hitachi_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    GwyContainer *container = NULL, *meta;
    GdkPixbuf *pixbuf = NULL;
    GwyDataField *dfield = NULL;
    gchar *value, *imagename = NULL, *header = NULL;
    guchar *pixels;
    GHashTable *hash = NULL;
    GError *err = NULL;
    gdouble dx;
    gint pxres, pyres, hxres, hyres, rowstride, nchannels, i, j;
    gdouble *data;

    if (!(hash = hitachi_load_header(filename, &header, error)))
        return NULL;

    if (!require_keys(hash, error,
                      "ImageName", "DataSize", "PixelSize",
                      NULL))
        goto fail;
    value = g_hash_table_lookup(hash, "ImageName");

    if (!(imagename = hitachi_find_data_name(filename, value))) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("No corresponding data file was found for header file."));
        goto fail;
    }

    if (!(pixbuf = gdk_pixbuf_new_from_file(imagename, &err))) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO,
                    _("Cannot load image: %s"), err->message);
        g_clear_error(&err);
        goto fail;
    }

    /* We know the image dimensions so check them. */
    pxres = gdk_pixbuf_get_width(pixbuf);
    pyres = gdk_pixbuf_get_height(pixbuf);

    value = g_hash_table_lookup(hash, "DataSize");
    if (sscanf(value, "%ux%u", &hxres, &hyres) != 2) {
        err_INVALID(error, "DataSize");
        goto fail;
    }
    if (hxres != pxres || hyres != pyres) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Field DataSize %ux%u does not match image dimensions "
                      "%ux%u."),
                    hxres, hyres, pxres, pyres);
        goto fail;
    }
    if (err_DIMENSION(error, hxres) || err_DIMENSION(error, hyres))
        goto fail;

    dx = g_ascii_strtod(g_hash_table_lookup(hash, "PixelSize"), NULL);
    /* Use negated positive conditions to catch NaNs */
    if (!((dx = fabs(dx)) > 0)) {
        g_warning("Pixel size is 0.0, fixing to 1.0");
        dx = 1.0;
    }
    dx *= Nanometre;

    dfield = gwy_data_field_new(hxres, hyres, hxres*dx, hyres*dx, FALSE);
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m");

    data = gwy_data_field_get_data(dfield);
    pixels = gdk_pixbuf_get_pixels(pixbuf);
    rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    nchannels = gdk_pixbuf_get_n_channels(pixbuf);
    for (i = 0; i < hyres; i++) {
        gdouble *drow = data + i*hxres;
        guchar *p = pixels + i*rowstride;

        for (j = 0; j < hxres; j++, p += nchannels)
            drow[j] = (p[0] + p[1] + p[2])/765.0;
    }

    container = gwy_container_new();
    gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield);
    g_object_unref(dfield);

    if ((value = g_hash_table_lookup(hash, "SampleName"))
        && *value)
        gwy_container_set_string_by_name(container, "/0/data/title",
                                         g_strdup(value));
    else
        gwy_container_set_string_by_name(container, "/0/data/title",
                                         g_strdup("SEM"));

    meta = gwy_container_new();
    g_hash_table_foreach(hash, store_meta, meta);
    gwy_container_set_object_by_name(container, "/0/meta", meta);
    g_object_unref(meta);

    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    gwy_object_unref(pixbuf);
    g_free(imagename);
    g_free(header);
    g_hash_table_destroy(hash);

    return container;
}
Example #14
0
static void
facets_dialog(FacetsArgs *args,
              GwyContainer *data,
              GwyContainer *fdata,
              GwyDataField *dfield,
              GwyDataField *mfield,
              gint id,
              GQuark mquark)
{
    GtkWidget *dialog, *table, *hbox, *hbox2, *vbox, *label, *scale, *button;
    GtkWidget *spin;
    FacetsControls controls;
    enum {
        RESPONSE_RESET = 1,
        RESPONSE_PREVIEW = 2
    };
    gint response;
    GwyPixmapLayer *layer;
    GwyVectorLayer *vlayer;
    GwySelection *selection;
    gint row;

    memset(&controls, 0, sizeof(FacetsControls));
    controls.args = args;
    dialog = gtk_dialog_new_with_buttons(_("Mark Facets"),
                                         NULL,
                                         GTK_DIALOG_DESTROY_WITH_PARENT,
                                         _("_Mark"), RESPONSE_PREVIEW,
                                         _("_Reset"), RESPONSE_RESET,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    controls.dialog = dialog;

    /* Shallow-copy stuff to temporary container */
    controls.fdata = fdata;
    controls.mydata = gwy_container_new();
    gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield);
    gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_REAL_SQUARE,
                            0);

    hbox = gtk_hbox_new(FALSE, 2);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    controls.view = gwy_data_view_new(controls.mydata);
    layer = gwy_layer_basic_new();
    g_object_set(layer,
                 "data-key", "/0/data",
                 "gradient-key", "/0/base/palette",
                 "range-type-key", "/0/base/range-type",
                 "min-max-key", "/0/base",
                 NULL);
    gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);
    gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE);

    vlayer = g_object_new(g_type_from_name("GwyLayerPoint"), NULL);
    gwy_vector_layer_set_selection_key(vlayer, "/0/select/pointer");
    gwy_data_view_set_top_layer(GWY_DATA_VIEW(controls.view), vlayer);
    selection = gwy_vector_layer_ensure_selection(vlayer);
    g_signal_connect(selection, "changed",
                     G_CALLBACK(preview_selection_updated), &controls);

    gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4);

    vbox = gtk_vbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);

    hbox2 = gtk_hbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);

    /* Slope view */
    controls.fview = gwy_data_view_new(controls.fdata);
    gtk_box_pack_start(GTK_BOX(hbox2), controls.fview, FALSE, FALSE, 0);

    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.fview),
                                 layer);

    vlayer = g_object_new(g_type_from_name("GwyLayerPoint"), NULL);
    gwy_vector_layer_set_selection_key(vlayer, "/0/select/pointer");
    gwy_data_view_set_top_layer(GWY_DATA_VIEW(controls.fview),
                                GWY_VECTOR_LAYER(vlayer));
    selection = gwy_vector_layer_ensure_selection(vlayer);
    g_signal_connect(selection, "changed",
                     G_CALLBACK(facet_view_selection_updated), &controls);

    /* Info table */
    table = gtk_table_new(7, 2, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(hbox2), table, TRUE, TRUE, 4);
    row = 0;

    label = gwy_label_new_header(gwy_sgettext("noun|Normal"));
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.theta_label = add_angle_label(table, _("θ:"), &row);
    controls.phi_label = add_angle_label(table, _("φ:"), &row);

    button = gtk_button_new_with_mnemonic(_("_Find Maximum"));
    gtk_table_attach(GTK_TABLE(table), button,
                     0, 2, row, row+1, GTK_FILL, 0, 0, 0);
    g_signal_connect_swapped(button, "clicked",
                             G_CALLBACK(facet_view_reset_maximum), &controls);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    label = gwy_label_new_header(_("Mean Normal"));
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.mtheta_label = add_angle_label(table, _("θ:"), &row);
    controls.mphi_label = add_angle_label(table, _("φ:"), &row);
    gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

    label = gtk_label_new_with_mnemonic(_("Facet plane size:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.kernel_size = gtk_adjustment_new(args->kernel_size,
                                              0.0, MAX_PLANE_SIZE, 1.0, 1.0, 0);
    spin = gtk_spin_button_new(GTK_ADJUSTMENT(controls.kernel_size), 0.0, 0);
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin);
    gtk_table_attach(GTK_TABLE(table), spin,
                     0, 1, row, row+1, 0, 0, 0, 0);
    g_signal_connect(controls.kernel_size, "value-changed",
                     G_CALLBACK(facet_view_recompute), &controls);
    row++;

    table = gtk_table_new(9, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 4);
    row = 0;

    controls.tolerance = gtk_adjustment_new(args->tolerance*180.0/G_PI,
                                            0.0, 15.0, 0.01, 0.1, 0);
    scale = gwy_table_attach_hscale(table, row++, _("_Tolerance:"), _("deg"),
                                    controls.tolerance, 0);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(scale), 3);
    g_signal_connect(controls.tolerance, "value-changed",
                     G_CALLBACK(facets_tolerance_changed), &controls);

    controls.color_button = gwy_color_button_new();
    gwy_color_button_set_use_alpha(GWY_COLOR_BUTTON(controls.color_button),
                                   TRUE);
    load_mask_color(controls.color_button,
                    gwy_data_view_get_data(GWY_DATA_VIEW(controls.view)));
    gwy_table_attach_hscale(table, row++, _("_Mask color:"), NULL,
                            GTK_OBJECT(controls.color_button),
                            GWY_HSCALE_WIDGET_NO_EXPAND);
    g_signal_connect(controls.color_button, "clicked",
                     G_CALLBACK(mask_color_change_cb), &controls);

    if (!gwy_si_unit_equal(gwy_data_field_get_si_unit_xy(dfield),
                           gwy_data_field_get_si_unit_z(dfield))) {
        gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);
        label = gtk_label_new(_("Warning: Lateral and value units differ. "
                                "Angles are not physically meaningful."));
        gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), label,
                         0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
        row++;
    }

    facets_invalidate(&controls);
    gtk_widget_show_all(dialog);
    facet_view_select_angle(&controls, args->theta0, args->phi0);

    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            g_object_unref(controls.mydata);
            return;
            break;

            case GTK_RESPONSE_OK:
            break;

            case RESPONSE_RESET:
            args->tolerance = facets_defaults.tolerance;
            args->kernel_size = facets_defaults.kernel_size;
            facets_dialog_update_controls(&controls, args);
            break;

            case RESPONSE_PREVIEW:
            preview(&controls, args);
            update_average_angle(&controls, args);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    gtk_widget_destroy(dialog);

    if (controls.computed) {
        mfield = gwy_container_get_object_by_name(controls.mydata, "/0/mask");
        gwy_app_undo_qcheckpointv(data, 1, &mquark);
        gwy_container_set_object(data, mquark, mfield);
        g_object_unref(controls.mydata);
    }
    else {
        g_object_unref(controls.mydata);
        run_noninteractive(args, data, fdata, dfield, mfield, mquark);
    }
}
Example #15
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;
}
Example #16
0
static gboolean
read_aist_curve(const guchar **p, gsize *size, AistContext *context)
{
    AistCurve curve;
    GwyGraphModel *gmodel;
    GwyGraphCurveModel *gcmodel;
    GwySIUnit *xunit, *yunit;
    gboolean ok = FALSE;
    guint len, viewlen, i;
    const guchar *data, *viewdata;
    const gdouble *xdata, *ydata;
    gdouble *xdatacal, *ydatacal;
    gdouble *must_free = NULL;
    gdouble qx, qy;
    GQuark quark;

    gwy_clear(&curve, 1);

    gwy_debug("reading common");
    if (!read_aist_common(p, size, &curve.common))
        goto fail;

    gwy_debug("reading curve");
    if (!read_qt_int(p, size, &curve.res))
        goto fail;

    if (!read_qt_byte_array(p, size, &len, &data))
        goto fail;
    if (len != 2*curve.res*sizeof(gdouble))
        goto fail;

    /* Again something called view data.  Skip it.  The units follow. */
    if (!read_qt_byte_array(p, size, &viewlen, &viewdata))
        goto fail;

    if (!read_qt_string(p, size, &curve.xunits)
        || !read_qt_string(p, size, &curve.yunits))
        goto fail;

    xunit = extract_units(curve.xunits, &qx);
    yunit = extract_units(curve.yunits, &qy);

    /* The data are already stored as doubles in the correct order, so save
     * work if also the endianess matches. */
    if (G_BYTE_ORDER == G_BIG_ENDIAN) {
        must_free = g_new(gdouble, 2*curve.res);
        xdata = must_free;
        ydata = xdata + curve.res;
        gwy_memcpy_byte_swap(data, (guchar*)must_free, 8, 2*curve.res, 7);
    }
    else if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
        xdata = (const gdouble *)data;
        ydata = xdata + curve.res;
    }

    xdatacal = g_new(gdouble, curve.res);
    ydatacal = g_new(gdouble, curve.res);
    for (i = 0; i < curve.res; i++) {
        xdatacal[i] = xdata[i]*qx;
        ydatacal[i] = ydata[i]*qy;
    }

    gcmodel = gwy_graph_curve_model_new();
    gwy_graph_curve_model_set_data(gcmodel, xdatacal, ydatacal, curve.res);
    g_object_set(gcmodel,
                 "mode", GWY_GRAPH_CURVE_LINE,
                 "description", curve.common.description,
                 NULL);
    g_free(must_free);
    g_free(xdatacal);
    g_free(ydatacal);

    gmodel = gwy_graph_model_new();
    gwy_graph_model_add_curve(gmodel, gcmodel);
    g_object_unref(gcmodel);
    g_object_set(gmodel,
                 "title", curve.common.name,
                 "si-unit-x", xunit,
                 "si-unit-y", yunit,
                 NULL);
    g_object_unref(xunit);
    g_object_unref(yunit);

    quark = gwy_app_get_graph_key_for_id(context->graph_id+1);
    gwy_container_set_object(context->container, quark, gmodel);
    g_object_unref(gmodel);

    context->graph_id++;

    ok = TRUE;

fail:
    free_aist_common(&curve.common);
    g_free(curve.xunits);
    g_free(curve.yunits);
    return ok;
}
Example #17
0
static GwyContainer*
shimadzu_load(const gchar *filename,
              G_GNUC_UNUSED GwyRunType mode,
              GError **error)
{
    GwyContainer *meta, *container = NULL;
    GwyDataField *dfield = NULL;
    GError *err = NULL;
    gchar *buffer = NULL;
    GHashTable *hash;
    gchar *head;
    gsize size = 0;
    gboolean ok;
    gint text_data_start;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }
    if (size < HEADER_SIZE + 2) {
        err_TOO_SHORT(error);
        return NULL;
    }
    if (memcmp(buffer, MAGIC, MAGIC_SIZE) != 0
        && !(memcmp(buffer, MAGIC_ASCII, MAGIC_ASCII_SIZE) == 0
             && (memcmp(buffer + MAGIC_ASCII_SIZE+1,
                        MAGIC, MAGIC_SIZE) == 0
                 || memcmp(buffer + MAGIC_ASCII_SIZE+2,
                           MAGIC, MAGIC_SIZE) == 0))) {
        err_FILE_TYPE(error, "Shimadzu");
        g_free(buffer);
        return NULL;
    }

    head = g_memdup(buffer, HEADER_SIZE+1);
    head[HEADER_SIZE] = '\0';

    /* text_data_start is set to nonzero if data are text */
    hash = read_hash(head, &text_data_start, error);
    ok = !!hash;
    if (ok) {
        if (text_data_start)
            dfield = read_text_data(buffer, text_data_start, hash, error);
        else
            dfield = read_binary_data(buffer, size, hash, error);

        ok = !!dfield;
    }

    if (ok) {
        GQuark quark;
        const gchar *title;

        container = gwy_container_new();
        quark = gwy_app_get_data_key_for_id(0);
        gwy_container_set_object(container, quark, dfield);
        g_object_unref(dfield);

        meta = shimadzu_get_metadata(hash);
        gwy_container_set_object_by_name(container, "/0/meta", meta);
        g_object_unref(meta);

        title = g_hash_table_lookup(hash, "Channel");
        if (title && *title)
            gwy_container_set_string_by_name(container, "/0/data/title",
                                             g_strdup(title));
        else
            gwy_app_channel_title_fall_back(container, 0);

        gwy_file_channel_import_log_add(container, 0, NULL, filename);
    }

    g_free(head);
    g_free(buffer);
    g_hash_table_destroy(hash);

    return container;
}
Example #18
0
static void
create_profiles(const X3PFile *x3pfile,
                GwyContainer *container)
{
    GwyGraphModel *gmodel;
    GwySIUnit *siunitx, *siunity;
    GArray *validx, *validy;
    GQuark quark;
    gint id;

    gmodel = gwy_graph_model_new();
    siunitx = gwy_si_unit_new("m");
    siunity = gwy_si_unit_new("m");
    g_object_set(gmodel,
                 "title", "Profiles",
                 "si-unit-x", siunitx,
                 "si-unit-y", siunity,
                 NULL);
    g_object_unref(siunity);
    g_object_unref(siunitx);

    validx = g_array_new(FALSE, FALSE, sizeof(gdouble));
    validy = g_array_new(FALSE, FALSE, sizeof(gdouble));
    for (id = 0; id < x3pfile->zres; id++) {
        guint n = x3pfile->xres;
        GwyGraphCurveModel *gcmodel;
        gchar *title;
        guint j;

        g_array_set_size(validx, 0);
        g_array_set_size(validy, 0);
        for (j = 0; j < x3pfile->xres; j++) {
            gdouble v = x3pfile->values[id*n + j];

            if (gwy_isnan(v) || gwy_isinf(v) || !x3pfile->valid[id*n + j])
                continue;

            g_array_append_val(validy, v);
            v = j*x3pfile->dx;
            g_array_append_val(validx, v);
        }

        if (!validx->len)
            continue;

        gcmodel = gwy_graph_curve_model_new();
        title = g_strdup_printf("Profile %u", id+1);
        g_object_set(gcmodel,
                     "mode", GWY_GRAPH_CURVE_LINE,
                     "description", title,
                     "color", gwy_graph_get_preset_color(id),
                     NULL);
        g_free(title);
        gwy_graph_curve_model_set_data(gcmodel,
                                       (gdouble*)validx->data,
                                       (gdouble*)validy->data,
                                       validx->len);
        gwy_graph_model_add_curve(gmodel, gcmodel);
        g_object_unref(gcmodel);
    }

    g_array_free(validy, TRUE);
    g_array_free(validx, TRUE);

    quark = gwy_app_get_graph_key_for_id(0);
    gwy_container_set_object(container, quark, gmodel);
    g_object_unref(gmodel);
}
Example #19
0
/**
 * proc_plugin_proxy_run:
 * @data: A data container.
 * @run: Run mode.
 * @name: Plug-in name (i.e. data processing function) to run.
 *
 * The plug-in proxy itself, runs plug-in @name on @data.
 *
 * Returns: Whether it succeeded running the plug-in.
 **/
static void
proc_plugin_proxy_run(GwyContainer *data,
                      GwyRunType run,
                      const gchar *name)
{
    ProcPluginInfo *info;
    GwyContainer *newdata;
    gchar *filename, *buffer = NULL;
    GError *err = NULL;
    gint exit_status, id, newid;
    gsize size = 0;
    FILE *fh;
    gchar *args[] = { NULL, "run", NULL, NULL, NULL };
    GQuark dquark, mquark, squark;
    gboolean ok;

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_MASK_FIELD_KEY, &mquark,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);

    gwy_debug("called as %s with run mode %d", name, run);
    if (!(info = proc_find_plugin(name, run)))
        return;

    fh = text_dump_export(data, dquark, mquark, &filename, NULL);
    g_return_if_fail(fh);
    args[0] = info->file;
    args[2] = g_strdup(gwy_enum_to_string(run, run_mode_names, -1));
    args[3] = decode_glib_encoded_filename(filename);
    gwy_debug("%s %s %s %s", args[0], args[1], args[2], args[3]);
    ok = g_spawn_sync(NULL, args, NULL, 0, NULL, NULL,
                      NULL, NULL, &exit_status, &err);
    if (!err)
        ok &= g_file_get_contents(filename, &buffer, &size, &err);
    g_unlink(filename);
    fclose(fh);
    gwy_debug("ok = %d, exit_status = %d, err = %p", ok, exit_status, err);
    ok &= !exit_status;
    if (ok && (newdata = text_dump_import(buffer, size, NULL))) {
        GwyDataField *dfield;

        /* Merge data */
        if (gwy_container_gis_object_by_name(newdata, "/0/data", &dfield))
            g_object_ref(dfield);
        else {
            dfield = gwy_container_get_object(data, dquark);
            dfield = gwy_data_field_duplicate(dfield);
        }
        newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);

        /* Merge mask */
        if (gwy_container_gis_object_by_name(newdata, "/0/mask", &dfield))
            g_object_ref(dfield);
        else if (gwy_container_gis_object(data, mquark, &dfield))
            dfield = gwy_data_field_duplicate(dfield);
        else
            dfield = NULL;

        if (dfield) {
            mquark = gwy_app_get_mask_key_for_id(newid);
            gwy_container_set_object(data, mquark, dfield);
            g_object_unref(dfield);
        }

        /* Merge presentation */
        if (gwy_container_gis_object_by_name(newdata, "/0/show", &dfield)) {
            squark = gwy_app_get_show_key_for_id(newid);
            gwy_container_set_object(data, squark, dfield);
        }

        /* Merge stuff.  XXX: This is brutal and incomplete. */
        gwy_app_sync_data_items(data, data, id, newid, FALSE,
                                GWY_DATA_ITEM_GRADIENT,
                                GWY_DATA_ITEM_RANGE_TYPE,
                                GWY_DATA_ITEM_MASK_COLOR,
                                GWY_DATA_ITEM_REAL_SQUARE,
                                0);
        gwy_app_sync_data_items(newdata, data, 0, newid, FALSE,
                                GWY_DATA_ITEM_GRADIENT,
                                GWY_DATA_ITEM_RANGE_TYPE,
                                0);

        g_object_unref(newdata);
    }
    else {
        g_warning("Cannot run plug-in %s: %s",
                  info->file,
                  err ? err->message : "it returned garbage.");
    }
    g_free(args[3]);
    g_free(args[2]);
    g_clear_error(&err);
    g_free(buffer);
    g_free(filename);
}
Example #20
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;
}
Example #21
0
static GwyContainer*
plt_load(const gchar *filename,
         G_GNUC_UNUSED GwyRunType mode,
         GError **error)
{
    GwyContainer *container = NULL;
    GwyDataField *dfield = NULL;
    GwyTextHeaderParser parser;
    GwySIUnit *xunit, *yunit, *zunit;
    gchar *p, *value, *buffer = NULL;
    GHashTable *hash = NULL;
    gsize size;
    GError *err = NULL;
    G_GNUC_UNUSED gdouble xreal, yreal, zreal;
    gint i, xres, yres;
    gdouble *data;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        goto fail;
    }

    if (strncmp(buffer, MAGIC1, MIN(size, sizeof(MAGIC1)-1))) {
        err_FILE_TYPE(error, "Nanosurf PLT");
        goto fail;
    }

    /* Find the first line not starting with '#' */
    for (p = buffer; (p - buffer) + 1 < size; p++) {
        if ((p[0] == '\n' || p[0] == '\r')
            && (p[1] != '\n' && p[1] != '#')) {
            break;
        }
    }
    *p = '\0';
    p++;

    gwy_clear(&parser, 1);
    parser.line_prefix = "#";
    parser.key_value_separator = ":";
    hash = gwy_text_header_parse(buffer, &parser, NULL, NULL);
    if (!require_keys(hash, error,
                      "Channel", "Lines", "Points",
                      "XRange", "YRange", "ZRange",
                      NULL))
        goto fail;

    xres = atoi(g_hash_table_lookup(hash, "Points"));
    yres = atoi(g_hash_table_lookup(hash, "Lines"));
    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        goto fail;

    value = g_hash_table_lookup(hash, "XRange");
    xreal = g_ascii_strtod(value, &value);
    xunit = gwy_si_unit_new(value);

    value = g_hash_table_lookup(hash, "YRange");
    yreal = g_ascii_strtod(value, &value);
    yunit = gwy_si_unit_new(value);

    value = g_hash_table_lookup(hash, "ZRange");
    zreal = g_ascii_strtod(value, &value);
    zunit = gwy_si_unit_new(value);

    /* Use negated positive conditions to catch NaNs */
    if (!((xreal = fabs(xreal)) > 0)) {
        g_warning("Real x size is 0.0, fixing to 1.0");
        xreal = 1.0;
    }
    if (!((yreal = fabs(yreal)) > 0)) {
        g_warning("Real y size is 0.0, fixing to 1.0");
        yreal = 1.0;
    }

    if (!gwy_si_unit_equal(xunit, yunit))
        g_warning("X and Y units differ, using X");

    dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE);
    gwy_data_field_set_si_unit_xy(dfield, xunit);
    gwy_data_field_set_si_unit_z(dfield, zunit);
    g_object_unref(xunit);
    g_object_unref(yunit);
    g_object_unref(zunit);

    data = gwy_data_field_get_data(dfield);
    value = p;
    for (i = 0; i < xres*yres; i++) {
        data[i] = g_ascii_strtod(value, &p);
        value = p;
    }

    container = gwy_container_new();
    gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield);
    g_object_unref(dfield);

    if ((value = g_hash_table_lookup(hash, "Channel")))
        gwy_container_set_string_by_name(container, "/0/data/title",
                                         g_strdup(value));
    else
        gwy_app_channel_title_fall_back(container, 0);

    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    g_free(buffer);
    g_hash_table_destroy(hash);

    return container;
}
Example #22
0
static GwyContainer*
omicron_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    OmicronFile ofile;
    GwyContainer *container = NULL, *meta;
    gchar *text = NULL;
    GError *err = NULL;
    GwyDataField *dfield = NULL;
    GwySpectra *spectra = NULL;
    gchar key[32];
    guint i;

    /* @text must not be destroyed while @ofile is still in used because
     * all strings are only references there */
    if (!g_file_get_contents(filename, &text, NULL, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }

    gwy_clear(&ofile, 1);
    ofile.filename = filename;
    if (!omicron_read_header(text, &ofile, error))
        goto fail;

    if (!ofile.topo_channels || !ofile.topo_channels->len) {
        err_NO_DATA(error);
        goto fail;
    }

    container = gwy_container_new();

    /* First Load the Topographic Data */
    for (i = 0; i < ofile.topo_channels->len; i++) {
        OmicronTopoChannel *channel;

        channel = g_ptr_array_index(ofile.topo_channels, i);
        dfield = omicron_read_data(&ofile, channel, error);
        if (!dfield) {
            gwy_object_unref(container);
            goto fail;
        }

        g_snprintf(key, sizeof(key), "/%u/data", i);
        gwy_container_set_object_by_name(container, key, dfield);
        g_object_unref(dfield);

        if (channel->name) {
            gchar *s;

            g_snprintf(key, sizeof(key), "/%u/data/title", i);
            if (channel->scandir == SCAN_FORWARD)
                s = g_strdup_printf("%s (Forward)", channel->name);
            else if (channel->scandir == SCAN_BACKWARD)
                s = g_strdup_printf("%s (Backward)", channel->name);
            else
                s = g_strdup(channel->name);
            gwy_container_set_string_by_name(container, key, s);
        }

        if ((meta = omicron_make_meta(&ofile))) {
            g_snprintf(key, sizeof(key), "/%u/meta", i);
            gwy_container_set_object_by_name(container, key, meta);
            g_object_unref(meta);
        }
    }

    /* Then load the spectroscopy data. */
    /*
     * There are two types of spectroscopy file:
     *
     * a) Single Point Spectroscopy Files
     * Single point which is stored by SCALA as an ascii file.  Any number of
     * single point spectrums may be aquired, but the number is normally
     * quite small. These files are identified by their filename *.cs[0..3]
     *
     * b) Binary Spectroscopy Files
     * When large numbers of spectra are aquired on a regular grid they are
     * stored in BE binary. These data are aquired during the scan, and so
     * can be aquired during the forward scan or the backward scan.
     *
     * Forwards scan files can be indentified from their filename *.sf[0..3]
     * Backward scan files can be indentified from their filename *.sb[0..3]
     */
    if (ofile.spectro_channels) {
        for (i = 0; i < ofile.spectro_channels->len; i++) {
            OmicronSpectroChannel *channel;

            channel = g_ptr_array_index(ofile.spectro_channels, i);
            if (omicron_has_extension(channel->filename, "cs")) {
                gchar *t;
                GQuark quark;

                spectra = omicron_read_cs_data(&ofile, channel, error);
                if (!spectra) {
                    gwy_object_unref(container);
                    goto fail;
                }

                if (!gwy_spectra_get_n_spectra(spectra)) {
                    gwy_debug("Spectra %u is empty, ignoring", i);
                    g_object_unref(spectra);
                    continue;
                }

                /* FIXME */
                t = g_strconcat(channel->chan, "-", channel->param, NULL);
                gwy_spectra_set_title(spectra, t);
                g_free(t);
                quark = gwy_app_get_spectra_key_for_id(i);
                gwy_container_set_object(container, quark, spectra);
                g_object_unref(spectra);
            }
            else if (omicron_has_extension(channel->filename, "sf")
                     || omicron_has_extension(channel->filename, "sb")) {
                /* FIXME */
            }
            else {
                g_warning("Cannot determine spectra type of %s",
                          channel->filename);
            }
        }
    }

fail:
    omicron_file_free(&ofile);
    g_free(text);

    return container;
}
static GwyContainer*
rhk_sm4_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    RHKFile rhkfile;
    RHKObject *obj, o;
    GwyContainer *meta, *container = NULL;
    guchar *buffer = NULL;
    gsize size = 0;
    GError *err = NULL;
    const guchar *p;
    GString *key = NULL;
    guint i, imageid = 0, graphid = 0;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }

    gwy_clear(&rhkfile, 1);
    if (size < HEADER_SIZE) {
        err_TOO_SHORT(error);
        goto fail;
    }

    /* File header */
    p = buffer + MAGIC_OFFSET + MAGIC_TOTAL_SIZE;
    rhkfile.page_count = gwy_get_guint32_le(&p);
    rhkfile.object_count = gwy_get_guint32_le(&p);
    rhkfile.object_field_size = gwy_get_guint32_le(&p);
    gwy_debug("page_count: %u, object_count: %u, object_field_size: %u",
              rhkfile.page_count, rhkfile.object_count,
              rhkfile.object_field_size);
    if (rhkfile.object_field_size != OBJECT_SIZE)
        g_warning("Object field size %u differs from %u",
                  rhkfile.object_field_size, OBJECT_SIZE);
    rhkfile.reserved1 = gwy_get_guint32_le(&p);
    rhkfile.reserved2 = gwy_get_guint32_le(&p);

    /* Header objects */
    if (!(rhkfile.objects = rhk_sm4_read_objects(buffer, p, size,
                                                 rhkfile.object_count,
                                                 RHK_OBJECT_FILE_HEADER,
                                                 error)))
        goto fail;

    /* Find page index header */
    if (!(obj = rhk_sm4_find_object(rhkfile.objects, rhkfile.object_count,
                                    RHK_OBJECT_PAGE_INDEX_HEADER,
                                    RHK_OBJECT_FILE_HEADER, error))
        || !rhk_sm4_read_page_index_header(&rhkfile.page_index_header,
                                           obj, buffer, size, error))
        goto fail;

    /* There, find the page index array.  That's a single object in the object
     * list but it contains a page_count-long sequence of page indices. */
    rhkfile.page_indices = g_new0(RHKPageIndex,
                                  rhkfile.page_index_header.page_count);
    if (!(obj = rhk_sm4_find_object(rhkfile.page_index_header.objects,
                                    rhkfile.page_index_header.object_count,
                                    RHK_OBJECT_PAGE_INDEX_ARRAY,
                                    RHK_OBJECT_PAGE_INDEX_HEADER, error)))
        goto fail;

    o = *obj;
    for (i = 0; i < rhkfile.page_index_header.page_count; i++) {
        if (!rhk_sm4_read_page_index(rhkfile.page_indices + i, &o,
                                     buffer, size, error))
            goto fail;

        /* Carefully move to the next page index */
        o.offset += o.size + OBJECT_SIZE*rhkfile.page_indices[i].object_count;
    }

    container = gwy_container_new();
    key = g_string_new(NULL);

    /* Read pages */
    for (i = 0; i < rhkfile.page_index_header.page_count; i++) {
        RHKPageIndex *pi = rhkfile.page_indices + i;
        RHKPage *page = &pi->page;

        /* Page must contain header */
        if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count,
                                        RHK_OBJECT_PAGE_HEADER,
                                        RHK_OBJECT_PAGE_INDEX, error))
            || !rhk_sm4_read_page_header(page, obj, buffer, size, error))
            goto fail;

        /* Page must contain data */
        if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count,
                                        RHK_OBJECT_PAGE_DATA,
                                        RHK_OBJECT_PAGE_INDEX, error))
            || !rhk_sm4_read_page_data(page, obj, buffer, error))
            goto fail;

        /* Page may contain strings */
        if (!(obj = rhk_sm4_find_object(page->objects, page->object_count,
                                        RHK_OBJECT_STRING_DATA,
                                        RHK_OBJECT_PAGE_HEADER, NULL))
            || !rhk_sm4_read_string_data(page, obj, pi->page.string_count,
                                         buffer)) {
            g_warning("Failed to read string data in page %u", i);
        }

        /* Read the data */
        if (pi->data_type == RHK_DATA_IMAGE) {
            GwyDataField *dfield = rhk_sm4_page_to_data_field(page);
            GQuark quark = gwy_app_get_data_key_for_id(imageid);
            const gchar *scandir, *name;
            gchar *title;

            gwy_container_set_object(container, quark, dfield);
            g_object_unref(dfield);

            if ((name = page->strings[RHK_STRING_LABEL])) {
                scandir = gwy_enum_to_string(page->scan_dir, scan_directions,
                                             G_N_ELEMENTS(scan_directions));
                g_string_assign(key, g_quark_to_string(quark));
                g_string_append(key, "/title");
                if (scandir && *scandir)
                    title = g_strdup_printf("%s [%s]", name, scandir);
                else
                    title = g_strdup(name);
                gwy_container_set_string_by_name(container, key->str, title);
            }

            meta = rhk_sm4_get_metadata(pi, page);
            g_string_printf(key, "/%u/meta", imageid);
            gwy_container_set_object_by_name(container, key->str, meta);
            g_object_unref(meta);

            imageid++;
        }
        else if (pi->data_type == RHK_DATA_LINE) {
            GwyGraphModel *gmodel;
            RHKSpecDriftHeader drift_header;
            RHKSpecInfo spec_info;
            G_GNUC_UNUSED gboolean have_header = FALSE, have_info = FALSE;

            gwy_debug("page_type %u", page->page_type);
            gwy_debug("line_type %u", page->line_type);
            gwy_debug("page_sizes %u %u", page->x_size, page->y_size);
            /* Page may contain drift header */
            if ((obj = rhk_sm4_find_object(page->objects, page->object_count,
                                           RHK_OBJECT_SPEC_DRIFT_HEADER,
                                           RHK_OBJECT_PAGE_HEADER, NULL))
                && rhk_sm4_read_drift_header(&drift_header, obj, buffer)) {
                gwy_debug("drift_header OK");
                have_header = TRUE;
            }
            if ((obj = rhk_sm4_find_object(page->objects, page->object_count,
                                           RHK_OBJECT_SPEC_DRIFT_DATA,
                                           RHK_OBJECT_PAGE_HEADER, NULL))
                && rhk_sm4_read_spec_info(&spec_info, obj, buffer)) {
                gwy_debug("spec_info OK");
                have_info = TRUE;
            }
            /* FIXME: RHK_STRING_PLL_PRO_STATUS may contain interesting
             * metadata.  But we have not place where to put it. */

            if ((gmodel = rhk_sm4_page_to_graph_model(page))) {
                graphid++;
                gwy_container_set_object(container,
                                         gwy_app_get_graph_key_for_id(graphid),
                                         gmodel);
                g_object_unref(gmodel);
            }
        }
    }

    if (!imageid && !graphid)
        err_NO_DATA(error);

fail:
    gwy_file_abandon_contents(buffer, size, NULL);
    rhk_sm4_free(&rhkfile);
    if (!imageid && !graphid) {
        gwy_object_unref(container);
    }
    if (key)
        g_string_free(key, TRUE);

    return container;
}
Example #24
0
static void
rotate(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3];
    GQuark quark;
    gint oldid, newid;
    RotateArgs args;
    gboolean ok;

    g_return_if_fail(run & ROTATE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfields[0]);

    rotate_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = rotate_dialog(&args, data);
        rotate_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfields[0] = gwy_data_field_duplicate(dfields[0]);
    rotate_datafield(dfields[0], &args);
    if (dfields[1]) {
        GwyInterpolationType interp = args.interp;

        dfields[1] = gwy_data_field_duplicate(dfields[1]);
        args.interp = GWY_INTERPOLATION_ROUND;
        rotate_datafield(dfields[1], &args);
        args.interp = interp;
    }
    if (dfields[2]) {
        dfields[2] = gwy_data_field_duplicate(dfields[2]);
        rotate_datafield(dfields[2], &args);
    }

    newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE);
    g_object_unref(dfields[0]);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    if (dfields[1]) {
        quark = gwy_app_get_mask_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[1]);
        g_object_unref(dfields[1]);
    }
    if (dfields[2]) {
        quark = gwy_app_get_show_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[2]);
        g_object_unref(dfields[2]);
    }

    gwy_app_set_data_field_title(data, newid, _("Rotated Data"));
    gwy_app_channel_log_add_proc(data, oldid, newid);
}
Example #25
0
static void
gfilter_dialog(GFilterArgs *args,
              GwyContainer *data,
              GwyDataField *dfield,
              GwyDataField *mfield,
              gint id,
              GQuark mquark)
{
    GtkWidget *dialog, *table, *vbox, *hbox, *scwin, *hbox2, *label;
    GtkTreeView *treeview;
    GtkTreeSelection *selection;
    GFilterControls controls;
    gint response, row, i;
    GwySIUnit *siunit;
    GwyPixmapLayer *layer;

    controls.args = args;
    controls.mask = mfield;
    controls.in_init = TRUE;
    controls.computed = FALSE;

    siunit = gwy_si_unit_new(NULL);
    for (i = 0; i < NQUANTITIES; i++) {
        controls.vf[i]
            = gwy_si_unit_get_format_with_digits(siunit,
                                                 GWY_SI_UNIT_FORMAT_VFMARKUP,
                                                 1.0, 4, NULL);
    }
    g_object_unref(siunit);

    dialog = gtk_dialog_new_with_buttons(_("Filter Grains"),
                                         NULL, 0, NULL);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),
                                 gwy_stock_like_button_new(_("_Update"),
                                                           GTK_STOCK_EXECUTE),
                                 RESPONSE_PREVIEW);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_OK, GTK_RESPONSE_OK);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), RESPONSE_PREVIEW,
                                      !args->update);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);
    controls.dialog = dialog;

    hbox = gtk_hbox_new(FALSE, 2);

    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 4);

    vbox = gtk_vbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.mydata = gwy_container_new();
    gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield);
    mfield = gwy_data_field_duplicate(mfield);
    gwy_container_set_object_by_name(controls.mydata, "/0/mask", mfield);
    g_object_unref(mfield);
    gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_REAL_SQUARE,
                            0);
    controls.view = gwy_data_view_new(controls.mydata);
    layer = gwy_layer_basic_new();
    g_object_set(layer,
                 "data-key", "/0/data",
                 "gradient-key", "/0/base/palette",
                 "range-type-key", "/0/base/range-type",
                 "min-max-key", "/0/base",
                 NULL);
    gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);
    layer = gwy_layer_mask_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/mask");
    gwy_layer_mask_set_color_key(GWY_LAYER_MASK(layer), "/0/mask");
    gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls.view), layer);
    gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE);

    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    controls.update = gtk_check_button_new_with_mnemonic(_("I_nstant updates"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.update),
                                 args->update);
    gtk_box_pack_start(GTK_BOX(vbox), controls.update, FALSE, FALSE, 0);
    g_signal_connect_swapped(controls.update, "toggled",
                             G_CALLBACK(update_changed), &controls);

    hbox2 = gtk_hbox_new(FALSE, 6);
    gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);

    label = gtk_label_new_with_mnemonic(_("_Mask color:"));
    gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);

    controls.color_button = gwy_color_button_new();
    gwy_color_button_set_use_alpha(GWY_COLOR_BUTTON(controls.color_button),
                                   TRUE);
    load_mask_color(controls.color_button,
                    gwy_data_view_get_data(GWY_DATA_VIEW(controls.view)));
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.color_button);
    gtk_box_pack_start(GTK_BOX(hbox2), controls.color_button, FALSE, FALSE, 0);
    g_signal_connect(controls.color_button, "clicked",
                     G_CALLBACK(mask_color_changed), &controls);

    table = gtk_table_new(10, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 4);
    controls.table = table;
    row = 0;

    scwin = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin),
                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_table_attach(GTK_TABLE(table), scwin, 0, 4, row, row+1,
                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);

    controls.values = gwy_grain_value_tree_view_new(FALSE,
                                                    "name", "symbol_markup",
                                                    NULL);
    treeview = GTK_TREE_VIEW(controls.values);
    gtk_widget_set_size_request(scwin, -1, 120);
    gtk_tree_view_set_headers_visible(treeview, FALSE);
    selection = gtk_tree_view_get_selection(treeview);
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
    gwy_grain_value_tree_view_set_same_units(treeview, args->units_equal);
    gwy_grain_value_tree_view_set_expanded_groups(treeview, args->expanded);
    gtk_container_add(GTK_CONTAINER(scwin), controls.values);
    row++;

    hbox2 = gtk_hbox_new(FALSE, 0);
    for (i = 0; i < NQUANTITIES; i++) {
        gchar buf[2];
        buf[0] = 'A' + i;
        buf[1] = '\0';
        controls.set_as[i] = gtk_button_new_with_label(buf);
        gtk_box_pack_start(GTK_BOX(hbox2), controls.set_as[i], FALSE, FALSE, 0);
        g_object_set_data(G_OBJECT(controls.set_as[i]),
                          "id", GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.set_as[i], "clicked",
                                 G_CALLBACK(set_as_clicked), &controls);
    }
    gwy_table_attach_hscale(table, row++,
                            _("Set selected as:"), NULL,
                            GTK_OBJECT(hbox2), GWY_HSCALE_WIDGET_NO_EXPAND);

    controls.logical_op
        = gwy_enum_combo_box_newl(G_CALLBACK(logical_op_changed), &controls,
                                  args->logical,
                                  "A", GRAIN_LOGICAL_A,
                                  "A ∧ B", GRAIN_LOGICAL_A_AND_B,
                                  "A ∨ B", GRAIN_LOGICAL_A_OR_B,
                                  "A ∧ B ∧ C", GRAIN_LOGICAL_A_AND_B_AND_C,
                                  "A ∨ B ∨ C", GRAIN_LOGICAL_A_OR_B_OR_C,
                                  "(A ∧ B) ∨ C", GRAIN_LOGICAL_A_AND_B_OR_C,
                                  "(A ∨ B) ∧ C", GRAIN_LOGICAL_A_OR_B_AND_C,
                                  NULL);
    gwy_table_attach_hscale(table, row++,
                            _("Keep grains satisfying:"), NULL,
                            GTK_OBJECT(controls.logical_op),
                            GWY_HSCALE_WIDGET);

    for (i = 0; i < NQUANTITIES; i++) {
        gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

        controls.header[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.header[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.header[i],
                         0, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;

        /* The values are set properly later. */
        controls.lower_label[i] = gtk_label_new(_("Lower threshold:"));
        gtk_misc_set_alignment(GTK_MISC(controls.lower_label[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.lower_label[i],
                         0, 1, row, row+1, GTK_FILL, 0, 0, 0);

        controls.lower[i] = gtk_adjustment_new(0.0, 0.0, 0.0,
                                               1.0, 10.0, 0.0);
        g_object_set_data(G_OBJECT(controls.lower[i]), "id",
                          GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.lower[i], "value-changed",
                                 G_CALLBACK(threshold_changed), &controls);
        controls.lower_scale[i]
            = gtk_hscale_new(GTK_ADJUSTMENT(controls.lower[i]));
        gtk_scale_set_draw_value(GTK_SCALE(controls.lower_scale[i]), FALSE);
        gtk_widget_set_size_request(controls.lower_scale[i],
                                    GWY_HSCALE_WIDTH, -1);
        gtk_table_attach(GTK_TABLE(table), controls.lower_scale[i],
                         1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);

        controls.lower_entry[i] = gtk_entry_new();
        gtk_entry_set_width_chars(GTK_ENTRY(controls.lower_entry[i]), 8);
        gtk_table_attach(GTK_TABLE(table), controls.lower_entry[i],
                         2, 3, row, row+1, GTK_FILL, 0, 0, 0);
        gwy_widget_set_activate_on_unfocus(controls.lower_entry[i], TRUE);
        g_object_set_data(G_OBJECT(controls.lower_entry[i]), "id",
                          GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.lower_entry[i], "activate",
                                 G_CALLBACK(threshold_activated), &controls);

        controls.lower_units[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.lower_units[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.lower_units[i],
                         3, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;

        controls.upper_label[i] = gtk_label_new(_("Upper threshold:"));
        gtk_misc_set_alignment(GTK_MISC(controls.upper_label[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.upper_label[i],
                         0, 1, row, row+1, GTK_FILL, 0, 0, 0);

        controls.upper[i] = gtk_adjustment_new(0.0, 0.0, 0.0,
                                               1.0, 10.0, 0.0);
        g_object_set_data(G_OBJECT(controls.upper[i]), "id",
                          GUINT_TO_POINTER(i | IS_UPPER));
        g_signal_connect_swapped(controls.upper[i], "value-changed",
                                 G_CALLBACK(threshold_changed), &controls);
        controls.upper_scale[i]
            = gtk_hscale_new(GTK_ADJUSTMENT(controls.upper[i]));
        gtk_scale_set_draw_value(GTK_SCALE(controls.upper_scale[i]), FALSE);
        gtk_widget_set_size_request(controls.upper_scale[i],
                                    GWY_HSCALE_WIDTH, -1);
        gtk_table_attach(GTK_TABLE(table), controls.upper_scale[i],
                         1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);

        controls.upper_entry[i] = gtk_entry_new();
        gtk_entry_set_width_chars(GTK_ENTRY(controls.upper_entry[i]), 8);
        gtk_table_attach(GTK_TABLE(table), controls.upper_entry[i],
                         2, 3, row, row+1, GTK_FILL, 0, 0, 0);
        gwy_widget_set_activate_on_unfocus(controls.upper_entry[i], TRUE);
        g_object_set_data(G_OBJECT(controls.upper_entry[i]), "id",
                          GUINT_TO_POINTER(i | IS_UPPER));
        g_signal_connect_swapped(controls.upper_entry[i], "activate",
                                 G_CALLBACK(threshold_activated), &controls);

        controls.upper_units[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.upper_units[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.upper_units[i],
                         3, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;
    }

    for (i = 0; i < NQUANTITIES; i++) {
        GwyInventory *inventory;
        GwyGrainValue *gvalue;

        inventory = gwy_grain_values();
        gvalue = gwy_inventory_get_item(inventory, args->ranges[i].quantity);
        set_up_quantity(&controls, gvalue, i);
    }
    logical_op_changed(GTK_COMBO_BOX(controls.logical_op), &controls);

    /* finished initializing, allow instant updates */
    controls.in_init = FALSE;
    gfilter_invalidate(&controls);

    gtk_widget_show_all(dialog);
    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            args->expanded = gwy_grain_value_tree_view_get_expanded_groups
                                             (GTK_TREE_VIEW(controls.values));
            for (i = 0; i < NQUANTITIES; i++)
                gwy_si_unit_value_format_free(controls.vf[i]);
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            g_object_unref(controls.mydata);
            gfilter_save_args(gwy_app_settings_get(), args);
            return;
            break;

            case GTK_RESPONSE_OK:
            break;

            case RESPONSE_PREVIEW:
            preview(&controls);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    for (i = 0; i < NQUANTITIES; i++)
        gwy_si_unit_value_format_free(controls.vf[i]);
    args->expanded = gwy_grain_value_tree_view_get_expanded_groups
                                             (GTK_TREE_VIEW(controls.values));
    gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    gtk_widget_destroy(dialog);

    gfilter_save_args(gwy_app_settings_get(), args);

    if (controls.computed) {
        mfield = gwy_container_get_object_by_name(controls.mydata, "/0/mask");
        gwy_app_undo_qcheckpointv(data, 1, &mquark);
        gwy_container_set_object(data, mquark, mfield);
        g_object_unref(controls.mydata);
    }
    else {
        g_object_unref(controls.mydata);
        run_noninteractive(args, data, controls.mask, mquark);
    }

    gwy_app_channel_log_add_proc(data, id, id);
}
Example #26
0
static void
run_noninteractive(NoiseSynthArgs *args,
                   const GwyDimensionArgs *dimsargs,
                   GwyContainer *data,
                   GwyDataField *dfield,
                   gint oldid,
                   GQuark quark)
{
    GwySIUnit *siunit;
    gboolean replace = dimsargs->replace && dfield;
    gboolean add = dimsargs->add && dfield;
    gint newid;

    if (args->randomize)
        args->seed = g_random_int() & 0x7fffffff;

    if (replace) {
        /* Always take a reference so that we can always unref. */
        g_object_ref(dfield);

        gwy_app_undo_qcheckpointv(data, 1, &quark);
        if (!add)
            gwy_data_field_clear(dfield);

        gwy_app_channel_log_add_proc(data, oldid, oldid);
    }
    else {
        if (add)
            dfield = gwy_data_field_duplicate(dfield);
        else {
            gdouble mag = pow10(dimsargs->xypow10) * dimsargs->measure;
            dfield = gwy_data_field_new(dimsargs->xres, dimsargs->yres,
                                        mag*dimsargs->xres, mag*dimsargs->yres,
                                        TRUE);

            siunit = gwy_data_field_get_si_unit_xy(dfield);
            gwy_si_unit_set_from_string(siunit, dimsargs->xyunits);

            siunit = gwy_data_field_get_si_unit_z(dfield);
            gwy_si_unit_set_from_string(siunit, dimsargs->zunits);
        }
    }

    noise_synth_do(args, dimsargs, dfield);

    if (replace)
        gwy_data_field_data_changed(dfield);
    else {
        if (data) {
            newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
            if (oldid != -1)
                gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                                        GWY_DATA_ITEM_GRADIENT,
                                        0);
        }
        else {
            newid = 0;
            data = gwy_container_new();
            gwy_container_set_object(data, gwy_app_get_data_key_for_id(newid),
                                     dfield);
            gwy_app_data_browser_add(data);
            gwy_app_data_browser_reset_visibility(data,
                                                  GWY_VISIBILITY_RESET_SHOW_ALL);
            g_object_unref(data);
        }

        gwy_app_set_data_field_title(data, newid, _("Generated"));
        gwy_app_channel_log_add_proc(data, add ? oldid : -1, newid);
    }
    g_object_unref(dfield);
}
Example #27
0
static void
scale(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3];
    GQuark quark;
    gint oldid, newid;
    ScaleArgs args;
    gboolean ok;

    g_return_if_fail(run & SCALE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfields[0]);

    scale_load_args(gwy_app_settings_get(), &args);
    args.org_xres = gwy_data_field_get_xres(dfields[0]);
    args.org_yres = gwy_data_field_get_yres(dfields[0]);
    args.xres = ROUND(args.ratio*args.org_xres);
    if (args.proportional)
        args.aspectratio = 1.0;
    args.yres = ROUND(args.aspectratio*args.ratio*args.org_yres);

    if (run == GWY_RUN_INTERACTIVE) {
        ok = scale_dialog(&args);
        scale_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfields[0] = gwy_data_field_new_resampled(dfields[0],
                                              ROUND(args.xres),
                                              ROUND(args.yres),
                                              args.interp);
    if (dfields[1]) {
        dfields[1] = gwy_data_field_new_resampled(dfields[1],
                                                  ROUND(args.xres),
                                                  ROUND(args.yres),
                                                  args.interp);
    }
    if (dfields[2]) {
        dfields[2] = gwy_data_field_new_resampled(dfields[2],
                                                  ROUND(args.xres),
                                                  ROUND(args.yres),
                                                  args.interp);
    }

    newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE);
    g_object_unref(dfields[0]);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    if (dfields[1]) {
        quark = gwy_app_get_mask_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[1]);
        g_object_unref(dfields[1]);
    }
    if (dfields[2]) {
        quark = gwy_app_get_show_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[2]);
        g_object_unref(dfields[2]);
    }

    gwy_app_set_data_field_title(data, newid, _("Scaled Data"));
}
Example #28
0
static GwyContainer*
mif_load(const gchar *filename,
         G_GNUC_UNUSED GwyRunType mode,
         GError **error)
{
    GwyContainer *container = NULL;
    guchar *buffer = NULL;
    gsize size = 0;
    GError *err = NULL;
    MIFFile mfile;
    GwyDataField *dfield;
    guint i;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }

    if (!mif_read_header(buffer, size, &mfile.header, error)) {
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }
    /* TODO: Check file version */
    if (!mif_read_image_items(mfile.images, buffer, size, &mfile.header.info,
                              error)) {
        gwy_file_abandon_contents(buffer, size, NULL);
        return NULL;
    }

    /* FIXME: Only v1.7! */
    for (i = 0; i < mfile.header.nimages; i++) {
        MIFInfoItem *item = mfile.images + i;
        MIFImageHeader image_header;
        MIFBlock raster, macro_geometry, preview, image, curve, calc;
        guint ncalculations;
        const guchar *p = buffer + item->image.offset;
        GQuark quark;

        if (!item->image.size)
            continue;
        if (item->image.offset > size
            || item->image.size > size
            || item->image.offset + item->image.size > size) {
            continue;
        }

        /* XXX: We cannot use item->image.size because it's bogus, i.e.
         * too short.  Apparently there is some unaccounted-for space until
         * the next block starts, 120 bytes for v1.7 files, after the image
         * header which is in fact still occupied by the image header.
         * MIFBlock says 714 bytes but the true size is 834 = 714 + 120. */
        if (!mif_read_image_header(&image_header, &p, size - (p - buffer),
                                   mfile.header.file_version,
                                   error))
            continue;

        if (p - buffer + 52 > size)
            continue;

        mif_read_block(&raster, "raster", &p);
        mif_read_block(&macro_geometry, "macro_geometry", &p);
        mif_read_block(&preview, "preview", &p);
        mif_read_block(&image, "image", &p);
        mif_read_block(&curve, "curve", &p);
        ncalculations = gwy_get_guint32_le(&p);
        mif_read_block(&calc, "calc", &p);

        gwy_debug("image header true size: %zu",
                  (gsize)(p - (buffer + item->image.offset)));

        dfield = mif_read_data_field(&image_header, &image, buffer, size, NULL);
        if (!dfield)
            continue;

        if (!container)
            container = gwy_container_new();

        quark = gwy_app_get_data_key_for_id(i);
        gwy_container_set_object(container, quark, dfield);
        g_object_unref(dfield);
        gwy_app_channel_title_fall_back(container, i);
    }

    if (!container)
        err_NO_DATA(error);

    gwy_file_abandon_contents(buffer, size, NULL);
    return container;
}
Example #29
0
static GwyContainer*
burleigh_exp_load(const gchar *filename,
                  G_GNUC_UNUSED GwyRunType mode,
                  GError **error)
{
    GwyContainer *container = NULL;
    gchar *buffer = NULL;
    BurleighExpHeader header;
    gsize size = 0;
    GError *err = NULL;
    GwyDataField *dfield;
    gdouble *data;
    guint i, n;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }
    if (size < MIN_FILE_SIZE + 2) {
        err_TOO_SHORT(error);
        g_free(buffer);
        return NULL;
    }

    if (!burleigh_exp_read_header(&header, buffer, error))
        goto fail;

    n = header.xres * header.yres;
    if (header.binary) {
        if (header.bpp != 16) {
            err_BPP(error, header.bpp);
            goto fail;
        }
        else if (err_SIZE_MISMATCH(error, header.length + 2*n, size, TRUE))
            goto fail;
    }

    dfield = gwy_data_field_new(header.xres, header.yres,
                                header.xscale, header.yscale,
                                FALSE);
    data = gwy_data_field_get_data(dfield);

    if (header.binary) {
        const gint16 *d16 = (const gint16*)(buffer + header.length);

        for (i = 0; i < n; i++)
            data[i] = GINT16_FROM_LE(d16[i]);
    }
    else {
        gchar *p = buffer + header.length;

        for (i = 0; i < n; i++)
            data[i] = strtol(p, &p, 10);
    }

    gwy_data_field_multiply(dfield, header.zscale/32768.0);

    /* Units references released in free_header() */
    gwy_data_field_set_si_unit_xy(dfield, header.xyunits);
    gwy_data_field_set_si_unit_z(dfield, header.zunits);

    container = gwy_container_new();
    gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield);
    g_object_unref(dfield);
    gwy_app_channel_title_fall_back(container, 0);
    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    free_header(&header);
    g_free(buffer);

    return container;
}
Example #30
0
static GwyContainer*
rawxyz_load(const gchar *filename,
            GwyRunType mode,
            GError **error)
{
    GwyContainer *settings, *container = NULL;
    GwySurface *surface = NULL;
    RawXYZArgs args;
    GwySIUnit *unit;
    gint power10;
    gdouble q;
    gchar *buffer = NULL;
    gsize size;
    GError *err = NULL;
    gboolean ok;
    guint k;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        goto fail;
    }

    surface = read_xyz_points(buffer);
    g_free(buffer);
    if (!surface->n) {
        err_NO_DATA(error);
        goto fail;
    }

    settings = gwy_app_settings_get();
    rawxyz_load_args(settings, &args);
    if (mode == GWY_RUN_INTERACTIVE) {
        ok = rawxyz_dialog(&args, surface);
        rawxyz_save_args(settings, &args);
        if (!ok) {
            err_CANCELLED(error);
            goto fail;
        }
    }

    unit = gwy_si_unit_new_parse(args.xy_units, &power10);
    if (power10) {
        q = pow10(power10);
        for (k = 0; k < surface->n; k++) {
            surface->data[k].x *= q;
            surface->data[k].y *= q;
        }
        gwy_surface_invalidate(surface);
    }
    gwy_serializable_clone(G_OBJECT(unit),
                           G_OBJECT(gwy_surface_get_si_unit_xy(surface)));

    unit = gwy_si_unit_new_parse(args.z_units, &power10);
    if (power10) {
        q = pow10(power10);
        for (k = 0; k < surface->n; k++)
            surface->data[k].z *= q;
        gwy_surface_invalidate(surface);
    }
    gwy_serializable_clone(G_OBJECT(unit),
                           G_OBJECT(gwy_surface_get_si_unit_z(surface)));

    container = gwy_container_new();
    gwy_container_set_object(container, gwy_app_get_surface_key_for_id(0),
                             surface);
    gwy_app_xyz_title_fall_back(container, 0);
    gwy_file_xyz_import_log_add(container, 0, NULL, filename);

fail:
    g_free(args.xy_units);
    g_free(args.z_units);
    GWY_OBJECT_UNREF(surface);

    return container;
}