static gboolean read_aist_raster(const guchar **p, gsize *size, AistContext *context) { AistRaster raster; GwyDataField *dfield, *mfield; GwySIUnit *xyunit, *zunit; gboolean ok = FALSE; guint i, j, n, len; const guchar *data; gchar *s; gchar key[32]; gdouble *d; gdouble qxy, qz; gwy_clear(&raster, 1); gwy_debug("reading common"); if (!read_aist_common(p, size, &raster.common)) goto fail; gwy_debug("reading raster"); if (!read_qt_int(p, size, &raster.xres) || !read_qt_int(p, size, &raster.yres) || !read_qt_double(p, size, &raster.left) || !read_qt_double(p, size, &raster.right) || !read_qt_double(p, size, &raster.top) || !read_qt_double(p, size, &raster.bottom) || !read_qt_string(p, size, &raster.xunits) || !read_qt_string(p, size, &raster.yunits) || !read_qt_string(p, size, &raster.zunits)) goto fail; if (!read_qt_byte_array(p, size, &len, &data)) goto fail; n = raster.xres * raster.yres; if (len != n*sizeof(gdouble)) goto fail; xyunit = extract_units(raster.xunits, &qxy); zunit = extract_units(raster.zunits, &qz); dfield = gwy_data_field_new(raster.xres, raster.yres, qxy*fabs(raster.right - raster.left), qxy*fabs(raster.bottom - raster.top), FALSE); gwy_data_field_set_si_unit_xy(dfield, xyunit); gwy_data_field_set_si_unit_z(dfield, zunit); /* Apparently this is not generally wanted. gwy_data_field_set_xoffset(dfield, qxy*MIN(raster.left, raster.right)); gwy_data_field_set_yoffset(dfield, qxy*MIN(raster.top, raster.bottom)); */ g_object_unref(xyunit); g_object_unref(zunit); d = gwy_data_field_get_data(dfield); for (i = 0; i < raster.yres; i++) { for (j = 0; j < raster.xres; j++) { d[(raster.yres-1 - i)*raster.xres + j] = qz*gwy_get_gdouble_le(&data); } } g_snprintf(key, sizeof(key), "/%d/data", context->channel_id); gwy_container_set_object_by_name(context->container, key, dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(context->container, context->channel_id, NULL, context->filename); if ((s = strchr(raster.common.name, '['))) s = g_strchomp(g_strndup(raster.common.name, s - raster.common.name)); else s = g_strdup(raster.common.name); g_snprintf(key, sizeof(key), "/%d/data/title", context->channel_id); gwy_container_set_string_by_name(context->container, key, s); g_snprintf(key, sizeof(key), "/%d/mask", context->channel_id); context->channel_id++; /* At this moment we consider the loading successful. */ ok = TRUE; /* The mask raster is byte-valued. It contains nonzeroes in points that * were measured (the opposite of how we normally create masks upon * import). */ if (read_qt_byte_array(p, size, &len, &data)) { if (len == raster.xres*raster.yres) { mfield = make_mask_field(dfield, data); if (mfield) { gwy_app_channel_remove_bad_data(dfield, mfield); gwy_container_set_object_by_name(context->container, key, mfield); g_object_unref(mfield); } } /* Here's something called view data. It means the data was processed * (by whatever means) hence we are not interesed in it. */ read_qt_byte_array(p, size, &len, &data); } fail: free_aist_common(&raster.common); g_free(raster.xunits); g_free(raster.yunits); g_free(raster.zunits); return ok; }
static gint fill_data_fields(MProFile *mprofile, const guchar *buffer) { GwyDataField *dfield, *vpmask; gdouble *data, *mask; gdouble xreal, yreal, q; const guchar *p; guint n, id, i, j, ndata; ndata = 0; mprofile->intensity_data = NULL; mprofile->intensity_mask = NULL; mprofile->phase_data = NULL; mprofile->phase_mask = NULL; p = buffer + mprofile->header_size; /* Intensity data */ n = mprofile->intens_xres * mprofile->intens_yres; /* Enorce consistency */ if (!n && mprofile->nbuckets) { g_warning("nbuckets > 0, but intensity data have zero dimension"); mprofile->nbuckets = 0; } if (mprofile->nbuckets) { const guint16 *d16; mprofile->intensity_data = g_new(GwyDataField*, mprofile->nbuckets); mprofile->intensity_mask = g_new(GwyDataField*, mprofile->nbuckets); q = mprofile->data_inverted ? -1.0 : 1.0; if (mprofile->camera_res) { xreal = mprofile->intens_xres * mprofile->camera_res; yreal = mprofile->intens_yres * mprofile->camera_res; } else { /* whatever */ xreal = mprofile->intens_xres; yreal = mprofile->intens_yres; } for (id = 0; id < mprofile->nbuckets; id++) { ndata++; dfield = gwy_data_field_new(mprofile->intens_xres, mprofile->intens_yres, xreal, yreal, FALSE); vpmask = gwy_data_field_new_alike(dfield, FALSE); gwy_data_field_fill(vpmask, 1.0); data = gwy_data_field_get_data(dfield); mask = gwy_data_field_get_data(vpmask); d16 = (const guint16*)p; for (i = 0; i < mprofile->intens_yres; i++) { for (j = 0; j < mprofile->intens_xres; j++) { guint v16 = GUINT16_FROM_BE(*d16); if (v16 >= 65412) { mask[i*mprofile->intens_xres + j] = 0.0; } else *data = q*v16; d16++; data++; } } set_units(dfield, mprofile, ""); if (!gwy_app_channel_remove_bad_data(dfield, vpmask)) gwy_object_unref(vpmask); mprofile->intensity_data[id] = dfield; mprofile->intensity_mask[id] = vpmask; p += sizeof(guint16)*n; } } /* Phase data */ n = mprofile->phase_xres * mprofile->phase_yres; if (n) { const gint32 *d32; gint32 d; ndata++; i = 4096; if (mprofile->phase_res == 1) i = 32768; q = mprofile->scale_factor * mprofile->obliquity_factor * mprofile->wavelength_in/i; if (mprofile->data_inverted) q = -q; gwy_debug("q: %g", q); if (mprofile->camera_res) { xreal = mprofile->phase_xres * mprofile->camera_res; yreal = mprofile->phase_yres * mprofile->camera_res; } else { /* whatever */ xreal = mprofile->phase_xres; yreal = mprofile->phase_yres; } dfield = gwy_data_field_new(mprofile->phase_xres, mprofile->phase_yres, xreal, yreal, FALSE); vpmask = gwy_data_field_new_alike(dfield, FALSE); gwy_data_field_fill(vpmask, 1.0); data = gwy_data_field_get_data(dfield); mask = gwy_data_field_get_data(vpmask); d32 = (const gint32*)p; for (i = 0; i < mprofile->phase_yres; i++) { for (j = 0; j < mprofile->phase_xres; j++) { d = GINT32_FROM_BE(*d32); if (d >= 2147483640) { mask[i*mprofile->phase_xres + j] = 0.0; } else *data = q*d; d32++; data++; } } set_units(dfield, mprofile, "m"); if (!gwy_app_channel_remove_bad_data(dfield, vpmask)) gwy_object_unref(vpmask); mprofile->phase_data = dfield; mprofile->phase_mask = vpmask; p += sizeof(gint32)*n; } return ndata; }
static GwyContainer* asc_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; GwyDataField *dfield = NULL, *mfield = NULL; GwyTextHeaderParser parser; GwySIUnit *unit; gchar *line, *p, *value, *buffer = NULL; GHashTable *hash = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal, q; gint i, xres, yres; gdouble *data; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } p = buffer; line = gwy_str_next_line(&p); if (!gwy_strequal(line, MAGIC_BARE)) { err_FILE_TYPE(error, "SPIP ASCII data"); goto fail; } gwy_clear(&parser, 1); parser.line_prefix = "#"; parser.key_value_separator = "="; parser.terminator = "# Start of Data:"; parser.error = &header_error; parser.end = &header_end; if (!(hash = gwy_text_header_parse(p, &parser, &p, &err))) { g_propagate_error(error, err); goto fail; } if (!require_keys(hash, error, "x-pixels", "y-pixels", "x-length", "y-length", NULL)) goto fail; xres = atoi(g_hash_table_lookup(hash, "x-pixels")); yres = atoi(g_hash_table_lookup(hash, "y-pixels")); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; xreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "x-length"), NULL); yreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "y-length"), NULL); /* Use negated positive conditions to catch NaNs */ if (!((xreal = fabs(xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); xreal = 1.0; } if (!((yreal = fabs(yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); yreal = 1.0; } dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); if ((value = g_hash_table_lookup(hash, "z-unit"))) { gint power10; unit = gwy_si_unit_new_parse(value, &power10); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); q = pow10(power10); } else if ((value = g_hash_table_lookup(hash, "Bit2nm"))) { q = Nanometer * g_ascii_strtod(value, NULL); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); } else q = 1.0; data = gwy_data_field_get_data(dfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = q*g_ascii_strtod(value, &p); if (p == value && (!*p || g_ascii_isspace(*p))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when reading sample #%d of %d"), i, xres*yres); goto fail; } if (p == value) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Malformed data encountered when reading sample " "#%d of %d"), i, xres*yres); goto fail; } value = p; } if ((value = g_hash_table_lookup(hash, "voidpixels")) && atoi(value)) { mfield = gwy_data_field_new_alike(dfield, FALSE); data = gwy_data_field_get_data(mfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = 1.0 - g_ascii_strtod(value, &p); value = p; } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) GWY_OBJECT_UNREF(mfield); } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: GWY_OBJECT_UNREF(dfield); g_free(buffer); if (hash) g_hash_table_destroy(hash); return container; }
static GwyContainer* int_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta; GwyDataField *dfield = NULL, *mfield = NULL; CodeVGridDataType type; gchar *line, *p, *comment, *end, *buffer = NULL; const gchar *unit, *title; gchar **fields = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal; gint i, xres, yres, no_data_value = 32767; guint fi; gdouble scale_size, wavelength, q = 1.0, x_scale = 1.0; gboolean nearest_neighbour = FALSE; gdouble *data, *mdata; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } /* Skip comments. */ p = buffer; for (line = gwy_str_next_line(&p); line && line[0] == '!'; line = gwy_str_next_line(&p)) { gwy_debug("comment <%s>", line); } if (!line) { err_FILE_TYPE(error, "Code V INT"); goto fail; } /* The title. */ comment = line; if (!(line = gwy_str_next_line(&p))) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("comment <%s>", comment); fields = split_line_in_place(line); if (!fields || g_strv_length(fields) < 8 || !gwy_strequal(fields[0], "GRD") || !(xres = atoi(fields[1])) || !(yres = atoi(fields[2])) || !(type = gwy_stramong(fields[3], "SUR", "WFR", "FIL", "THV", "BIR", "CAO", NULL)) || !gwy_strequal(fields[4], "WVL") || (!(wavelength = g_ascii_strtod(fields[5], &end)) && end == fields[5])) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("type %u (%s)", type, fields[3]); gwy_debug("xres %d, yres %d", xres, yres); gwy_debug("wavelength %g", wavelength); fi = 6; if (gwy_strequal(fields[fi], "NNB")) { nearest_neighbour = TRUE; fi++; } gwy_debug("nearest_neighbour %d", nearest_neighbour); if (!fields[fi] || !gwy_strequal(fields[fi], "SSZ")) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; if (!(scale_size = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("scale_size %g", scale_size); if (!scale_size) { g_warning("Zero SSZ, fixing to 1.0"); scale_size = 1.0; } fi++; if (fields[fi] && gwy_strequal(fields[fi], "NDA")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } no_data_value = atoi(fields[fi]); fi++; } gwy_debug("no_data_value %d", no_data_value); if (fields[fi] && gwy_strequal(fields[fi], "XSC")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } if (!(x_scale = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; } gwy_debug("x_scale %g", x_scale); if (!x_scale) { g_warning("Zero XSC, fixing to 1.0"); x_scale = 1.0; } /* There may be more stuff but we do not know anything about it. */ if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; yreal = 1.0; xreal = x_scale*yreal; dfield = gwy_data_field_new(xres, yres, xreal, yreal, TRUE); if (type == CODEV_INT_SURFACE_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Surface"; } else if (type == CODEV_INT_WAVEFRONT_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Wavefront"; } else { g_warning("Don't know how to convert this grid data type to physical " "units."); title = fields[3]; } gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), unit); mfield = gwy_data_field_new_alike(dfield, TRUE); data = gwy_data_field_get_data(dfield); mdata = gwy_data_field_get_data(mfield); for (i = 0; i < xres*yres; i++, p = end) { gint value = strtol(p, &end, 10); if (value != no_data_value && (type != CODEV_INT_INTENSITY_FILTER || value >= 0)) { mdata[i] = 1.0; data[i] = q*value; } } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) gwy_object_unref(mfield); container = gwy_container_new(); /* gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); from F. Riguet : apparently no flip is needed (the raw data import module gives the correct orientation without further flipping) */ gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); gwy_app_channel_check_nonsquare(container, 0); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); if (mfield) { /* gwy_data_field_invert(mfield, FALSE, TRUE, FALSE); */ gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } meta = gwy_container_new(); gwy_container_set_string_by_name(meta, "Comment", g_strdup(comment)); gwy_container_set_string_by_name(meta, "Interpolation", g_strdup(nearest_neighbour ? "NNB" : "Linear")); gwy_container_set_string_by_name(meta, "Wavelength", g_strdup_printf("%g μm", wavelength)); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: g_free(fields); g_free(buffer); return container; }
static GwyDataField* sensofar_read_data_field(SensofarDataDesc *data_desc, GwyDataField **maskfield, const guchar **p, gsize size, GError **error) { GwyDataField *dfield, *mfield; guint xres, yres, i, j, mcount; GwySIUnit *units = NULL; gdouble *data, *mdata; if (maskfield) *maskfield = NULL; yres = gwy_get_guint32_le(p); xres = gwy_get_guint32_le(p); gwy_debug("Data size: %dx%d", xres, yres); if (err_SIZE_MISMATCH(error, xres*yres*sizeof(gfloat), size - 2*sizeof(guint32), FALSE)) return NULL; if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; if (!((data_desc->axes_config.mppx = fabs(data_desc->axes_config.mppx)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); data_desc->axes_config.mppx = 1.0; } if (!((data_desc->axes_config.mppy = fabs(data_desc->axes_config.mppy)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); data_desc->axes_config.mppy = 1.0; } dfield = gwy_data_field_new(xres, yres, data_desc->axes_config.mppx * xres * Micrometer, data_desc->axes_config.mppy * yres * Micrometer, FALSE); units = gwy_si_unit_new("m"); // values are in um only gwy_data_field_set_si_unit_xy(dfield, units); g_object_unref(units); units = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, units); g_object_unref(units); mfield = gwy_data_field_new_alike(dfield, FALSE); gwy_data_field_fill(mfield, 1.0); data = gwy_data_field_get_data(dfield); mdata = gwy_data_field_get_data(mfield); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { gdouble v = gwy_get_gfloat_le(p); if (v == 1000001.0) mdata[i*xres + j] = 0.0; else data[i*xres + j] = v*Micrometer; } } gwy_debug("Offset: %g %g", data_desc->axes_config.x_0, data_desc->axes_config.y_0); //FIXME: offset later, support of offset determined by version? //gwy_data_field_set_xoffset(d, pow10(power10)*data_desc.axes_config.x_0); //gwy_data_field_set_yoffset(d, pow10(power10)*data_desc.axes_config.y_0); mcount = gwy_app_channel_remove_bad_data(dfield, mfield); if (maskfield && mcount) *maskfield = mfield; else g_object_unref(mfield); return dfield; }