Exemple #1
0
static GwyDataField*
microprof_read_data_field(const MicroProfFile *mfile,
                          const guchar *buffer)
{
    const guint16 *d16 = (const guint16*)buffer;
    GwyDataField *dfield;
    GwySIUnit *siunit;
    gdouble *d;
    guint xres, yres, i, j;

    xres = mfile->xres;
    yres = mfile->yres;
    dfield = gwy_data_field_new(xres, yres,
                                mfile->xrange, mfile->yrange, FALSE);
    d = gwy_data_field_get_data(dfield);

    for (i = 0; i < yres; i++) {
        for (j = 0; j < xres; j++) {
            d[(yres-1 - i)*xres + j] = mfile->zscale*GUINT16_FROM_LE(*d16);
            d16++;
        }
    }

    siunit = gwy_data_field_get_si_unit_xy(dfield);
    gwy_si_unit_set_from_string(siunit, "m");

    siunit = gwy_data_field_get_si_unit_z(dfield);
    gwy_si_unit_set_from_string(siunit, "m");

    return dfield;
}
Exemple #2
0
static void
fill_data_fields(APEFile *apefile,
                 const guchar *buffer)
{
    GwyDataField *dfield;
    GwySIUnit *unit;
    gdouble *data;
    const gchar *zunit;
    guint b, n, i, j, k;
    gdouble q;

    apefile->data = g_new0(GwyDataField*, apefile->ndata);
    for (b = apefile->channels, n = 0, k = 0; b; b = b >> 1, k++) {
        if (!(b & 1))
            continue;

        dfield = gwy_data_field_new(apefile->res, apefile->res,
                                    apefile->xreal, apefile->yreal, FALSE);
        unit = gwy_data_field_get_si_unit_xy(dfield);
        gwy_si_unit_set_from_string(unit, "m");

        data = gwy_data_field_get_data(dfield);
        buffer += (apefile->res + 1)*sizeof(float);
        switch (k) {
            case APE_HEIGHT:
            case APE_HEIGHT_R:
            case APE_AUX2:
            case APE_AUX2_R:
            q = apefile->z_piezo_factor * 1e-9;
            zunit = "m";
            break;

            case APE_AUX1:
            case APE_AUX1_R:
            q = 1.0;
            zunit = apefile->pg850_image ? "A" : "V";
            break;

            default:
            q = 1.0;
            zunit = "V";
            break;
        }

        unit = gwy_data_field_get_si_unit_z(dfield);
        gwy_si_unit_set_from_string(unit, zunit);

        for (i = 0; i < apefile->res; i++) {
            /* There is always one ignored record, do not ask me why... */
            buffer += sizeof(float);
            for (j = 0; j < apefile->res; j++) {
                *(data++) = q*gwy_get_gfloat_le(&buffer);
            }
        }
        apefile->data[n] = dfield;
        n++;
    }
}
static GwyDataField*
rhk_sm4_page_to_data_field(const RHKPage *page)
{
    GwyDataField *dfield;
    GwySIUnit *siunit;
    const gchar *unit;
    const gint32 *pdata;
    gint xres, yres, i, j;
    gdouble *data;

    xres = page->x_size;
    yres = page->y_size;
    dfield = gwy_data_field_new(xres, yres,
                                xres*fabs(page->x_scale),
                                yres*fabs(page->y_scale),
                                FALSE);
    data = gwy_data_field_get_data(dfield);
    pdata = (const gint32*)page->data;
    for (i = 0; i < yres; i++) {
        for (j = 0; j < xres; j++) {
            data[i*xres + xres-1 - j] = GINT32_FROM_LE(pdata[i*xres + j])
                                        *page->z_scale + page->z_offset;
        }
    }

    /* XY units */
    if (page->strings[RHK_STRING_X_UNITS]
        && page->strings[RHK_STRING_Y_UNITS]) {
        if (!gwy_strequal(page->strings[RHK_STRING_X_UNITS],
                          page->strings[RHK_STRING_Y_UNITS]))
            g_warning("X and Y units differ, using X");
        unit = page->strings[RHK_STRING_X_UNITS];
    }
    else if (page->strings[RHK_STRING_X_UNITS])
        unit = page->strings[RHK_STRING_X_UNITS];
    else if (page->strings[RHK_STRING_Y_UNITS])
        unit = page->strings[RHK_STRING_Y_UNITS];
    else
        unit = NULL;

    siunit = gwy_data_field_get_si_unit_xy(dfield);
    gwy_si_unit_set_from_string(siunit, unit);

    /* Z units */
    if (page->strings[RHK_STRING_Z_UNITS])
        unit = page->strings[RHK_STRING_Z_UNITS];
    else
        unit = NULL;
    /* Fix some silly units */
    if (unit && gwy_strequal(unit, "N/sec"))
        unit = "s^-1";

    siunit = gwy_data_field_get_si_unit_z(dfield);
    gwy_si_unit_set_from_string(siunit, unit);

    return dfield;
}
Exemple #4
0
static GwyDataField*
mif_read_data_field(const MIFImageHeader *image_header,
                    const MIFBlock *block,
                    const guchar *buffer,
                    gsize size,
                    GError **error)
{
    gint xres = image_header->setup.xres;
    gint yres = image_header->setup.yres;
    gdouble xreal = image_header->setup.xreal;
    gdouble yreal = image_header->setup.yreal;
    gdouble xoff = image_header->setup.xoff;
    gdouble yoff = image_header->setup.yoff;
    gdouble q = image_header->configuration.scan_int_to_meter;
    GwyDataField *dfield;
    gdouble *data;
    const gint16 *d16;
    gint i, j;

    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        return NULL;

    if (!block->size || block->offset > size || block->size > size
        || block->offset + block->size > size) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Image data are outside the file."));
        return NULL;
    }

    if (err_SIZE_MISMATCH(error, xres*yres*sizeof(gint16), block->size, FALSE))
        return NULL;

    dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE);
    gwy_data_field_set_xoffset(dfield, xoff);
    gwy_data_field_set_yoffset(dfield, yoff);
    data = gwy_data_field_get_data(dfield);
    d16 = (const gint16*)(buffer + block->offset);

    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");

    // FIXME: Don't know why this factor.  It seems to match what MIF spmview
    // profile reader shows though.
    q *= 1.0e4;
    for (i = 0; i < yres; i++) {
        for (j = 0; j < yres; j++) {
            data[(yres-1 - i)*xres + j] = q*GINT16_FROM_LE(d16[i*xres + j]);
        }
    }

    return dfield;
}
Exemple #5
0
static GwyDataField*
jeol_read_data_field(const guchar *buffer,
                     const JEOLImageHeader *header)
{
    GwyDataField *dfield;
    const gchar *unitstr;
    gdouble q, z0;

    switch (header->spm_misc_param.measurement_signal) {
        case JEOL_MEASUREMENT_SIGNAL_TOPOGRAPHY:
        z0 = Nanometer*header->z0;
        q = (header->z255 - header->z0)/65535.0*Nanometer;
        unitstr = "m";
        break;

        case JEOL_MEASUREMENT_SIGNAL_LINEAR_CURRENT:
        z0 = Nanoampere*header->z0;
        q = (header->z255 - header->z0)/65535.0*Nanoampere;
        unitstr = "A";
        break;

        /* We just guess it's always voltage.  At least sometimes it is. */
        case JEOL_MEASUREMENT_SIGNAL_AUX1:
        case JEOL_MEASUREMENT_SIGNAL_AUX2:
        z0 = header->z0;
        q = (header->z255 - header->z0)/65535.0;
        unitstr = "V";
        break;

        default:
        return NULL;
        break;
    }

    dfield = gwy_data_field_new(header->xres, header->yres,
                                Nanometer*header->xreal,
                                Nanometer*header->yreal,
                                FALSE);

    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), unitstr);

    gwy_convert_raw_data(buffer, header->xres*header->yres, 1,
                         GWY_RAW_DATA_UINT16, GWY_BYTE_ORDER_LITTLE_ENDIAN,
                         gwy_data_field_get_data(dfield), q, z0);
    return dfield;
}
Exemple #6
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);
        }
    }
}
Exemple #7
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);
}
Exemple #8
0
static GwyContainer*
amb_load(const gchar *filename,
         G_GNUC_UNUSED GwyRunType mode,
         GError **error)
{
    GwyContainer *container = NULL;
    guchar *buffer = NULL;
    const guchar *p;
    gdouble *data;
    guint i, j;
    gsize size = 0;
    GError *err = NULL;
    guint xres, yres;
    GwyDataField *dfield;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }
    if (size <= HEADER_SIZE) {
        err_TOO_SHORT(error);
        goto fail;
    }

    /* The two bytes before are usually zeroes */
    p = buffer + XRES_OFFSET;
    xres = gwy_get_guint32_le(&p);
    p = buffer + YRES_OFFSET;
    yres = gwy_get_guint32_le(&p);
    gwy_debug("xres: %u yres: %u", xres, yres);
    /* The four bytes after might be a float, then there are four more bytes. */
    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        goto fail;
    if (err_SIZE_MISMATCH(error, 4*xres*yres + HEADER_SIZE, size, TRUE))
        goto fail;

    dfield = gwy_data_field_new(xres, yres, 1.0, 1.0*yres/xres,
                                FALSE);
    data = gwy_data_field_get_data(dfield);
    p = buffer + HEADER_SIZE;
    for (i = 0; i < yres; i++) {
        for (j = 0; j < xres; j++)
            data[i*xres + j] = gwy_get_gfloat_le(&p);
    }

    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");

    container = gwy_container_new();
    gwy_container_set_object_by_name(container, "/0/data", dfield);
    gwy_container_set_string_by_name(container, "/0/data/title",
                                     g_strdup("Topography"));
    g_object_unref(dfield);

    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    gwy_file_abandon_contents(buffer, size, NULL);

    return container;
}
Exemple #9
0
static GwyDataField*
pt3file_extract_counts(const PicoHarpFile *pt3file,
                       const LineTrigger *linetriggers,
                       const guchar *p)
{
    GwyDataField *dfield;
    guint xres, yres, i, lineno, pixno, n;
    guint64 globaltime, globalbase, start, stop;
    gdouble pix_resol;
    gdouble *d;

    xres = pt3file->imaging.common.xres;
    yres = pt3file->imaging.common.yres;
    n = pt3file->number_of_records;
    if (pt3file->imaging.common.instrument == PICO_HARP_PIE710)
        pix_resol = pt3file->imaging.pie710.pix_resol;
    else if (pt3file->imaging.common.instrument == PICO_HARP_KDT180)
        pix_resol = pt3file->imaging.kdt180.pix_resol;
    else {
        g_return_val_if_reached(NULL);
    }
    if (!(pix_resol = fabs(pix_resol))) {
        g_warning("Pixel size is 0.0, fixing to 1.0");
        pix_resol = 1.0;
    }
    pix_resol *= 1e-6;

    dfield = gwy_data_field_new(xres, yres, pix_resol*xres, pix_resol*yres,
                                TRUE);
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m");
    d = gwy_data_field_get_data(dfield);

    lineno = 0;
    start = linetriggers[lineno].start;
    stop = linetriggers[lineno].stop;
    globaltime = globalbase = 0;
    for (i = 0; i < n; i++) {
        PicoHarpT3Record rec;

        p = read_t3_record(&rec, p);
        if (rec.channel == 15) {
            if (rec.nsync == 0 && rec.time == 0)
                globalbase += 0x10000;
            continue;
        }
        globaltime = globalbase | rec.nsync;
        while (lineno < yres && globaltime >= linetriggers[lineno].stop) {
            lineno++;
            if (lineno == yres)
                break;
            start = linetriggers[lineno].start;
            stop = linetriggers[lineno].stop;
        }

        if (globaltime >= start && globaltime < stop) {
            pixno = (xres*(globaltime - start)/(stop - start));
            pixno = MIN(pixno, xres-1);
            if (pt3file->imaging.common.bidirectional && lineno % 2)
                d[xres*lineno + (xres-1 - pixno)] += 1.0;
            else
                d[xres*lineno + pixno] += 1.0;
        }
    }

    return dfield;
}
Exemple #10
0
static GwyDataField*
apedax_get_data_field(unzFile uFile,
                      const gchar *chFileName,
                      const APEScanSize *scanSize,
                      gchar *zUnit,
                      gdouble scale,
                      GError **error)
{
    GwyDataField *dfield = NULL;
    GwySIUnit *xyUnit;
    GwySIUnit *zSIUnit;
    gdouble *data;
    guchar *buffer;
    gsize size, expectedSize;
    unz_file_info uFileInfo;

    /*Checking the dimensions*/
    if (err_DIMENSION(error, scanSize->XRes)) {
        return NULL;
    }

    if (err_DIMENSION(error, scanSize->YRes)) {
        return NULL;
    }

    /*If XReal it's not greater than 0 or XReal is NaN*/
    if (!(fabs(scanSize->XReal) > 0)) {
        err_UNSUPPORTED(error, "X scan size");
        return NULL;
    }

    /*Same for YReal*/
    if (!(fabs(scanSize->YReal) > 0)) {
        err_UNSUPPORTED(error, "Y scan size");
        return NULL;
    }

    expectedSize = scanSize->XRes * scanSize->YRes * sizeof(gdouble);

    unzGoToFirstFile(uFile);

    if (unzLocateFile(uFile, chFileName, 0) != UNZ_OK) {
        gwy_debug("Binary file not found");
        err_NO_DATA(error);
        return NULL;
    }

    if (unzGetCurrentFileInfo(uFile,
                              &uFileInfo,
                              NULL,
                              0L,
                              NULL,
                              0L,
                              NULL,
                              0L) != UNZ_OK) {
        err_NO_DATA(error);
        return NULL;
    }

    buffer = apedax_get_file_content(uFile, &uFileInfo, &size, error);

    if (buffer == NULL) {
        err_NO_DATA(error);
        return NULL;
    }

    if (err_SIZE_MISMATCH(error, expectedSize, size, FALSE)) {
       return NULL;
    }

    dfield = gwy_data_field_new(scanSize->XRes, scanSize->YRes,
                                scanSize->XReal, scanSize->YReal,
                                FALSE);

    data = gwy_data_field_get_data(dfield);

    xyUnit = gwy_data_field_get_si_unit_xy(dfield);
    gwy_si_unit_set_from_string(xyUnit, "m");

    zSIUnit = gwy_data_field_get_si_unit_z(dfield);
    gwy_si_unit_set_from_string(zSIUnit, zUnit);

    gwy_debug("Reading RAW data");

    gwy_convert_raw_data(buffer,
                         scanSize->XRes * scanSize->YRes,
                         1,
                         GWY_RAW_DATA_DOUBLE,
                         GWY_BYTE_ORDER_LITTLE_ENDIAN,
                         data,
                         scale,
                         0.0);

    return dfield;
}
Exemple #11
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);
}
Exemple #12
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;
}
Exemple #13
0
static GwyContainer*
csmfile_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    GwyContainer *meta, *container = NULL;
    GHashTable *hash = NULL;
    guchar *d24, *buffer = NULL;
    gsize size = 0;
    GError *err = NULL;
    GwyDataField *dfield = NULL;
    guint xres, yres, bmpsize, header_size, maxval, i, j;
    gdouble real, zmin, zmax, q, z0;
    GwyTextHeaderParser parser;
    GwySIUnit *unit = NULL;
    gchar *value, *end, *header = NULL;
    gdouble *data;
    gint power10;

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

    if (size < BMP_HEADER_SIZE) {
        err_TOO_SHORT(error);
        goto fail;
    }
    if (!read_bmp_header(buffer, &xres, &yres, &bmpsize)
        || size <= bmpsize) {
        err_FILE_TYPE(error, "CSM");
        goto fail;
    }

    header_size = size - bmpsize;
    header = g_new(gchar, header_size + 1);
    memcpy(header, buffer + bmpsize, header_size);
    header[header_size] = '\0';

    gwy_clear(&parser, 1);
    parser.key_value_separator = "=";
    hash = gwy_text_header_parse(header, &parser, NULL, NULL);

    /* Do NOT use the fields Image width, Image height from the added footer.
     * Even though it is specifically added by Benyuan it can disagree with the
     * BMP diemsions and when they disagree the BMP diemsions are apparently
     * right. */
    if (err_DIMENSION(error, xres))
        goto fail;
    if (err_DIMENSION(error, yres))
        goto fail;

    if (!(value = g_hash_table_lookup(hash, "ScanSize"))) {
        err_MISSING_FIELD(error, "ScanSize");
        goto fail;
    }
    real = g_ascii_strtod(value, NULL);
    /* Use negated positive conditions to catch NaNs */
    if (!((real = fabs(real)) > 0)) {
        g_warning("Real size is 0.0, fixing to 1.0");
        real = 1.0;
    }

    if (!(value = g_hash_table_lookup(hash, "HeightScale"))) {
        err_MISSING_FIELD(error, "HeightScale");
        goto fail;
    }
    zmax = g_ascii_strtod(value, &end);
    unit = gwy_si_unit_new_parse(end, &power10);

    /* Optional stuff for which we try to fall back. */
    if (!(value = g_hash_table_lookup(hash, "StartHeightScale")))
        zmin = 0.0;
    else
        zmin = g_ascii_strtod(value, NULL);

    if (!(value = g_hash_table_lookup(hash, "MaxValue")))
        maxval = 0xffff;
    else
        maxval = MAX(atoi(value), 1);


    dfield = gwy_data_field_new(xres, yres, real*Nanometre, real*Nanometre,
                                FALSE);
    data = gwy_data_field_get_data(dfield);

    d24 = buffer + BMP_HEADER_SIZE;
    q = pow10(power10)*(zmax - zmin)/maxval;
    z0 = pow10(power10)*zmin;
    for (i = 0; i < yres; i++) {
        gdouble *row = data + (yres-1 - i)*xres;
        for (j = 0; j < xres; j++, row++, d24 += 3)
            *row = (d24[0] + 256.0*d24[1])*q + z0;
    }

    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m");
    gwy_data_field_set_si_unit_z(dfield, unit);

    container = gwy_container_new();
    gwy_container_set_object_by_name(container, "/0/data", dfield);
    g_object_unref(dfield);

    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);

    if ((value = g_hash_table_lookup(hash, "sTitle"))
        && g_utf8_validate(value, -1, NULL)) {
        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:
    gwy_file_abandon_contents(buffer, size, NULL);
    GWY_OBJECT_UNREF(unit);
    if (header)
        g_free(header);
    if (hash)
        g_hash_table_destroy(hash);

    return container;
}
Exemple #14
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;
}
Exemple #15
0
static GwyDataField*
mif_read_data_field(const MIFImageHeader *image_header,
                    const MIFBlock *block,
                    const guchar *buffer,
                    gsize size,
                    GError **error)
{
    const MIFScanSetup *setup = &image_header->setup;
    const MIFImageConfiguration *configuration = &image_header->configuration;
    gint xres = setup->xres;
    gint yres = setup->yres;
    gdouble xreal = setup->xreal * image_header->configuration.xcal;
    gdouble yreal = setup->yreal * image_header->configuration.ycal;
    gdouble xoff = setup->xoff;
    gdouble yoff = setup->yoff;
    gdouble q = configuration->zcal/65536.0;
    GwyDataField *dfield;
    gdouble *data, *linecorrdata = NULL;
    gsize datasize;
    const gint16 *d16;
    gint i, j;

    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        return NULL;

    if (!block->size || block->offset > size || block->size > size
        || block->offset + block->size > size) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Image data are outside the file."));
        return NULL;
    }

    datasize = xres*yres*sizeof(gint16);
    if (err_SIZE_MISMATCH(error, datasize, block->size, FALSE))
        return NULL;

    if (datasize + yres*sizeof(gint16) <= block->size) {
        gwy_debug("There may be %u correction data after the image.", yres);
        linecorrdata = g_new(gdouble, yres);
        d16 = (const gint16*)(buffer + block->offset + datasize);
        for (i = 0; i < yres; i++) {
            linecorrdata[i] = pow(2.0, d16[i] - 13);
            gwy_debug("corr[%u] %g", i, linecorrdata[i]);
        }
    }

    dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE);
    gwy_data_field_set_xoffset(dfield, xoff);
    gwy_data_field_set_yoffset(dfield, yoff);
    data = gwy_data_field_get_data(dfield);
    d16 = (const gint16*)(buffer + block->offset);

    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");

    // XXX: Don't know why this range.  A user got it from DME.  Have no idea
    // why scan_int_to_meter does not appear here.
    if (!configuration->z_linearized)
        q *= 15e-6;
    else
        q *= 20e-6;

    for (i = 0; i < yres; i++) {
        gdouble qi = linecorrdata ? q*linecorrdata[i] : q;
        for (j = 0; j < yres; j++) {
            data[(yres-1 - i)*xres + j] = qi*GINT16_FROM_LE(d16[i*xres + j]);
        }
    }

    g_free(linecorrdata);

    return dfield;
}
Exemple #16
0
static void
psdflp_do(const PSDFLPArgs *args, GwyDataField *dfield, GwyDataField *lpsdf)
{
    enum { N = 4 };

    GwyDataField *reout, *imout;
    gint pxres, pyres, fxres, fyres;
    gint i, j, fi, pi;
    gdouble *ldata, *redata, *imdata;
    gdouble *cosphi, *sinphi;
    gdouble xreal, yreal, f0, f_max, b, p;

    reout = gwy_data_field_new_alike(dfield, FALSE);
    imout = gwy_data_field_new_alike(dfield, FALSE);
    gwy_data_field_2dfft(dfield, NULL, reout, imout,
                         args->window, GWY_TRANSFORM_DIRECTION_FORWARD,
                         GWY_INTERPOLATION_ROUND, /* Ignored */
                         TRUE, 1);

    pxres = reout->xres;
    pyres = reout->yres;
    redata = gwy_data_field_get_data(reout);
    imdata = gwy_data_field_get_data(imout);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = redata[i]*redata[i] + imdata[i]*imdata[i];
    gwy_data_field_2dfft_humanize(reout);
    gwy_data_field_filter_gaussian(reout, args->sigma);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = sqrt(redata[i]);

    fxres = pxres/2;
    fyres = pyres/2;
    gwy_data_field_resample(lpsdf, fxres, fyres, GWY_INTERPOLATION_NONE);
    ldata = gwy_data_field_get_data(lpsdf);

    xreal = dfield->xreal;
    yreal = dfield->yreal;
    f0 = 2.0/MIN(xreal, yreal);
    f_max = 0.5*MIN(pxres/xreal, pyres/yreal);
    if (f_max <= f0) {
        g_warning("Minimum frequency is not smaller than maximum frequency.");
    }
    b = log(f_max/f0)/fyres;

    /* Incorporate some prefactors to sinphi[] and cosphi[], knowing that
     * cosine is only ever used for x and sine for y frequencies. */
    cosphi = g_new(gdouble, (N+1)*fxres);
    sinphi = g_new(gdouble, (N+1)*fxres);
    for (j = 0; j < fxres; j++) {
        gdouble phi_from = 2.0*G_PI*j/fxres;
        gdouble phi_to = 2.0*G_PI*(j + 1.0)/fxres;

        for (pi = 0; pi <= N; pi++) {
            gdouble phi = ((pi + 0.5)*phi_from + (N - 0.5 - pi)*phi_to)/N;
            cosphi[j*(N+1) + pi] = cos(phi)*xreal;
            sinphi[j*(N+1) + pi] = sin(phi)*yreal;
        }
    }

    for (i = 0; i < fyres; i++) {
        gdouble f_from = f0*exp(b*i);
        gdouble f_to = f0*exp(b*(i + 1.0));

        for (j = 0; j < fxres; j++) {
            const gdouble *cosphi_j = cosphi + j*(N+1);
            const gdouble *sinphi_j = sinphi + j*(N+1);
            guint n = 0;
            gdouble s = 0.0;

            for (fi = 0; fi <= N; fi++) {
                gdouble f = ((fi + 0.5)*f_from + (N - 0.5 - fi)*f_to)/N;
                for (pi = 0; pi <= N; pi++) {
                    gdouble x = f*cosphi_j[pi] + pxres/2.0,
                            y = f*sinphi_j[pi] + pyres/2.0;

                    if (G_UNLIKELY(x < 0.5
                                   || y < 0.5
                                   || x > pxres - 1.5
                                   || y > pyres - 1.5))
                        continue;

                    p = gwy_data_field_get_dval(reout, x, y,
                                                GWY_INTERPOLATION_SCHAUM);
                    s += p;
                    n++;
                }
            }

            if (!n)
                n = 1;

            ldata[i*fxres + j] = 2.0*G_PI/fxres * s/n*(f_to - f_from);
        }
    }

    g_object_unref(imout);
    g_object_unref(reout);

    gwy_data_field_set_xreal(lpsdf, 2.0*G_PI);
    gwy_data_field_set_xoffset(lpsdf, 0.0);
    gwy_data_field_set_yreal(lpsdf, log(f_max/f0));
    gwy_data_field_set_yoffset(lpsdf, log(f0));
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(lpsdf), "");
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(lpsdf), "");
    gwy_data_field_normalize(lpsdf);
}