static GwyContainer* x3p_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; X3PFile x3pfile; unzFile zipfile; zipfile = gwyminizip_unzOpen(filename); if (!zipfile) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_SPECIFIC, _("Minizip cannot open the file as a ZIP file.")); return NULL; } gwy_clear(&x3pfile, 1); if (!x3p_parse_main(zipfile, &x3pfile, error)) goto fail; if (!x3pfile.ndata) { err_NO_DATA(error); goto fail; } if (!x3pfile.datapos) { if (!read_binary_data(&x3pfile, zipfile, error)) goto fail; } container = gwy_container_new(); if (x3pfile.feature_type == X3P_FEATURE_SUR) create_images(&x3pfile, container); else if (x3pfile.feature_type == X3P_FEATURE_PRF) create_profiles(&x3pfile, container); else { g_assert_not_reached(); } fail: gwy_debug("calling unzClose()"); unzClose(zipfile); x3p_file_free(&x3pfile); return container; }
static GwyContainer* shimadzu_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; GwyDataField *dfield = NULL; GError *err = NULL; gchar *buffer = NULL; GHashTable *hash; gchar *head; gsize size = 0; gboolean ok; gint text_data_start; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE + 2) { err_TOO_SHORT(error); return NULL; } if (memcmp(buffer, MAGIC, MAGIC_SIZE) != 0 && !(memcmp(buffer, MAGIC_ASCII, MAGIC_ASCII_SIZE) == 0 && (memcmp(buffer + MAGIC_ASCII_SIZE+1, MAGIC, MAGIC_SIZE) == 0 || memcmp(buffer + MAGIC_ASCII_SIZE+2, MAGIC, MAGIC_SIZE) == 0))) { err_FILE_TYPE(error, "Shimadzu"); g_free(buffer); return NULL; } head = g_memdup(buffer, HEADER_SIZE+1); head[HEADER_SIZE] = '\0'; /* text_data_start is set to nonzero if data are text */ hash = read_hash(head, &text_data_start, error); ok = !!hash; if (ok) { if (text_data_start) dfield = read_text_data(buffer, text_data_start, hash, error); else dfield = read_binary_data(buffer, size, hash, error); ok = !!dfield; } if (ok) { GQuark quark; const gchar *title; container = gwy_container_new(); quark = gwy_app_get_data_key_for_id(0); gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); meta = shimadzu_get_metadata(hash); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); title = g_hash_table_lookup(hash, "Channel"); if (title && *title) gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); else gwy_app_channel_title_fall_back(container, 0); gwy_file_channel_import_log_add(container, 0, NULL, filename); } g_free(head); g_free(buffer); g_hash_table_destroy(hash); return container; }
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 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; }