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