static void compute_slopes(GwyDataField *dfield, gint kernel_size, GwyDataField *xder, GwyDataField *yder) { gint xres, yres; xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); if (kernel_size) { GwyPlaneFitQuantity quantites[] = { GWY_PLANE_FIT_BX, GWY_PLANE_FIT_BY }; GwyDataField *fields[2]; fields[0] = xder; fields[1] = yder; gwy_data_field_fit_local_planes(dfield, kernel_size, 2, quantites, fields); gwy_data_field_multiply(xder, xres/gwy_data_field_get_xreal(dfield)); gwy_data_field_multiply(yder, yres/gwy_data_field_get_yreal(dfield)); } else gwy_data_field_filter_slope(dfield, xder, yder); }
static void compute_slopes(GwyDataField *dfield, gint kernel_size, GwyDataField *xder, GwyDataField *yder) { gint xres, yres; xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); if (kernel_size > 1) { GwyPlaneFitQuantity quantites[] = { GWY_PLANE_FIT_BX, GWY_PLANE_FIT_BY }; GwyDataField *fields[2]; fields[0] = xder; fields[1] = yder; gwy_data_field_fit_local_planes(dfield, kernel_size, 2, quantites, fields); } else { gint col, row; gdouble *xd, *yd; const gdouble *data; gdouble d; data = gwy_data_field_get_data_const(dfield); xd = gwy_data_field_get_data(xder); yd = gwy_data_field_get_data(yder); for (row = 0; row < yres; row++) { for (col = 0; col < xres; col++) { if (!col) d = data[row*xres + col + 1] - data[row*xres + col]; else if (col == xres-1) d = data[row*xres + col] - data[row*xres + col - 1]; else d = (data[row*xres + col + 1] - data[row*xres + col - 1])/2; *(xd++) = d; if (!row) d = data[row*xres + xres + col] - data[row*xres + col]; else if (row == yres-1) d = data[row*xres + col] - data[row*xres - xres + col]; else d = (data[row*xres + xres + col] - data[row*xres - xres + col])/2; *(yd++) = d; } } } gwy_data_field_multiply(xder, xres/gwy_data_field_get_xreal(dfield)); gwy_data_field_multiply(yder, yres/gwy_data_field_get_yreal(dfield)); }
static void fix_scales(EZDSection *section, gint idx, GwyContainer *container) { GwyDataField *dfield; GwySIUnit *siunit; gchar key[40]; gint power10; gdouble r; g_snprintf(key, sizeof(key), "/%d/data", idx); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(container, key)); /* Fix value scale */ siunit = gwy_si_unit_new_parse(section->zrange.unit, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); r = pow10(power10); gwy_data_field_multiply(dfield, r*section->zrange.range); gwy_data_field_add(dfield, r*section->zrange.min); /* Fix lateral scale */ siunit = gwy_si_unit_new_parse(section->xrange.unit, &power10); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); gwy_data_field_set_xreal(dfield, pow10(power10)*section->xrange.range); siunit = gwy_si_unit_new_parse(section->yrange.unit, &power10); gwy_data_field_set_yreal(dfield, pow10(power10)*section->yrange.range); g_object_unref(siunit); /* Some metadata */ if (section->zrange.name) { const gchar *s; switch (section->direction) { case SCAN_FORWARD: s = " forward"; break; case SCAN_BACKWARD: s = " backward"; break; default: s = ""; break; } g_snprintf(key, sizeof(key), "/%d/data/title", idx); gwy_container_set_string_by_name(container, key, g_strdup_printf("%s%s", section->zrange.name, s)); } }
static GwyDataField* rhkspm32_read_data(RHKPage *rhkpage) { GwyDataField *dfield; const guint16 *p; GwySIUnit *siunit; gdouble *data; const gchar *s; gdouble q; gint power10; guint i, j, xres, yres; p = (const guint16*)(rhkpage->buffer + rhkpage->data_offset); xres = rhkpage->xres; yres = rhkpage->yres; // the scales are no longer gurunteed to be positive, // so they must be "fixed" here (to enable spectra) dfield = gwy_data_field_new(xres, yres, xres*fabs(rhkpage->x.scale), yres*fabs(rhkpage->y.scale), FALSE); data = gwy_data_field_get_data(dfield); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) data[i*xres + xres-1 - j] = GINT16_FROM_LE(p[i*xres + j]); } siunit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string_parse(siunit, rhkpage->x.units, &power10); if (power10) { q = pow10(power10); gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield)); gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield)); } siunit = gwy_data_field_get_si_unit_z(dfield); s = rhkpage->z.units; /* Fix some silly units */ if (gwy_strequal(s, "N/sec")) s = "s^-1"; gwy_si_unit_set_from_string_parse(siunit, s, &power10); q = pow10(power10); gwy_data_field_multiply(dfield, q*fabs(rhkpage->z.scale)); gwy_data_field_add(dfield, q*rhkpage->z.offset); return dfield; }
static void sdfile_set_units(SDFile *sdfile, GwyDataField *dfield) { GwySIUnit *siunit; gwy_data_field_multiply(dfield, sdfile->zscale); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); }
static GwyContainer* burleigh_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwySIUnit *unit; GwyContainer *container = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; GError *err = NULL; IMGFile imgfile; GwyDataField *dfield; gdouble *data; const gint16 *d; gdouble zoom; guint i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE_MIN + 2) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } gwy_clear(&imgfile, 1); p = buffer; imgfile.version = gwy_get_gfloat_le(&p); imgfile.version_int = GWY_ROUND(10*imgfile.version); if (imgfile.version_int == 21) { d = burleigh_load_v21(&imgfile, buffer, size, error); if (!d) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File format version %.1f is not supported."), imgfile.version); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } zoom = burleigh_get_zoom_v21(&imgfile); if (err_DIMENSION(error, imgfile.xres) || err_DIMENSION(error, imgfile.yres)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } dfield = gwy_data_field_new(imgfile.xres, imgfile.yres, Angstrom*imgfile.xrange/zoom, Angstrom*imgfile.yrange/zoom, FALSE); data = gwy_data_field_get_data(dfield); for (i = 0; i < imgfile.xres*imgfile.yres; i++) data[i] = GINT16_FROM_LE(d[i])*imgfile.zrange/4095.0; gwy_file_abandon_contents(buffer, size, NULL); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); container = gwy_container_new(); switch (imgfile.data_type) { case BURLEIGH_CURRENT: unit = gwy_si_unit_new("A"); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Current")); gwy_data_field_multiply(dfield, Picoampere); break; case BURLEIGH_TOPOGRAPHY: unit = gwy_si_unit_new("m"); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Topography")); gwy_data_field_multiply(dfield, Angstrom); break; default: unit = gwy_si_unit_new("m"); break; } gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(container, 0, NULL, filename); return container; }
static GwyContainer* surffile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SurfFile surffile; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; const guchar *p; gsize expected_size, size = 0; GError *err = NULL; gchar signature[12]; gdouble max, min; gint add = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); g_clear_error(&err); return NULL; } if (size < SURF_HEADER_SIZE + 2) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } p = buffer; get_CHARARRAY(signature, &p); if (strncmp(signature, "DIGITAL SURF", 12) != 0) { err_FILE_TYPE(error, "Surf"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } surffile.format = gwy_get_guint16_le(&p); surffile.nobjects = gwy_get_guint16_le(&p); surffile.version = gwy_get_guint16_le(&p); surffile.type = gwy_get_guint16_le(&p); get_CHARS0(surffile.object_name, &p, 30); get_CHARS0(surffile.operator_name, &p, 30); surffile.material_code = gwy_get_guint16_le(&p); surffile.acquisition = gwy_get_guint16_le(&p); surffile.range = gwy_get_guint16_le(&p); surffile.special_points = gwy_get_guint16_le(&p); surffile.absolute = gwy_get_guint16_le(&p); /*reserved*/ p += 8; surffile.pointsize = gwy_get_guint16_le(&p); surffile.zmin = gwy_get_gint32_le(&p); surffile.zmax = gwy_get_gint32_le(&p); surffile.xres = gwy_get_gint32_le(&p); surffile.yres = gwy_get_gint32_le(&p); surffile.nofpoints = gwy_get_guint32_le(&p); surffile.dx = gwy_get_gfloat_le(&p); surffile.dy = gwy_get_gfloat_le(&p); surffile.dz = gwy_get_gfloat_le(&p); get_CHARS0(surffile.xaxis, &p, 16); get_CHARS0(surffile.yaxis, &p, 16); get_CHARS0(surffile.zaxis, &p, 16); get_CHARS0(surffile.dx_unit, &p, 16); get_CHARS0(surffile.dy_unit, &p, 16); get_CHARS0(surffile.dz_unit, &p, 16); get_CHARS0(surffile.xlength_unit, &p, 16); get_CHARS0(surffile.ylength_unit, &p, 16); get_CHARS0(surffile.zlength_unit, &p, 16); surffile.xunit_ratio = gwy_get_gfloat_le(&p); surffile.yunit_ratio = gwy_get_gfloat_le(&p); surffile.zunit_ratio = gwy_get_gfloat_le(&p); surffile.imprint = gwy_get_guint16_le(&p); surffile.inversion = gwy_get_guint16_le(&p); surffile.leveling = gwy_get_guint16_le(&p); p += 12; surffile.seconds = gwy_get_guint16_le(&p); surffile.minutes = gwy_get_guint16_le(&p); surffile.hours = gwy_get_guint16_le(&p); surffile.day = gwy_get_guint16_le(&p); surffile.month = gwy_get_guint16_le(&p); surffile.year = gwy_get_guint16_le(&p); surffile.measurement_duration = gwy_get_guint16_le(&p); surffile.comment_size = gwy_get_guint16_le(&p); surffile.private_size = gwy_get_guint16_le(&p); get_CHARARRAY(surffile.client_zone, &p); surffile.XOffset = gwy_get_gfloat_le(&p); surffile.YOffset = gwy_get_gfloat_le(&p); surffile.ZOffset = gwy_get_gfloat_le(&p); gwy_debug("fileformat: %d, n_of_objects: %d, " "version: %d, object_type: %d", surffile.format, surffile.nobjects, surffile.version, surffile.type); gwy_debug("object name: <%s>", surffile.object_name); gwy_debug("operator name: <%s>", surffile.operator_name); gwy_debug("material code: %d, acquisition type: %d", surffile.material_code, surffile.acquisition); gwy_debug("range type: %d, special points: %d, absolute: %d", surffile.range, surffile.special_points, (gint)surffile.absolute); gwy_debug("data point size: %d", surffile.pointsize); gwy_debug("zmin: %d, zmax: %d", surffile.zmin, surffile.zmax); gwy_debug("xres: %d, yres: %d (xres*yres = %d)", surffile.xres, surffile.yres, (surffile.xres*surffile.yres)); gwy_debug("total number of points: %d", surffile.nofpoints); gwy_debug("dx: %g, dy: %g, dz: %g", surffile.dx, surffile.dy, surffile.dz); gwy_debug("X axis name: %16s", surffile.xaxis); gwy_debug("Y axis name: %16s", surffile.yaxis); gwy_debug("Z axis name: %16s", surffile.zaxis); gwy_debug("dx unit: %16s", surffile.dx_unit); gwy_debug("dy unit: %16s", surffile.dy_unit); gwy_debug("dz unit: %16s", surffile.dz_unit); gwy_debug("X axis unit: %16s", surffile.xlength_unit); gwy_debug("Y axis unit: %16s", surffile.ylength_unit); gwy_debug("Z axis unit: %16s", surffile.zlength_unit); gwy_debug("xunit_ratio: %g, yunit_ratio: %g, zunit_ratio: %g", surffile.xunit_ratio, surffile.yunit_ratio, surffile.zunit_ratio); gwy_debug("imprint: %d, inversion: %d, leveling: %d", surffile.imprint, surffile.inversion, surffile.leveling); gwy_debug("Time: %d:%d:%d, Date: %d.%d.%d", surffile.hours, surffile.minutes, surffile.seconds, surffile.day, surffile.month, surffile.year); gwy_debug("private zone size: %d, comment size %d", surffile.private_size, surffile.comment_size); expected_size = (SURF_HEADER_SIZE + surffile.pointsize/8*surffile.xres*surffile.yres); if (expected_size != size) { gwy_debug("Size mismatch!"); if (size > expected_size) add = size - expected_size; /*TODO correct this !*/ else { err_SIZE_MISMATCH(error, expected_size, size); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } p = buffer + SURF_HEADER_SIZE + add; if (!fill_data_fields(&surffile, p, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (!surffile.absolute) { max = gwy_data_field_get_max(surffile.dfield); min = gwy_data_field_get_min(surffile.dfield); gwy_data_field_add(surffile.dfield, -min); gwy_data_field_multiply(surffile.dfield, (surffile.zmax - surffile.zmin)/(max-min)); } switch (surffile.inversion) { case SURF_INV_Z: gwy_data_field_invert(surffile.dfield, FALSE, FALSE, TRUE); break; case SURF_FLIP_Z: gwy_data_field_invert(surffile.dfield, FALSE, TRUE, TRUE); break; case SURF_FLOP_Z: gwy_data_field_invert(surffile.dfield, TRUE, FALSE, TRUE); break; default: break; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", surffile.dfield); g_object_unref(surffile.dfield); meta = surffile_get_metadata(&surffile); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_app_channel_check_nonsquare(container, 0); return container; }
static GwyContainer* surffile_load(const gchar *filename) { SurfFile surffile; GObject *object = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; gsize estsize; GError *err = NULL; gchar signature[12]; gdouble max, min; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_warning("Cannot read file %s", filename); g_clear_error(&err); return NULL; } p = buffer; get_CHARARRAY(signature, &p); if (strncmp(signature, "DIGITAL SURF", 12) != 0) { g_warning("File %s is not a Surf file", filename); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (size < 500) { g_warning("File %s is too short to be Surf file", filename); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } surffile.format = get_WORD_LE(&p); surffile.nobjects = get_WORD_LE(&p); surffile.version = get_WORD_LE(&p); surffile.type = get_WORD_LE(&p); get_CHARS0(surffile.object_name, &p, 30); get_CHARS0(surffile.operator_name, &p, 30); surffile.material_code = get_WORD_LE(&p); surffile.acquisition = get_WORD_LE(&p); surffile.range = get_WORD_LE(&p); surffile.special_points = get_WORD_LE(&p); surffile.absolute = get_WORD_LE(&p); /*reserved*/ p += 8; surffile.pointsize = get_WORD_LE(&p); surffile.zmin = get_DWORD(&p); surffile.zmax = get_DWORD(&p); surffile.xres = get_DWORD(&p); surffile.yres = get_DWORD(&p); surffile.nofpoints = get_DWORD(&p); //surffile.xres = 200; surffile.yres = 200; surffile.dx = get_FLOAT_LE(&p); surffile.dy = get_FLOAT_LE(&p); surffile.dz = get_FLOAT_LE(&p); get_CHARS0(surffile.xaxis, &p, 16); get_CHARS0(surffile.yaxis, &p, 16); get_CHARS0(surffile.zaxis, &p, 16); get_CHARS0(surffile.dx_unit, &p, 16); get_CHARS0(surffile.dy_unit, &p, 16); get_CHARS0(surffile.dz_unit, &p, 16); get_CHARS0(surffile.xlength_unit, &p, 16); get_CHARS0(surffile.ylength_unit, &p, 16); get_CHARS0(surffile.zlength_unit, &p, 16); surffile.xunit_ratio = get_FLOAT_LE(&p); surffile.yunit_ratio = get_FLOAT_LE(&p); surffile.zunit_ratio = get_FLOAT_LE(&p); surffile.imprint = get_WORD_LE(&p); surffile.inversion = get_WORD_LE(&p); surffile.leveling = get_WORD_LE(&p); p += 12; surffile.seconds = get_WORD_LE(&p); surffile.minutes = get_WORD_LE(&p); surffile.hours = get_WORD_LE(&p); surffile.day = get_WORD_LE(&p); surffile.month = get_WORD_LE(&p); surffile.year = get_WORD_LE(&p); surffile.measurement_duration = get_WORD_LE(&p); surffile.comment_size = get_WORD_LE(&p); surffile.private_size = get_WORD_LE(&p); get_CHARARRAY(surffile.client_zone, &p); surffile.XOffset = get_FLOAT_LE(&p); surffile.YOffset = get_FLOAT_LE(&p); surffile.ZOffset = get_FLOAT_LE(&p); gwy_debug("fileformat: %d, n_of_objects: %d, version: %d, object_type: %d", surffile.format, surffile.nobjects, surffile.version, surffile.type); gwy_debug("object name: %s", surffile.object_name); gwy_debug("operator name: %s", surffile.operator_name); gwy_debug("material code: %d, acquisition type: %d", surffile.material_code, surffile.acquisition); gwy_debug("range type: %d, special points: %d, absolute: %d", surffile.range, surffile.special_points, (gint)surffile.absolute); gwy_debug("data point size: %d", surffile.pointsize); gwy_debug("zmin: %d, zmax: %d", surffile.zmin, surffile.zmax); gwy_debug("xres: %d, yres: %d (xres*yres = %d)", surffile.xres, surffile.yres, (surffile.xres*surffile.yres)); gwy_debug("total number of points: %d", surffile.nofpoints); gwy_debug("dx: %g, dy: %g, dz: %g", surffile.dx, surffile.dy, surffile.dz); gwy_debug("X axis name: %16s", surffile.xaxis); gwy_debug("Y axis name: %16s", surffile.yaxis); gwy_debug("Z axis name: %16s", surffile.zaxis); gwy_debug("dx unit: %16s", surffile.dx_unit); gwy_debug("dy unit: %16s", surffile.dy_unit); gwy_debug("dz unit: %16s", surffile.dz_unit); gwy_debug("X axis unit: %16s", surffile.xlength_unit); gwy_debug("Y axis unit: %16s", surffile.ylength_unit); gwy_debug("Z axis unit: %16s", surffile.zlength_unit); gwy_debug("xunit_ratio: %g, yunit_ratio: %g, zunit_ratio: %g", surffile.xunit_ratio, surffile.yunit_ratio, surffile.zunit_ratio); gwy_debug("imprint: %d, inversion: %d, leveling: %d", surffile.imprint, surffile.inversion, surffile.leveling); gwy_debug("Time: %d:%d:%d, Date: %d.%d.%d", surffile.hours, surffile.minutes, surffile.seconds, surffile.day, surffile.month, surffile.year); p = buffer + 512; estsize = 512 + surffile.pointsize*surffile.xres*surffile.yres/8; if (size < estsize) { g_warning("File %s is too short to contain Surf data %d %d", filename, (int)size, (int)estsize); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } fill_data_fields(&surffile, p); gwy_file_abandon_contents(buffer, size, NULL); if (surffile.absolute == 0) { max = gwy_data_field_get_max(surffile.dfield); min = gwy_data_field_get_min(surffile.dfield); gwy_data_field_add(surffile.dfield, -min); gwy_data_field_multiply(surffile.dfield, (surffile.zmax - surffile.zmin)/(max-min)); } if (surffile.inversion == 1) gwy_data_field_invert(surffile.dfield, FALSE, FALSE, TRUE); if (surffile.inversion == 2) gwy_data_field_invert(surffile.dfield, FALSE, TRUE, TRUE); if (surffile.inversion == 3) gwy_data_field_invert(surffile.dfield, TRUE, FALSE, TRUE); if (surffile.dfield) { object = gwy_container_new(); gwy_container_set_object_by_name(GWY_CONTAINER(object), "/0/data", G_OBJECT(surffile.dfield)); store_metadata(&surffile, GWY_CONTAINER(object)); } return (GwyContainer*)object; return NULL; }
static void level_grains_do(const LevelGrainsArgs *args, GwyContainer *data, GQuark dquark, gint id, GwyDataField *dfield, GwyDataField *mfield) { GwyDataField *buffer, *background, *invmask; gdouble error, cor, maxerr, lastfrac, frac, starterr; gdouble *heights, *bgdata; gint *grains; gboolean cancelled = FALSE; gint i, xres, yres, ngrains; xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); if (!ngrains) { g_free(grains); return; } heights = g_new(gdouble, ngrains+1); gwy_data_field_grains_get_values(dfield, heights, ngrains, grains, args->base); heights[0] = 0.0; background = gwy_data_field_new_alike(dfield, FALSE); bgdata = gwy_data_field_get_data(background); for (i = 0; i < xres*yres; i++) bgdata[i] = -heights[grains[i]]; invmask = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(invmask, -1.0); gwy_data_field_add(invmask, 1.0); maxerr = gwy_data_field_get_rms(dfield)/1.0e4; gwy_app_wait_start(gwy_app_find_window_for_channel(data, id), _("Laplace interpolation...")); g_free(heights); g_free(grains); buffer = gwy_data_field_new_alike(background, TRUE); gwy_data_field_correct_average(background, invmask); cor = 0.2; error = 0.0; lastfrac = 0.0; starterr = 0.0; for (i = 0; i < 5000; i++) { gwy_data_field_correct_laplace_iteration(background, invmask, buffer, cor, &error); if (error < maxerr) break; if (!i) starterr = error; frac = log(error/starterr)/log(maxerr/starterr); 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_data_field_invert(background, FALSE, FALSE, TRUE); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (args->do_extract) { gint newid; newid = gwy_app_data_browser_add_data_field(background, data, TRUE); gwy_app_sync_data_items(data, data, id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); } } g_object_unref(buffer); g_object_unref(invmask); g_object_unref(background); }
static GwyContainer* zeiss_load_tiff(const GwyTIFF *tiff, GError **error) { GwyContainer *container = NULL, *meta = NULL; GwyDataField *dfield; GwySIUnit *siunit; GwyTIFFImageReader *reader = NULL; GHashTable *hash = NULL; gint i, power10; gchar *value, *end, *comment = NULL; gdouble *data; gboolean new_file; double factor, dx; /* Comment with parameters is common for all data fields */ if (!gwy_tiff_get_string0(tiff, ZEISS_HEADER_TAG, &comment)) { err_FILE_TYPE(error, "Carl Zeiss SEM"); goto fail; } if (strstr(comment, MAGIC_COMMENT)) new_file = TRUE; else if (g_str_has_prefix(comment, SOMEWHAT_LESS_MAGIC_COMMENT)) new_file = FALSE; else { err_FILE_TYPE(error, "Carl Zeiss SEM"); goto fail; } /* Read the comment header. */ if (new_file) { hash = parse_comment(comment); if ((value = g_hash_table_lookup(hash, "Image Pixel Size"))) { gwy_debug("Using dx from Image Pixel Size: %s", value); } else if ((value = g_hash_table_lookup(hash, "Pixel Size"))) { gwy_debug("Using dx from Pixel Size: %s", value); } else { err_MISSING_FIELD(error, "Pixel Size"); goto fail; } } else { /* The first thing is the pixel size, apparently. */ value = comment + strlen(SOMEWHAT_LESS_MAGIC_COMMENT); gwy_debug("Using dx from old-style comment: %s", value); } dx = g_ascii_strtod(value, &end); /* Use negated positive conditions to catch NaNs */ if (!((dx = fabs(dx)) > 0)) { g_warning("Real pixel size is 0.0, fixing to 1.0"); dx = 1.0; } if (!new_file) end = "m"; /* Request a reader, this ensures dimensions and stuff are defined. * NB: Newer versions store the image as RGB. Not useful here; just * average the channels. */ if (!(reader = gwy_tiff_get_image_reader(tiff, 0, 3, error))) goto fail; siunit = gwy_si_unit_new_parse(end, &power10); factor = pow10(power10); dfield = gwy_data_field_new(reader->width, reader->height, reader->width * factor * dx, reader->height * factor * dx, FALSE); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); data = gwy_data_field_get_data(dfield); if (reader->samples_per_pixel > 1) { gdouble *datarow = g_new(gdouble, reader->width); gint ch, j, spp = reader->samples_per_pixel; gwy_data_field_clear(dfield); for (i = 0; i < reader->height; i++) { for (ch = 0; ch < spp; ch++) { gwy_tiff_read_image_row(tiff, reader, 0, i, 1.0, 0.0, datarow); for (j = 0; j < reader->width; j++) data[i*reader->width + j] += datarow[j]; } } g_free(datarow); gwy_data_field_multiply(dfield, 1.0/spp); gwy_data_field_invalidate(dfield); } else { for (i = 0; i < reader->height; i++) gwy_tiff_read_image_row(tiff, reader, 0, i, 1.0, 0.0, data + i*reader->width); } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Secondary electron count")); if (new_file) { meta = gwy_container_new(); g_hash_table_foreach(hash, add_meta, meta); if (gwy_container_get_n_items(meta)) gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); } fail: if (hash) g_hash_table_destroy(hash); g_free(comment); return container; }
static GwyContainer* aafm_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwySIUnit *unit; GwyContainer *container = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; GError *err = NULL; AFMFile afmfile; GwyDataField *dfield; gdouble min, max; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < 12) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } p = buffer; afmfile.res = gwy_get_guint16_le(&p); if (err_DIMENSION(error, afmfile.res)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (err_SIZE_MISMATCH(error, afmfile.res * afmfile.res + 10, size, FALSE)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } afmfile.real = Angstrom*gwy_get_gfloat_le(&p); if (!(afmfile.real = fabs(afmfile.real))) { g_warning("Real size is 0.0, fixing to 1.0"); afmfile.real = 1.0; } dfield = gwy_data_field_new(afmfile.res, afmfile.res, afmfile.real, afmfile.real, FALSE); read_binary_data(afmfile.res, gwy_data_field_get_data(dfield), p); p += 2*afmfile.res*afmfile.res; afmfile.range = gwy_get_gfloat_le(&p); gwy_data_field_get_min_max(dfield, &min, &max); if (min == max) gwy_data_field_clear(dfield); else gwy_data_field_multiply(dfield, afmfile.range/(max - min)*Angstrom); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); 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); gwy_file_abandon_contents(buffer, size, NULL); return container; }
static GwyDataField* read_datafield(const guchar *buffer, guint size, const StmprgFile *stmprgfile, GError **error) { gint xres, yres, bpp; gdouble xreal, yreal, q; GwyDataField *dfield; gdouble *data; GwySIUnit *unit; bpp = 2; /* words, always */ xres = stmprgfile->mainfield.points; yres = stmprgfile->mainfield.lines; xreal = Angstrom * stmprgfile->mainfield.field_x; yreal = Angstrom * stmprgfile->mainfield.field_y; q = stmprgfile->mainfield.sol_z * 1.0e-5; /* 5 ?? */ /* resolution of z value in angstrom/bit, 1.0e-10 */ if (err_SIZE_MISMATCH(error, bpp*xres*yres, size, FALSE)) return NULL; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); data = gwy_data_field_get_data(dfield); if (!read_binary_ubedata(xres * yres, data, buffer, bpp)) { err_BPP(error, bpp); g_object_unref(dfield); return NULL; } gwy_data_field_multiply(dfield, q); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); /* Assuming we are reading channel1... */ switch (stmprgfile->control.channel1) { case STMPRG_CHANNEL_OFF: g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("First channel is switched off.")); return NULL; case STMPRG_CHANNEL_Z: unit = gwy_si_unit_new("m"); break; case STMPRG_CHANNEL_I: case STMPRG_CHANNEL_I_I0: case STMPRG_CHANNEL_I0: unit = gwy_si_unit_new("A"); break; case STMPRG_CHANNEL_EXT1: case STMPRG_CHANNEL_EXT2: case STMPRG_CHANNEL_U0: unit = gwy_si_unit_new("V"); break; default: g_assert_not_reached(); break; } gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); return dfield; }
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; }
static GwyContainer* fits_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; fitsfile *fptr = NULL; GwyDataField *field = NULL, *mask; gint status = 0; /* Must be initialised to zero! */ gint hdutype, naxis, anynull, nkeys, k; glong res[3]; /* First index is the fast looping one. */ char strvalue[FLEN_VALUE]; gchar *invalid = NULL; gdouble real, off; if (fits_open_image(&fptr, filename, READONLY, &status)) { err_FITS(error, status); return NULL; } if (fits_get_hdu_type(fptr, &hdutype, &status)) { err_FITS(error, status); goto fail; } gwy_debug("hdutype %d", hdutype); if (hdutype != IMAGE_HDU) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } if (fits_get_img_dim(fptr, &naxis, &status)) { err_FITS(error, status); goto fail; } gwy_debug("naxis %d", naxis); if (naxis != 2 && naxis != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } if (fits_get_img_size(fptr, naxis, res, &status)) { err_FITS(error, status); goto fail; } if (naxis == 3 && res[2] != 1) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } gwy_debug("xres %ld, yres %ld", res[0], res[1]); if (err_DIMENSION(error, res[0]) || err_DIMENSION(error, res[1])) goto fail; field = gwy_data_field_new(res[0], res[1], res[0], res[1], FALSE); invalid = g_new(gchar, res[0]*res[1]); if (fits_read_imgnull(fptr, TDOUBLE, 1, res[0]*res[1], field->data, invalid, &anynull, &status)) { err_FITS(error, status); goto fail; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", field); /* Failures here are non-fatal. We already have an image. */ if (fits_get_hdrspace(fptr, &nkeys, NULL, &status)) { g_warning("Cannot get the first hdrspace."); goto fail; } if (!fits_read_key(fptr, TSTRING, "BUINT ", strvalue, NULL, &status)) { gint power10; gwy_debug("BUINT = <%s>", strvalue); gwy_si_unit_set_from_string_parse(gwy_data_field_get_si_unit_z(field), strvalue, &power10); if (power10) gwy_data_field_multiply(field, pow10(power10)); } status = 0; if (get_real_and_offset(fptr, 1, res[0], &real, &off)) { if (real < 0.0) { off += real; real = -real; gwy_data_field_invert(field, FALSE, TRUE, FALSE); } gwy_data_field_set_xreal(field, real); gwy_data_field_set_xoffset(field, off); } if (get_real_and_offset(fptr, 2, res[1], &real, &off)) { if (real < 0.0) { off += real; real = -real; gwy_data_field_invert(field, TRUE, FALSE, FALSE); } gwy_data_field_set_yreal(field, real); gwy_data_field_set_yoffset(field, off); } /* Create a mask of invalid data. */ for (k = 0; k < field->xres*field->yres; k++) { if (invalid[k]) field->data[k] = NAN; } if ((mask = gwy_app_channel_mask_of_nans(field, TRUE))) { gwy_container_set_object_by_name(container, "/0/mask", mask); g_object_unref(mask); } fail: fits_close_file(fptr, &status); gwy_object_unref(field); g_free(invalid); return container; }
static GwyContainer* pni_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const GwyEnum titles[] = { { "Height", DATA_TYPE_HGT, }, { "Sens", DATA_TYPE_SEN, }, { "Dem", DATA_TYPE_DEM, }, { "Error", DATA_TYPE_ERR, }, { "L-R", DATA_TYPE_L_R, }, }; GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; const guchar *p; gint i, xres, yres; PNIDataType data_type; PNIValueType value_type; PNIDirection direction; gdouble xreal, yreal, zscale; gdouble *data; const gint16 *d16; GwySIUnit *siunit; const gchar *title; gchar *s; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < DATA_START + 2) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } p = buffer + DATA_HEADER_START + RESOLUTION_OFFSET; xres = gwy_get_guint32_le(&p); yres = gwy_get_guint32_le(&p); gwy_debug("%d %d", xres, yres); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres) || err_SIZE_MISMATCH(error, DATA_START + 2*xres*yres, size, TRUE)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } p = buffer + DATA_HEADER_START; data_type = p[DATA_TYPE_OFFSET]; value_type = p[VALUE_TYPE_OFFSET]; direction = p[DIRECTION_OFFSET]; p = buffer + DATA_HEADER_START + REAL_SIZE_OFFSET; xreal = gwy_get_gfloat_le(&p); yreal = gwy_get_gfloat_le(&p); /* 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; } xreal *= Micrometer; yreal *= Micrometer; p = buffer + DATA_HEADER_START + VALUE_SCALE_OFFSET; zscale = gwy_get_gfloat_le(&p); dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); data = gwy_data_field_get_data(dfield); d16 = (const gint16*)(buffer + DATA_START); for (i = 0; i < xres*yres; i++) data[i] = zscale*GINT16_FROM_LE(d16[i])/65536.0; gwy_file_abandon_contents(buffer, size, NULL); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); switch (value_type) { case VALUE_TYPE_NM: siunit = gwy_si_unit_new("m"); gwy_data_field_multiply(dfield, Nanometer); break; case VALUE_TYPE_MV: siunit = gwy_si_unit_new("V"); gwy_data_field_multiply(dfield, Milivolt); break; default: g_warning("Value type %d is unknown", value_type); siunit = gwy_si_unit_new(NULL); break; } gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); title = gwy_enum_to_string(data_type, titles, G_N_ELEMENTS(titles)); if (title) { s = g_strdup_printf("%s (%s)", title, direction ? "Forward" : "Backward"); gwy_container_set_string_by_name(container, "/0/data/title", s); } else g_warning("Data type %d is unknown", data_type); gwy_file_channel_import_log_add(container, 0, NULL, filename); return container; }
static GwyDataField* omicron_read_data(OmicronFile *ofile, OmicronTopoChannel *channel, GError **error) { GError *err = NULL; GwyDataField *dfield; GwySIUnit *siunit; gchar *filename; gdouble *data; guchar *buffer; const gint16 *d; gdouble scale; gsize size; guint i, j, n; gint power10 = 0; filename = omicron_fix_file_name(ofile->filename, channel->filename, error); if (!filename) return NULL; gwy_debug("Succeeded with <%s>", filename); if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_free(filename); err_GET_FILE_CONTENTS(error, &err); return NULL; } g_free(filename); n = ofile->xres*ofile->yres; if (err_SIZE_MISMATCH(error, 2*n, size, TRUE)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } scale = (channel->max_phys - channel->min_phys) /(channel->max_raw - channel->min_raw); dfield = gwy_data_field_new(ofile->xres, ofile->yres, ofile->xreal, ofile->yreal, FALSE); data = gwy_data_field_get_data(dfield); d = (const gint16*)buffer; for (i = 0; i < ofile->yres; i++) { for (j = 0; j < ofile->xres; j++) data[(ofile->yres-1 - i)*ofile->xres + j] = scale*GINT16_FROM_BE(d[i*ofile->xres + j]); } gwy_file_abandon_contents(buffer, size, NULL); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); siunit = gwy_si_unit_new_parse(channel->units, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); if (power10) gwy_data_field_multiply(dfield, pow10(power10)); return dfield; }
static GwyDataField* unisoku_read_data_field(const guchar *buffer, gsize size, UnisokuFile *ufile, GError **error) { gint i, n, power10; const gchar *unit; GwyDataField *dfield; GwySIUnit *siunit; gdouble q, pmin, pmax, rmin, rmax; gdouble *data; n = ufile->xres * ufile->yres; if (err_SIZE_MISMATCH(error, n*type_sizes[ufile->data_type], size, FALSE)) return NULL; dfield = gwy_data_field_new(ufile->xres, ufile->yres, fabs((ufile->end_x - ufile->start_x)), fabs((ufile->end_y - ufile->start_y)), FALSE); data = gwy_data_field_get_data(dfield); /* FIXME: what to do when ascii_flag is set? */ switch (ufile->data_type) { case UNISOKU_UINT8: for (i = 0; i < n; i++) data[i] = buffer[i]; break; case UNISOKU_SINT8: for (i = 0; i < n; i++) data[i] = (signed char)buffer[i]; break; case UNISOKU_UINT16: { const guint16 *pdata = (const guint16*)buffer; for (i = 0; i < n; i++) data[i] = GUINT16_FROM_LE(pdata[i]); } break; case UNISOKU_SINT16: { const gint16 *pdata = (const gint16*)buffer; for (i = 0; i < n; i++) data[i] = GINT16_FROM_LE(pdata[i]); } break; case UNISOKU_FLOAT: for (i = 0; i < n; i++) data[i] = gwy_get_gfloat_le(&buffer); break; default: g_return_val_if_reached(NULL); break; } unit = ufile->unit_x; if (!*unit) unit = "nm"; siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_xy(dfield, siunit); q = pow10((gdouble)power10); gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield)); gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield)); g_object_unref(siunit); unit = ufile->unit_z; /* XXX: No fallback yet, just make z unitless */ siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); q = pow10((gdouble)power10); pmin = q*ufile->min_z; pmax = q*ufile->max_z; rmin = ufile->min_raw_z; rmax = ufile->max_raw_z; gwy_data_field_multiply(dfield, (pmax - pmin)/(rmax - rmin)); gwy_data_field_add(dfield, (pmin*rmax - pmax*rmin)/(rmax - rmin)); g_object_unref(siunit); return dfield; }
static GwyDataField* hash_to_data_field(GHashTable *hash, GHashTable *scannerlist, GHashTable *scanlist, NanoscopeFileType file_type, gboolean has_version, guint bufsize, gchar *buffer, gint gxres, gint gyres, gchar **p, GError **error) { NanoscopeValue *val; GwyDataField *dfield; GwySIUnit *unitz, *unitxy; gchar *s, *end; gchar un[5]; gint xres, yres, bpp, offset, size, power10; gdouble xreal, yreal, q; gdouble *data; gboolean size_ok, use_global; if (!require_keys(hash, error, "Samps/line", "Number of lines", "Scan size", "Data offset", "Data length", NULL)) return NULL; val = g_hash_table_lookup(hash, "Samps/line"); xres = GWY_ROUND(val->hard_value); val = g_hash_table_lookup(hash, "Number of lines"); yres = GWY_ROUND(val->hard_value); val = g_hash_table_lookup(hash, "Bytes/pixel"); bpp = val ? GWY_ROUND(val->hard_value) : 2; /* scan size */ val = g_hash_table_lookup(hash, "Scan size"); xreal = g_ascii_strtod(val->hard_value_str, &end); if (errno || *end != ' ') { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Cannot parse `Scan size' field.")); return NULL; } gwy_debug("xreal = %g", xreal); s = end+1; yreal = g_ascii_strtod(s, &end); if (errno || *end != ' ') { /* Old files don't have two numbers here, assume equal dimensions */ yreal = xreal; end = s; } gwy_debug("yreal = %g", yreal); while (g_ascii_isspace(*end)) end++; if (sscanf(end, "%4s", un) != 1) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Cannot parse `Scan size' field.")); return NULL; } gwy_debug("xy unit: <%s>", un); unitxy = gwy_si_unit_new_parse(un, &power10); q = pow10(power10); xreal *= q; yreal *= q; offset = size = 0; if (file_type == NANOSCOPE_FILE_TYPE_BIN) { val = g_hash_table_lookup(hash, "Data offset"); offset = GWY_ROUND(val->hard_value); val = g_hash_table_lookup(hash, "Data length"); size = GWY_ROUND(val->hard_value); size_ok = FALSE; use_global = FALSE; /* Try channel size and local size */ if (!size_ok && size == bpp*xres*yres) size_ok = TRUE; if (!size_ok && size == bpp*gxres*gyres) { size_ok = TRUE; use_global = TRUE; } /* If they don't match exactly, try whether they at least fit inside */ if (!size_ok && size > bpp*MAX(xres*yres, gxres*gyres)) { size_ok = TRUE; use_global = (xres*yres < gxres*gyres); } if (!size_ok && size > bpp*MIN(xres*yres, gxres*gyres)) { size_ok = TRUE; use_global = (xres*yres > gxres*gyres); } if (!size_ok) { err_SIZE_MISMATCH(error, size, bpp*xres*yres); return NULL; } if (use_global) { if (gxres) { xreal *= (gdouble)gxres/xres; xres = gxres; } if (gyres) { yreal *= (gdouble)gyres/yres; yres = gyres; } } if (offset + size > (gint)bufsize) { err_SIZE_MISMATCH(error, offset + size, bufsize); return NULL; } } q = 1.0; unitz = get_physical_scale(hash, scannerlist, scanlist, has_version, &q, error); if (!unitz) return NULL; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); data = gwy_data_field_get_data(dfield); switch (file_type) { case NANOSCOPE_FILE_TYPE_TXT: if (!read_ascii_data(xres*yres, data, p, bpp, error)) { g_object_unref(dfield); return NULL; } break; case NANOSCOPE_FILE_TYPE_BIN: if (!read_binary_data(xres*yres, data, buffer + offset, bpp, error)) { g_object_unref(dfield); return NULL; } break; default: g_assert_not_reached(); break; } gwy_data_field_multiply(dfield, q); gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); gwy_data_field_set_si_unit_z(dfield, unitz); g_object_unref(unitz); gwy_data_field_set_si_unit_xy(dfield, unitxy); g_object_unref(unitxy); return dfield; }
static void do_level(GwyContainer *data, GwyRunType run, LevelMethod level_type, const gchar *dialog_title) { GwyDataField *dfield; GwyDataField *mfield; LevelArgs args; gdouble c, bx, by; GQuark quark; gint id; g_return_if_fail(run & LEVEL_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &quark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield && quark); load_args(gwy_app_settings_get(), &args); if (run != GWY_RUN_IMMEDIATE && mfield) { gboolean ok = level_dialog(&args, dialog_title); save_args(gwy_app_settings_get(), &args); if (!ok) return; } if (args.masking == GWY_MASK_IGNORE) mfield = NULL; if (mfield) { if (args.masking == GWY_MASK_EXCLUDE) { mfield = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(mfield, -1.0); gwy_data_field_add(mfield, 1.0); } else g_object_ref(mfield); } gwy_app_undo_qcheckpoint(data, quark, NULL); if (mfield) gwy_data_field_area_fit_plane(dfield, mfield, 0, 0, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), &c, &bx, &by); else gwy_data_field_fit_plane(dfield, &c, &bx, &by); switch (level_type) { case LEVEL_SUBTRACT: c = -0.5*(bx*gwy_data_field_get_xres(dfield) + by*gwy_data_field_get_yres(dfield)); gwy_data_field_plane_level(dfield, c, bx, by); break; case LEVEL_ROTATE: bx = gwy_data_field_rtoj(dfield, bx); by = gwy_data_field_rtoi(dfield, by); gwy_data_field_plane_rotate(dfield, atan2(bx, 1), atan2(by, 1), GWY_INTERPOLATION_LINEAR); gwy_debug("b = %g, alpha = %g deg, c = %g, beta = %g deg", bx, 180/G_PI*atan2(bx, 1), by, 180/G_PI*atan2(by, 1)); break; default: g_assert_not_reached(); break; } gwy_app_channel_log_add_proc(data, id, id); gwy_data_field_data_changed(dfield); gwy_object_unref(mfield); }
static void sphrev(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *background = NULL; Sphrev1DArgs args; gint oldid, newid; GQuark dquark; gdouble xr, yr; gboolean ok = TRUE; g_return_if_fail(run & SPHREV_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield && dquark); sphrev_load_args(gwy_app_settings_get(), &args); /* FIXME: this is bogus for non-square pixels anyway */ xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield); yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield); args.pixelsize = hypot(xr, yr); args.valform = gwy_data_field_get_value_format_xy(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); gwy_debug("pixelsize = %g, vf = (%g, %d, %s)", args.pixelsize, args.valform->magnitude, args.valform->precision, args.valform->units); if (run == GWY_RUN_INTERACTIVE) { ok = sphrev_dialog(&args); sphrev_save_args(gwy_app_settings_get(), &args); } gwy_si_unit_value_format_free(args.valform); if (!ok) return; gwy_app_undo_qcheckpointv(data, 1, &dquark); switch (args.direction) { case SPHREV_HORIZONTAL: background = sphrev_horizontal(&args, dfield); break; case SPHREV_VERTICAL: background = sphrev_vertical(&args, dfield); break; case SPHREV_BOTH: { GwyDataField *tmp; background = sphrev_horizontal(&args, dfield); tmp = sphrev_vertical(&args, dfield); gwy_data_field_sum_fields(background, background, tmp); g_object_unref(tmp); gwy_data_field_multiply(background, 0.5); } break; default: g_assert_not_reached(); break; } gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (!args.do_extract) { g_object_unref(background); return; } newid = gwy_app_data_browser_add_data_field(background, data, TRUE); g_object_unref(background); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); }
static GwyContainer* gxsm_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const gchar *dimensions[] = { "time", "value", "dimy", "dimx" }; GwyContainer *data = NULL; GwyDataField *dfield; GwySIUnit *siunit; NetCDF cdffile; const NetCDFDim *dim; const NetCDFVar *var; const NetCDFAttr *attr; gdouble real; gint i, power10; if (!cdffile_load(&cdffile, filename, error)) return NULL; if (cdffile.nrecs) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("NetCDF records are not supported.")); goto gxsm_load_fail; } /* Look for variable "H" or "FloatField". This seems to be how GXSM calls * data. */ if (!(var = cdffile_get_var(&cdffile, "H")) && !(var = cdffile_get_var(&cdffile, "FloatField"))) { err_NO_DATA(error); goto gxsm_load_fail; } /* Check the dimensions. We only know how to handle time=1 and value=1. */ for (i = 0; i < var->ndims; i++) { dim = cdffile.dims + var->dimids[i]; if (!gwy_strequal(dim->name, dimensions[i]) || (i < 2 && dim->length != 1)) { /* XXX */ err_NO_DATA(error); goto gxsm_load_fail; } } if (err_DIMENSION(error, cdffile.dims[var->dimids[3]].length) || err_DIMENSION(error, cdffile.dims[var->dimids[2]].length)) goto gxsm_load_fail; dfield = read_data_field((const guchar*)(cdffile.buffer + var->begin), cdffile.dims[var->dimids[3]].length, cdffile.dims[var->dimids[2]].length, var->type); if ((siunit = read_real_size(&cdffile, "rangex", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_xreal(dfield, real*pow10(power10)); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangey", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_yreal(dfield, real*pow10(power10)); /* must be the same gwy_data_field_set_si_unit_xy(dfield, siunit); */ g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangez", &real, &power10))) { /* rangez seems to be some bogus value, take only units */ gwy_data_field_set_si_unit_z(dfield, siunit); gwy_data_field_multiply(dfield, pow10(power10)); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "dz", &real, &power10))) { /* on the other hand the units seem to be bogus here, take the range */ gwy_data_field_multiply(dfield, real); g_object_unref(siunit); } data = gwy_container_new(); gwy_container_set_object_by_name(data, "/0/data", dfield); g_object_unref(dfield); if ((attr = cdffile_get_attr(var->attrs, var->nattrs, "long_name")) && attr->type == NC_CHAR && attr->nelems) { gwy_container_set_string_by_name(data, "/0/data/title", g_strndup(attr->values, attr->nelems)); } gxsm_load_fail: gwy_file_abandon_contents(cdffile.buffer, cdffile.size, NULL); cdffile_free(&cdffile); return data; }