static GwyContainer* spmlab_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; const gchar *title; gint type; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } /* 2048 is wrong. moreover it differs for r5 and r4, kasigra uses 5752 for * r5 */ if (size < 2048) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (buffer[0] != '#' || buffer[1] != 'R') { err_FILE_TYPE(error, "Thermicroscopes SpmLab"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } switch (buffer[2]) { case '3': case '4': case '5': case '6': dfield = read_data_field(buffer, size, buffer[2], &type, error); break; default: g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Unknown format version %c."), buffer[2]); break; } gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) return NULL; container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); title = gwy_enum_to_string(type, spmlab_channel_types, G_N_ELEMENTS(spmlab_channel_types)); if (*title) gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); return container; }
static GwyContainer* rhk_sm3_load(const gchar *filename) { GPtrArray *rhkfile; RHKPage *rhkpage; GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; const guchar *p; guint i, count; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_warning("Cannot read file %s", filename); g_clear_error(&err); return NULL; } if (size < HEADER_SIZE) { g_warning("File %s is not a RHK SM3 file", filename); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } rhkfile = g_ptr_array_new(); p = buffer; count = 0; gwy_debug("position %04x", p - buffer); while ((rhkpage = rhk_sm3_read_page(&p, &size))) { gwy_debug("Page #%u read OK", count); count++; rhkpage->pageno = count; gwy_debug("position %04x", p - buffer); if (rhkpage->type != RHK_TYPE_IMAGE) { gwy_debug("Page is not IMAGE, skipping"); rhk_sm3_page_free(rhkpage); continue; } g_ptr_array_add(rhkfile, rhkpage); } i = select_which_data(rhkfile); if (i != (guint)-1) { rhkpage = g_ptr_array_index(rhkfile, i); container = GWY_CONTAINER(gwy_container_new()); dfield = rhk_sm3_page_to_data_field(rhkpage); gwy_container_set_object_by_name(container, "/0/data", (GObject*)dfield); g_object_unref(dfield); rhk_sm3_store_metadata(rhkpage, container); } gwy_file_abandon_contents(buffer, size, NULL); for (i = 0; i < rhkfile->len; i++) rhk_sm3_page_free(g_ptr_array_index(rhkfile, i)); g_ptr_array_free(rhkfile, TRUE); return container; }
static GwyContainer* hitachi_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error, const gchar *name) { GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; GwyDataField *(*do_load)(const guchar*, guint, GError**); guint header_size; if (gwy_strequal(name, "hitachi-afm")) { do_load = &read_data_field; header_size = HEADER_SIZE; } else if (gwy_strequal(name, "hitachi-afm-old")) { do_load = &read_data_field_old; header_size = HEADER_SIZE_OLD; } else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_UNIMPLEMENTED, _("Hitachi-AFM has not registered file type `%s'."), name); return NULL; } if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < header_size + 2) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } dfield = do_load(buffer, size, error); gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) return NULL; 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("Topography")); gwy_app_channel_check_nonsquare(container, 0); gwy_file_channel_import_log_add(container, 0, NULL, filename); return container; }
static GwyContainer* gwyfile_load(const gchar *filename) { GObject *object, *dfield; GError *err = NULL; guchar *buffer = NULL; gsize size = 0; gsize pos = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_warning("Cannot read file %s", filename); g_clear_error(&err); return NULL; } if (size < MAGIC_SIZE || (memcmp(buffer, MAGIC, MAGIC_SIZE) && memcmp(buffer, MAGIC2, MAGIC_SIZE))) { g_warning("File %s doesn't seem to be a .gwy file", filename); if (!gwy_file_abandon_contents(buffer, size, &err)) { g_critical("%s", err->message); g_clear_error(&err); } return NULL; } if (!memcmp(buffer, MAGIC, MAGIC_SIZE)) object = gwy_serializable_deserialize(buffer + MAGIC_SIZE, size - MAGIC_SIZE, &pos); else object = gwy_container_deserialize2(buffer + MAGIC_SIZE, size - MAGIC_SIZE, &pos); if (!gwy_file_abandon_contents(buffer, size, &err)) { g_critical("%s", err->message); g_clear_error(&err); } if (!object) { g_warning("File %s deserialization failed", filename); return NULL; } if (!GWY_IS_CONTAINER(object)) { g_warning("File %s contains some strange object", filename); g_object_unref(object); return NULL; } dfield = gwy_container_get_object_by_name(GWY_CONTAINER(object), "/0/data"); if (!dfield || !GWY_IS_DATA_FIELD(dfield)) { g_warning("File %s contains no data field", filename); g_object_unref(object); return NULL; } return (GwyContainer*)object; }
static GwyContainer* gwyfile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GObject *object; GError *err = NULL; guchar *buffer = NULL; gsize size = 0; gsize pos = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < MAGIC_SIZE || (memcmp(buffer, MAGIC, MAGIC_SIZE) && memcmp(buffer, MAGIC2, MAGIC_SIZE))) { err_FILE_TYPE(error, "Gwyddion"); gwy_file_abandon_contents(buffer, size, &err); return NULL; } if (!memcmp(buffer, MAGIC, MAGIC_SIZE)) { object = gwy_container_deserialize_old(buffer + MAGIC_SIZE, size - MAGIC_SIZE, &pos); gwyfile_remove_old_data(object); } else object = gwy_serializable_deserialize(buffer + MAGIC_SIZE, size - MAGIC_SIZE, &pos); gwy_file_abandon_contents(buffer, size, &err); if (!object) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Data deserialization failed.")); return NULL; } if (!GWY_IS_CONTAINER(object)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Data deserialization succeeded, but resulted in " "an unexpected object %s."), g_type_name(G_TYPE_FROM_INSTANCE(object))); g_object_unref(object); return NULL; } gwyfile_pack_metadata(GWY_CONTAINER(object)); return GWY_CONTAINER(object); }
static GwyContainer* aist_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { AistContext context; guchar *buffer = NULL; const guchar *p; gsize remaining, size = 0; GError *err = NULL; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = buffer; remaining = size; context.container = gwy_container_new(); context.filename = filename; context.channel_id = 0; context.graph_id = 0; read_aist_tree(&p, &remaining, &context); gwy_file_abandon_contents(buffer, size, NULL); if ((context.channel_id == 0) && (context.graph_id == 0)) { g_object_unref(context.container); context.container = NULL; err_NO_DATA(error); } return context.container; }
static GwyContainer* sdfile_load_bin(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SDFile sdfile; GwyContainer *container = NULL; guchar *buffer = NULL; const guchar *p; gsize len, size = 0; GError *err = NULL; GwyDataField *dfield = NULL; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } len = size; p = buffer; if (sdfile_read_header_bin(&p, &len, &sdfile, error)) { if (check_params(&sdfile, len, error)) dfield = sdfile_read_data_bin(&sdfile); } gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) return NULL; sdfile_set_units(&sdfile, dfield); 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("Topography")); return container; }
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* burleigh_load(const gchar *filename) { 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 scale; guint i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_warning("Cannot get file contents"); g_clear_error(&err); return NULL; } if (size < HEADER_SIZE_MIN + 2) { g_warning("File is too short"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } memset(&imgfile, 0, sizeof(imgfile)); p = buffer; imgfile.version = get_FLOAT(&p); imgfile.version_int = ROUND(10*imgfile.version); if (imgfile.version_int == 21) { d = burleigh_load_v21(&imgfile, buffer, size); if (!d) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } else { g_warning("File format version %.f is not supported", imgfile.version); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } dfield = GWY_DATA_FIELD(gwy_data_field_new(imgfile.xres, imgfile.yres, Angstrom*imgfile.xrange, Angstrom*imgfile.yrange, FALSE)); data = gwy_data_field_get_data(dfield); scale = Angstrom * imgfile.z_gain * imgfile.zrange; for (i = 0; i < imgfile.xres*imgfile.yres; i++) data[i] = scale * GINT16_FROM_LE(d[i]); gwy_file_abandon_contents(buffer, size, NULL); unit = GWY_SI_UNIT(gwy_si_unit_new("m")); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); container = GWY_CONTAINER(gwy_container_new()); switch (imgfile.data_type) { case BURLEIGH_CURRENT: unit = GWY_SI_UNIT(gwy_si_unit_new("A")); gwy_container_set_string_by_name(container, "/filename/title", g_strdup("Current")); break; case BURLEIGH_TOPOGRAPHY: unit = GWY_SI_UNIT(gwy_si_unit_new("m")); gwy_container_set_string_by_name(container, "/filename/title", g_strdup("Topography")); break; default: unit = GWY_SI_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", (GObject*)dfield); g_object_unref(dfield); return container; }
static GwyContainer* ezdfile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; EZDSection *section = NULL; GwyDataField *dfield = NULL; GPtrArray *ezdfile; guint header_size, n; gint i; gchar *p; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (strncmp(buffer, MAGIC, MAGIC_SIZE) || !(header_size = find_data_start(buffer, size))) { err_FILE_TYPE(error, "EZD/NID"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } ezdfile = g_ptr_array_new(); p = g_strndup(buffer, header_size - DATA_MAGIC_SIZE); if (!file_read_header(ezdfile, p, error)) { gwy_file_abandon_contents(buffer, size, NULL); g_free(p); return NULL; } g_free(p); n = find_data_offsets(buffer + header_size, size - header_size, ezdfile, error); if (!n) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); i = 0; for (n = 0; n < ezdfile->len; n++) { gchar key[24]; section = (EZDSection*)g_ptr_array_index(ezdfile, n); if (!section->data) continue; dfield = gwy_data_field_new(section->xres, section->yres, 1.0, 1.0, FALSE); read_data_field(dfield, section); g_snprintf(key, sizeof(key), "/%d/data", i); gwy_container_set_object_by_name(container, key, dfield); g_object_unref(dfield); fix_scales(section, i, container); meta = ezdfile_get_metadata(ezdfile, n); if (meta) { g_snprintf(key, sizeof(key), "/%d/meta", i); gwy_container_set_object_by_name(container, key, meta); g_object_unref(meta); } i++; } gwy_file_abandon_contents(buffer, size, NULL); ezdfile_free(ezdfile); return container; }
static GwyContainer* rhk_sm4_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { RHKFile rhkfile; RHKObject *obj, o; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; GString *key = NULL; guint i, imageid = 0, graphid = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&rhkfile, 1); if (size < HEADER_SIZE) { err_TOO_SHORT(error); goto fail; } /* File header */ p = buffer + MAGIC_OFFSET + MAGIC_TOTAL_SIZE; rhkfile.page_count = gwy_get_guint32_le(&p); rhkfile.object_count = gwy_get_guint32_le(&p); rhkfile.object_field_size = gwy_get_guint32_le(&p); gwy_debug("page_count: %u, object_count: %u, object_field_size: %u", rhkfile.page_count, rhkfile.object_count, rhkfile.object_field_size); if (rhkfile.object_field_size != OBJECT_SIZE) g_warning("Object field size %u differs from %u", rhkfile.object_field_size, OBJECT_SIZE); rhkfile.reserved1 = gwy_get_guint32_le(&p); rhkfile.reserved2 = gwy_get_guint32_le(&p); /* Header objects */ if (!(rhkfile.objects = rhk_sm4_read_objects(buffer, p, size, rhkfile.object_count, RHK_OBJECT_FILE_HEADER, error))) goto fail; /* Find page index header */ if (!(obj = rhk_sm4_find_object(rhkfile.objects, rhkfile.object_count, RHK_OBJECT_PAGE_INDEX_HEADER, RHK_OBJECT_FILE_HEADER, error)) || !rhk_sm4_read_page_index_header(&rhkfile.page_index_header, obj, buffer, size, error)) goto fail; /* There, find the page index array. That's a single object in the object * list but it contains a page_count-long sequence of page indices. */ rhkfile.page_indices = g_new0(RHKPageIndex, rhkfile.page_index_header.page_count); if (!(obj = rhk_sm4_find_object(rhkfile.page_index_header.objects, rhkfile.page_index_header.object_count, RHK_OBJECT_PAGE_INDEX_ARRAY, RHK_OBJECT_PAGE_INDEX_HEADER, error))) goto fail; o = *obj; for (i = 0; i < rhkfile.page_index_header.page_count; i++) { if (!rhk_sm4_read_page_index(rhkfile.page_indices + i, &o, buffer, size, error)) goto fail; /* Carefully move to the next page index */ o.offset += o.size + OBJECT_SIZE*rhkfile.page_indices[i].object_count; } container = gwy_container_new(); key = g_string_new(NULL); /* Read pages */ for (i = 0; i < rhkfile.page_index_header.page_count; i++) { RHKPageIndex *pi = rhkfile.page_indices + i; RHKPage *page = &pi->page; /* Page must contain header */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_HEADER, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_header(page, obj, buffer, size, error)) goto fail; /* Page must contain data */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_DATA, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_data(page, obj, buffer, error)) goto fail; /* Page may contain strings */ if (!(obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_STRING_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) || !rhk_sm4_read_string_data(page, obj, pi->page.string_count, buffer)) { g_warning("Failed to read string data in page %u", i); } /* Read the data */ if (pi->data_type == RHK_DATA_IMAGE) { GwyDataField *dfield = rhk_sm4_page_to_data_field(page); GQuark quark = gwy_app_get_data_key_for_id(imageid); const gchar *scandir, *name; gchar *title; gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); if ((name = page->strings[RHK_STRING_LABEL])) { scandir = gwy_enum_to_string(page->scan_dir, scan_directions, G_N_ELEMENTS(scan_directions)); g_string_assign(key, g_quark_to_string(quark)); g_string_append(key, "/title"); if (scandir && *scandir) title = g_strdup_printf("%s [%s]", name, scandir); else title = g_strdup(name); gwy_container_set_string_by_name(container, key->str, title); } meta = rhk_sm4_get_metadata(pi, page); g_string_printf(key, "/%u/meta", imageid); gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); imageid++; } else if (pi->data_type == RHK_DATA_LINE) { GwyGraphModel *gmodel; RHKSpecDriftHeader drift_header; RHKSpecInfo spec_info; G_GNUC_UNUSED gboolean have_header = FALSE, have_info = FALSE; gwy_debug("page_type %u", page->page_type); gwy_debug("line_type %u", page->line_type); gwy_debug("page_sizes %u %u", page->x_size, page->y_size); /* Page may contain drift header */ if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_HEADER, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_drift_header(&drift_header, obj, buffer)) { gwy_debug("drift_header OK"); have_header = TRUE; } if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_spec_info(&spec_info, obj, buffer)) { gwy_debug("spec_info OK"); have_info = TRUE; } /* FIXME: RHK_STRING_PLL_PRO_STATUS may contain interesting * metadata. But we have not place where to put it. */ if ((gmodel = rhk_sm4_page_to_graph_model(page))) { graphid++; gwy_container_set_object(container, gwy_app_get_graph_key_for_id(graphid), gmodel); g_object_unref(gmodel); } } } if (!imageid && !graphid) err_NO_DATA(error); fail: gwy_file_abandon_contents(buffer, size, NULL); rhk_sm4_free(&rhkfile); if (!imageid && !graphid) { gwy_object_unref(container); } if (key) g_string_free(key, TRUE); return container; }
static GwyContainer* mif_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; MIFFile mfile; GwyDataField *dfield; guint i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (!mif_read_header(buffer, size, &mfile.header, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* TODO: Check file version */ if (!mif_read_image_items(mfile.images, buffer, size, &mfile.header.info, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* FIXME: Only v1.7! */ for (i = 0; i < mfile.header.nimages; i++) { MIFInfoItem *item = mfile.images + i; MIFImageHeader image_header; MIFBlock raster, macro_geometry, preview, image, curve, calc; guint ncalculations; const guchar *p = buffer + item->image.offset; GQuark quark; if (!item->image.size) continue; if (item->image.offset > size || item->image.size > size || item->image.offset + item->image.size > size) { continue; } /* XXX: We cannot use item->image.size because it's bogus, i.e. * too short. Apparently there is some unaccounted-for space until * the next block starts, 120 bytes for v1.7 files, after the image * header which is in fact still occupied by the image header. * MIFBlock says 714 bytes but the true size is 834 = 714 + 120. */ if (!mif_read_image_header(&image_header, &p, size - (p - buffer), mfile.header.file_version, error)) continue; if (p - buffer + 52 > size) continue; mif_read_block(&raster, "raster", &p); mif_read_block(¯o_geometry, "macro_geometry", &p); mif_read_block(&preview, "preview", &p); mif_read_block(&image, "image", &p); mif_read_block(&curve, "curve", &p); ncalculations = gwy_get_guint32_le(&p); mif_read_block(&calc, "calc", &p); gwy_debug("image header true size: %zu", (gsize)(p - (buffer + item->image.offset))); dfield = mif_read_data_field(&image_header, &image, buffer, size, NULL); if (!dfield) continue; if (!container) container = gwy_container_new(); quark = gwy_app_get_data_key_for_id(i); gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); gwy_app_channel_title_fall_back(container, i); } if (!container) err_NO_DATA(error); gwy_file_abandon_contents(buffer, size, NULL); return container; }
static GwyContainer* jeol_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { JEOLImageHeader image_header; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize expected_size, size = 0; GError *err = NULL; GwyDataField *dfield = NULL; const gchar *title; gchar *s; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < JEOL_DATA_START) { err_TOO_SHORT(error); goto fail; } if (memcmp(buffer, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "JEOL"); goto fail; } jeol_read_image_header(buffer, &image_header); /* Elementrary sanity */ if (image_header.bpp != 16) { err_BPP(error, image_header.bpp); goto fail; } if (err_DIMENSION(error, image_header.xres) || err_DIMENSION(error, image_header.yres)) goto fail; expected_size = image_header.bpp/8 * image_header.xres*image_header.yres; if (err_SIZE_MISMATCH(error, JEOL_DATA_START + expected_size, size, FALSE)) goto fail; if (image_header.image_type != JEOL_IMAGE || image_header.compressed) { err_NO_DATA(error); goto fail; } /* Use negated positive conditions to catch NaNs */ if (!((image_header.xreal = fabs(image_header.xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); image_header.xreal = 1.0; } if (!((image_header.yreal = fabs(image_header.yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); image_header.yreal = 1.0; } dfield = jeol_read_data_field(buffer + JEOL_DATA_START, &image_header); if (!dfield) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("The type of data is unknown. " "Please report it to the developers.")); goto fail; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); /* Title */ s = g_convert(image_header.internal_filename, -1, "iso-8859-1", "utf-8", NULL, NULL, NULL); if (s) g_strstrip(s); if (s && *s) gwy_container_set_string_by_name(container, "/0/data/title", s); else { title = gwy_flat_enum_to_string(image_header.data_source, G_N_ELEMENTS(data_sources), data_sources, data_sources_name); if (title) gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); } /* Meta */ meta = jeol_get_metadata(&image_header); 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_file_abandon_contents(buffer, size, NULL); return container; }
static GwyContainer* stmprg_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; StmprgFile stmprgfile; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield; char *filename_ta, *ptr; gboolean ok; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < MAGIC_SIZE || memcmp(buffer, MAGIC_TXT, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "Omicron STMPRG"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } gwy_clear(&stmprgfile, 1); ok = read_parameters(buffer, size, &stmprgfile, error); gwy_file_abandon_contents(buffer, size, NULL); if (!ok) return NULL; filename_ta = g_strdup(filename); ptr = filename_ta + strlen(filename_ta) - 1; while (g_ascii_isdigit(*ptr) && ptr > filename_ta+1) ptr--; if (ptr == filename_ta+1) { err_DATA_PART(error, filename); g_free(filename_ta); return NULL; } /* Accept lowercase and uppercase and try the same case for data file */ if (*ptr == 'p' && *(ptr - 1) == 't') *ptr = 'a'; if (*ptr == 'P' && *(ptr - 1) == 'T') *ptr = 'A'; if (!gwy_file_get_contents(filename_ta, &buffer, &size, &err)) { g_free(filename_ta); err_GET_FILE_CONTENTS(error, &err); return NULL; } g_free(filename_ta); dfield = read_datafield(buffer, size, &stmprgfile, error); if (dfield) { container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); /* FIXME: with documentation, we could perhaps do better */ gwy_app_channel_title_fall_back(container, 0); meta = stmprg_get_metadata(&stmprgfile); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); } gwy_file_abandon_contents(buffer, size, NULL); return container; }
static gboolean cdffile_load(NetCDF *cdffile, const gchar *filename, GError **error) { GError *err = NULL; const guchar *p; gwy_clear(cdffile, 1); if (!gwy_file_get_contents(filename, &cdffile->buffer, &cdffile->size, &err)) { err_GET_FILE_CONTENTS(error, &err); return FALSE; } if (cdffile->size < 32) { err_TOO_SHORT(error); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } p = cdffile->buffer; /* Header */ if (memcmp(p, MAGIC1, MAGIC_SIZE) == 0) cdffile->version = 1; else if (memcmp(p, MAGIC2, MAGIC_SIZE) == 0) cdffile->version = 2; else { err_FILE_TYPE(error, "NetCDF"); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } gwy_debug("Header: CDF v%d", (gint)cdffile->version); p += MAGIC_SIZE; /* N Records */ cdffile->nrecs = gwy_get_guint32_be(&p); gwy_debug("nrecs %d", cdffile->nrecs); /* Dimensions */ if (!cdffile_read_dim_array(&cdffile->dims, &cdffile->ndims, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } /* Global attributes */ if (!cdffile_read_attr_array(&cdffile->attrs, &cdffile->nattrs, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } /* Variables */ if (!cdffile_read_var_array(&cdffile->vars, &cdffile->nvars, cdffile->version, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } cdffile->data_start = (gsize)(p - cdffile->buffer); /* Sanity check */ if (!cdffile_validate_vars(cdffile, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } return TRUE; }
static GwyContainer* mprofile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { MProFile mprofile; GwyContainer *meta, *container = NULL; GwyDataField *dfield = NULL, *vpmask = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; gsize expected; GString *key; const gchar *title; guint n, i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (!mprofile_read_header(buffer, size, &mprofile, error)) return NULL; expected = mprofile.header_size + 2*mprofile.nbuckets*mprofile.intens_xres*mprofile.intens_yres + 4*mprofile.phase_xres*mprofile.phase_yres; if (err_SIZE_MISMATCH(error, expected, size, TRUE)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } n = fill_data_fields(&mprofile, buffer); gwy_file_abandon_contents(buffer, size, NULL); if (!n) { err_NO_DATA(error); return NULL; } key = g_string_new(NULL); container = gwy_container_new(); for (i = 0; i < n; i++) { if (i > 0) { dfield = mprofile.intensity_data[i-1]; vpmask = mprofile.intensity_mask[i-1]; title = "Intensity"; } else { dfield = mprofile.phase_data; vpmask = mprofile.phase_mask; title = "Phase"; } g_string_printf(key, "/%d/data", i); gwy_container_set_object_by_name(container, key->str, dfield); g_string_printf(key, "/%d/data/title", i); gwy_container_set_string_by_name(container, key->str, g_strdup(title)); if (vpmask) { g_string_printf(key, "/%d/mask", i); gwy_container_set_object_by_name(container, key->str, vpmask); } meta = mprofile_get_metadata(&mprofile); g_string_printf(key, "/%d/meta", i); gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); } g_string_free(key, TRUE); for (n = 0; n < mprofile.nbuckets; n++) { gwy_object_unref(mprofile.intensity_data[n]); gwy_object_unref(mprofile.intensity_mask[n]); } gwy_object_unref(mprofile.phase_data); gwy_object_unref(mprofile.phase_mask); return container; }
static GwyContainer* rhkspm32_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GArray *rhkfile; RHKPage *rhkpage; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gsize totalpos, pagesize; GString *key; guint i; 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); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } // niv - rhkfile is an array of rhkpage's, but buffer is where the actual // raw file data is stored rhkfile = g_array_new(FALSE, TRUE, sizeof(RHKPage)); totalpos = 0; while (totalpos < size) { g_array_set_size(rhkfile, rhkfile->len + 1); rhkpage = &g_array_index(rhkfile, RHKPage, rhkfile->len - 1); rhkpage->buffer = buffer + totalpos; // niv - if the header seems illegal, skip all the next ones as well // (and cancel the element addition to the g_array) if (!rhkspm32_read_header(rhkpage, &err)) { g_warning("failed to read rhk header after %u", rhkfile->len); g_array_set_size(rhkfile, rhkfile->len - 1); break; } pagesize = rhkpage->data_offset + rhkpage->item_size*rhkpage->xres*rhkpage->yres; if (size < totalpos + pagesize) { rhkspm32_free(rhkpage); g_array_set_size(rhkfile, rhkfile->len - 1); break; } totalpos += pagesize; } /* Be tolerant and don't fail when we were able to import at least * something */ if (!rhkfile->len) { if (err) g_propagate_error(error, err); else err_NO_DATA(error); gwy_file_abandon_contents(buffer, size, NULL); g_array_free(rhkfile, TRUE); return NULL; } g_clear_error(&err); container = gwy_container_new(); key = g_string_new(NULL); for (i = 0; i < rhkfile->len; i++) { const gchar *cs; gchar *s; gwy_debug("rhk-spm32: processing page %d of %d\n", i+1, rhkfile->len); rhkpage = &g_array_index(rhkfile, RHKPage, i); if (rhkpage->type == RHK_TYPE_IMAGE) { // niv - just leaving this alone dfield = rhkspm32_read_data(rhkpage); g_string_printf(key, "/%d/data", i); gwy_container_set_object_by_name(container, key->str, dfield); g_object_unref(dfield); g_string_append(key, "/title"); cs = gwy_enum_to_string(rhkpage->scan, scan_directions, G_N_ELEMENTS(scan_directions)); if (rhkpage->label) { if (cs) s = g_strdup_printf("%s [%s]", rhkpage->label, cs); else s = g_strdup(rhkpage->label); gwy_container_set_string_by_name(container, key->str, s); } else gwy_app_channel_title_fall_back(container, i); gwy_file_channel_import_log_add(container, i, NULL, filename); } else if (rhkpage->type == RHK_TYPE_LINE) { // niv - after omicron.c GwySpectra* spectra; GwyGraphModel *gmodel; spectra = rhkspm32_read_spectra(rhkpage); /* converting to graphs, as there is no point in leaving these as * sps - no xy coordinates, so the spectro tool is kinda clueless */ gwy_debug("processing graph in page %d\n", i); if ((gmodel = spectra_to_graph(spectra)) != NULL) { gchar *container_key = NULL; /* add gmodel to container */ container_key = g_strdup_printf("%s/%d", GRAPH_PREFIX, i); gwy_container_set_object_by_name(container, container_key, gmodel); g_free(container_key); } g_object_unref(gmodel); g_object_unref(spectra); } gwy_debug("rhk-spm32: finished parsing page %d \n", i); meta = rhkspm32_get_metadata(rhkpage); if (rhkpage->type == RHK_TYPE_IMAGE) { /* this doesn't really work, but at least the meta data stays with the graph, even if the metadata viewer won't show it*/ g_string_printf(key, "/%d/meta", i); } else if (rhkpage->type == RHK_TYPE_LINE) { g_string_printf(key, "%s/%d/meta", GRAPH_PREFIX, i); } gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); } g_string_free(key, TRUE); gwy_file_abandon_contents(buffer, size, NULL); for (i = 0; i < rhkfile->len; i++) rhkspm32_free(&g_array_index(rhkfile, RHKPage, i)); g_array_free(rhkfile, TRUE); return container; }
static GwyContainer* apefile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { APEFile apefile; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; guint b, i, n; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = buffer; apefile.version = *(p++); if (size < 1294) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } apefile.spm_mode = *(p++); p += 2; /* Skip VisualBasic VARIANT type type */ apefile.scan_date = gwy_get_gdouble_le(&p); apefile.maxr_x = gwy_get_gfloat_le(&p); apefile.maxr_y = gwy_get_gfloat_le(&p); apefile.x_offset = gwy_get_guint32_le(&p); apefile.y_offset = gwy_get_guint32_le(&p); apefile.size_flag = gwy_get_guint16_le(&p); apefile.res = 16 << apefile.size_flag; if (err_DIMENSION(error, apefile.res)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } apefile.acquire_delay = gwy_get_gfloat_le(&p); apefile.raster_delay = gwy_get_gfloat_le(&p); apefile.tip_dist = gwy_get_gfloat_le(&p); apefile.v_ref = gwy_get_gfloat_le(&p); if (apefile.version == 1) { apefile.vpmt1 = gwy_get_guint16_le(&p); apefile.vpmt2 = gwy_get_guint16_le(&p); } else { apefile.vpmt1 = gwy_get_gfloat_le(&p); apefile.vpmt2 = gwy_get_gfloat_le(&p); } apefile.remark = g_strndup(p, 120); p += 120; apefile.x_piezo_factor = gwy_get_guint32_le(&p); apefile.y_piezo_factor = gwy_get_guint32_le(&p); apefile.z_piezo_factor = gwy_get_guint32_le(&p); apefile.hv_gain = gwy_get_gfloat_le(&p); apefile.freq_osc_tip = gwy_get_gdouble_le(&p); apefile.rotate = gwy_get_gfloat_le(&p); apefile.slope_x = gwy_get_gfloat_le(&p); apefile.slope_y = gwy_get_gfloat_le(&p); apefile.topo_means = gwy_get_guint16_le(&p); apefile.optical_means = gwy_get_guint16_le(&p); apefile.error_means = gwy_get_guint16_le(&p); /* g_printerr("%04x %04x %04x\n", apefile.topo_means, apefile.optical_means, apefile.error_means); */ apefile.channels = gwy_get_guint32_le(&p); apefile.ndata = 0; for (b = apefile.channels; b; b = b >> 1) apefile.ndata += (b & 1); apefile.range_x = gwy_get_gfloat_le(&p); apefile.range_y = gwy_get_gfloat_le(&p); apefile.subversion = gwy_get_guint16_le(&p); /* Read everything since the header is long enough, check the version * later when we decide whether to use these values or not. */ /* Since 2.1 */ apefile.hv_gain_z = gwy_get_gfloat_le(&p); /* Since 2.2 */ apefile.fast2_0 = gwy_get_gdouble_le(&p); apefile.fast2_1 = gwy_get_gdouble_le(&p); apefile.fast2_2 = gwy_get_gdouble_le(&p); apefile.fast2_3 = gwy_get_gdouble_le(&p); /* Since 2.3 */ apefile.pg850_image = !!gwy_get_guint16_le(&p); /* Since 2.4 */ apefile.xy_hv_status = gwy_get_gint16_le(&p); apefile.z_hv_status = gwy_get_gint16_le(&p); /* reserved */ p += 2; apefile.xreal = apefile.maxr_x * apefile.x_piezo_factor * apefile.range_x * apefile.hv_gain/65535.0 * 1e-9; apefile.yreal = apefile.maxr_y * apefile.y_piezo_factor * apefile.range_y * apefile.hv_gain/65535.0 * 1e-9; /* Use negated positive conditions to catch NaNs */ if (!((apefile.xreal = fabs(apefile.xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); apefile.xreal = 1.0; } if (!((apefile.yreal = fabs(apefile.yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); apefile.yreal = 1.0; } gwy_debug("version = %u.%u, spm_mode = %u", apefile.version, apefile.subversion, apefile.spm_mode); gwy_debug("scan_date = %f", apefile.scan_date); gwy_debug("maxr_x = %g, maxr_y = %g", apefile.maxr_x, apefile.maxr_y); gwy_debug("x_offset = %u, y_offset = %u", apefile.x_offset, apefile.y_offset); gwy_debug("size_flag = %u", apefile.size_flag); gwy_debug("acquire_delay = %g, raster_delay = %g, tip_dist = %g", apefile.acquire_delay, apefile.raster_delay, apefile.tip_dist); gwy_debug("v_ref = %g, vpmt1 = %g, vpmt2 = %g", apefile.v_ref, apefile.vpmt1, apefile.vpmt2); gwy_debug("x_piezo_factor = %u, y_piezo_factor = %u, z_piezo_factor = %u", apefile.x_piezo_factor, apefile.y_piezo_factor, apefile.z_piezo_factor); gwy_debug("hv_gain = %g, freq_osc_tip = %g, rotate = %g", apefile.hv_gain, apefile.freq_osc_tip, apefile.rotate); gwy_debug("slope_x = %g, slope_y = %g", apefile.slope_x, apefile.slope_y); gwy_debug("topo_means = %u, optical_means = %u, error_means = %u", apefile.topo_means, apefile.optical_means, apefile.error_means); gwy_debug("channel bitmask = %03x, ndata = %u", apefile.channels, apefile.ndata); gwy_debug("range_x = %g, range_y = %g", apefile.range_x, apefile.range_y); n = (apefile.res + 1)*(apefile.res + 1)*sizeof(float); if (size - (p - buffer) != n*apefile.ndata) { g_warning("Expected data size %u, but it's %u.", n*apefile.ndata, (guint)(size - (p - buffer))); apefile.ndata = MIN(apefile.ndata, (size - (p - buffer))/n); } if (!apefile.ndata) { err_NO_DATA(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } fill_data_fields(&apefile, p); gwy_file_abandon_contents(buffer, size, NULL); container = gwy_container_new(); /* All metadata seems to be per-file (global) */ meta = apefile_get_metadata(&apefile); for (b = apefile.channels, n = 0, i = 0; b; b = b >> 1, i++) { GwyContainer *tmp; gchar *title; gchar key[32]; if (!(b & 1)) continue; g_snprintf(key, sizeof(key), "/%d/data", n); dfield = apefile.data[n]; gwy_container_set_object_by_name(container, key, dfield); g_object_unref(apefile.data[n]); g_snprintf(key, sizeof(key), "/%d/data/title", n); /* * Channel labelling based on SPM Mode */ switch (apefile.spm_mode) { case SPM_MODE_SNOM: title = gwy_enuml_to_string(i, "Height", APE_HEIGHT, "Height-R", APE_HEIGHT_R, "NSOM", APE_NSOM, "NSOM-R", APE_NSOM_R, "Error", APE_ERROR, "Error-R", APE_ERROR_R, "NSOM2", APE_NSOM2, "NSOM2-R", APE_NSOM2_R, "Lateral", APE_AUX1, "Z-Z0", APE_AUX2, "Lateral-R", APE_AUX1_R, "Z-Z0-R", APE_AUX2_R, NULL); break; case SPM_MODE_AFM_NONCONTACT: case SPM_MODE_AFM_CONTACT: case SPM_MODE_PHASE_DETECT_AFM: title = gwy_enuml_to_string(i, "Height", APE_HEIGHT, "Height-R", APE_HEIGHT_R, "IN1", APE_NSOM, "IN1-R", APE_NSOM_R, "Error", APE_ERROR, "Error-R", APE_ERROR_R, "IN2", APE_NSOM2, "IN2-R", APE_NSOM2_R, "Lateral", APE_AUX1, "Z-Z0", APE_AUX2, "Lateral-R", APE_AUX1_R, "Z-Z0-R", APE_AUX2_R, NULL); break; default: title = gwy_enuml_to_string(i, "Height", APE_HEIGHT, "Height-R", APE_HEIGHT_R, "IN1", APE_NSOM, "IN1-R", APE_NSOM_R, "Error", APE_ERROR, "Error-R", APE_ERROR_R, "IN2", APE_NSOM2, "IN2-R", APE_NSOM2_R, "Aux1", APE_AUX1, "Z-Z0", APE_AUX2, "Aux1-R", APE_AUX1_R, "Z-Z0-R", APE_AUX2_R, NULL); break; } if (title && *title) gwy_container_set_string_by_name(container, key, g_strdup(title)); tmp = gwy_container_duplicate(meta); g_snprintf(key, sizeof(key), "/%d/meta", n); gwy_container_set_object_by_name(container, key, tmp); g_object_unref(tmp); gwy_file_channel_import_log_add(container, n, NULL, filename); n++; } g_object_unref(meta); g_free(apefile.remark); return container; }
static GwyContainer* ecs_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gchar *s = NULL, *s2 = NULL; GwySIUnit *siunit; const guchar *p; gdouble *data, *row; guint xres, yres, i, j; gdouble xreal, q; const gint16 *pdata; guchar c; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); g_clear_error(&err); return NULL; } if (size < HEADER_SIZE + 2) { err_TOO_SHORT(error); goto fail; } p = buffer + ECS_RESOLUTION; xres = gwy_get_guint16_le(&p); yres = gwy_get_guint16_le(&p); gwy_debug("xres: %u, yres: %u", xres, yres); if (size != HEADER_SIZE + 2*xres*yres) { err_SIZE_MISMATCH(error, HEADER_SIZE + 2*xres*yres, size); goto fail; } /* Scan size */ p = buffer + ECS_SCAN_SIZE; s = get_PASCAL_STRING(&p, HEADER_SIZE - ECS_SCAN_SIZE); if (!s) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Scan size header field overlaps with data.")); goto fail; } gwy_debug("Scan size str: <%s>", s); if (!g_str_has_prefix(s, "Scan Size: ")) { err_FILE_TYPE(error, "ECS"); goto fail; } if (sscanf(s + strlen("Scan Size: "), "%lf %lf%c", &xreal, &q, &c) != 3) { err_INVALID(error, "Scan Size"); goto fail; } g_free(s); s = NULL; gwy_debug("xreal: %g q: %g unit: %s", xreal, q, c == 0x8f ? "Angstrom" : "Nanometer"); if (c == 0x8f) { xreal *= 1e-10; q *= 1e-10; } else { xreal *= 1e-9; q *= 1e-9; } q /= 65536.0; /* This does not make much sense when xres != yres, but it is what * Snomputz does. */ dfield = gwy_data_field_new(xres, yres, xreal, xreal, FALSE); data = gwy_data_field_get_data(dfield); pdata = (const gint16*)(buffer + HEADER_SIZE); for (i = 0; i < yres; i++) { row = data + (yres-1 - i)*xres; for (j = 0; j < xres; j++) row[j] = GINT16_TO_LE(pdata[i*xres + j])*q; } 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); container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); /* Channel title */ p = buffer + ECS_CHANNEL; s = get_PASCAL_STRING(&p, HEADER_SIZE - ECS_CHANNEL); if (!s || !*s) s = g_strdup("Topography"); gwy_container_set_string_by_name(container, "/0/data/title", s); s = NULL; meta = gwy_container_new(); /* Date & time */ p = buffer + ECS_DATE; s = get_PASCAL_STRING(&p, HEADER_SIZE - ECS_DATE); if (s) { p = buffer + ECS_TIME; s2 = get_PASCAL_STRING(&p, HEADER_SIZE - ECS_TIME); if (s2) { gwy_container_set_string_by_name(meta, "Date", g_strconcat(s, " ", s2, NULL)); g_free(s2); s2 = NULL; } g_free(s); s = NULL; } /* Channel title */ p = buffer + ECS_CHANNEL; s = get_PASCAL_STRING(&p, HEADER_SIZE - ECS_CHANNEL); if (s && *s) { gwy_container_set_string_by_name(meta, "Comment", s); s = NULL; } if (gwy_container_get_n_items(meta)) gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); fail: g_free(s); g_free(s2); gwy_object_unref(dfield); gwy_file_abandon_contents(buffer, size, NULL); 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* rhk_sm3_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GPtrArray *rhkfile; RHKPage *rhkpage; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; const guchar *p; GString *key; guint i, count; 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); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } rhkfile = g_ptr_array_new(); p = buffer; count = 0; gwy_debug("position %04x", p - buffer); while ((rhkpage = rhk_sm3_read_page(&p, &size, &err))) { gwy_debug("Page #%u read OK", count); count++; rhkpage->pageno = count; gwy_debug("position %04x", p - buffer); if (rhkpage->type != RHK_TYPE_IMAGE) { gwy_debug("Page is not IMAGE, skipping"); rhk_sm3_page_free(rhkpage); continue; } g_ptr_array_add(rhkfile, rhkpage); } /* Be tolerant and don't fail when we were able to import at least * something */ if (!rhkfile->len) { if (err) g_propagate_error(error, err); else err_NO_DATA(error); gwy_file_abandon_contents(buffer, size, NULL); g_ptr_array_free(rhkfile, TRUE); return NULL; } g_clear_error(&err); container = gwy_container_new(); key = g_string_new(""); for (i = 0; i < rhkfile->len; i++) { const gchar *cs; gchar *s; rhkpage = g_ptr_array_index(rhkfile, i); dfield = rhk_sm3_page_to_data_field(rhkpage); g_string_printf(key, "/%d/data", i); gwy_container_set_object_by_name(container, key->str, dfield); g_object_unref(dfield); p = rhkpage->strings[RHK_STRING_LABEL]; cs = gwy_enum_to_string(rhkpage->scan_dir, scan_directions, G_N_ELEMENTS(scan_directions)); if (p && *p) { g_string_append(key, "/title"); if (cs) s = g_strdup_printf("%s [%s]", p, cs); else s = g_strdup(p); gwy_container_set_string_by_name(container, key->str, s); } meta = rhk_sm3_get_metadata(rhkpage); g_string_printf(key, "/%d/meta", i); gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); gwy_app_channel_check_nonsquare(container, i); } g_string_free(key, TRUE); gwy_file_abandon_contents(buffer, size, NULL); for (i = 0; i < rhkfile->len; i++) rhk_sm3_page_free(g_ptr_array_index(rhkfile, i)); g_ptr_array_free(rhkfile, TRUE); return container; }
static GwyContainer* sensofar_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SensofarDataDesc data_desc; GwyContainer *container = NULL; GwyDataField *dfield, *mfield; GwyGraphModel *gmodel; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE + 12) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated")); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* Date block */ p = buffer; memcpy(&data_desc.date.str, p, DATE_SIZE); data_desc.date.str[DATE_SIZE-1] = '\0'; p += DATE_SIZE; data_desc.date.t = gwy_get_guint32_le(&p); /* Comment block */ memcpy(&data_desc.user_comment, p, COMMENT_SIZE); data_desc.user_comment[COMMENT_SIZE-1] = '\0'; p += COMMENT_SIZE; /* Calbration block */ data_desc.axes_config.yres = gwy_get_guint32_le(&p); data_desc.axes_config.xres = gwy_get_guint32_le(&p); data_desc.axes_config.N_tall = gwy_get_guint32_le(&p); data_desc.axes_config.dy_multip = gwy_get_gfloat_le(&p); data_desc.axes_config.mppx = gwy_get_gfloat_le(&p); data_desc.axes_config.mppy = gwy_get_gfloat_le(&p); data_desc.axes_config.x_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.y_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.mpp_tall = gwy_get_gfloat_le(&p); data_desc.axes_config.z_0 = gwy_get_gfloat_le(&p); /* Measurement block */ data_desc.measure_config.type = gwy_get_guint32_le(&p); data_desc.measure_config.algorithm = gwy_get_guint32_le(&p); data_desc.measure_config.method = gwy_get_guint32_le(&p); data_desc.measure_config.objective = gwy_get_guint32_le(&p); data_desc.measure_config.area = gwy_get_guint32_le(&p); data_desc.measure_config.xres_area = gwy_get_guint32_le(&p); data_desc.measure_config.yres_area = gwy_get_guint32_le(&p); data_desc.measure_config.xres = gwy_get_guint32_le(&p); data_desc.measure_config.yres = gwy_get_guint32_le(&p); data_desc.measure_config.na = gwy_get_guint32_le(&p); data_desc.measure_config.incr_z = gwy_get_gdouble_le(&p); data_desc.measure_config.range = gwy_get_gfloat_le(&p); data_desc.measure_config.n_planes = gwy_get_guint32_le(&p); data_desc.measure_config.tpc_umbral_F = gwy_get_guint32_le(&p); data_desc.measure_config.restore = gwy_get_gboolean8(&p); data_desc.measure_config.num_layers = *(p++); data_desc.measure_config.version = *(p++); data_desc.measure_config.config_hardware = *(p++); data_desc.measure_config.stack_im_num = *(p++); data_desc.measure_config.reserved = *(p++); p += 2; // struct padding data_desc.measure_config.factor_delmacio = gwy_get_guint32_le(&p); gwy_debug("File date=<%s>, data type=%d, xres=%d, yres=%d, version=%d", data_desc.date.str, data_desc.measure_config.type, data_desc.measure_config.xres, data_desc.measure_config.yres, data_desc.measure_config.version); switch (data_desc.measure_config.type) { case MES_TOPO: case MES_IMATGE: dfield = sensofar_read_data_field(&data_desc, &mfield, &p, size - (p - buffer), error); if (!dfield) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_app_channel_title_fall_back(container, 0); break; case MES_PERFIL: case MES_GRUIX: gmodel = sensofar_read_profile(&data_desc, &p, size - (p - buffer), error); if (!gmodel) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_graph_key_for_id(0), gmodel); g_object_unref(gmodel); break; default: err_DATA_TYPE(error, data_desc.measure_config.type); break; } return container; }
static GwyContainer* pt3file_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { PicoHarpFile pt3file; GwyContainer *meta, *container = NULL; GwyDataField *dfield = NULL; GwyGraphModel *gmodel = NULL; guchar *buffer = NULL; const guchar *p; gsize header_len, size = 0; GError *err = NULL; LineTrigger *linetriggers = NULL; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&pt3file, 1); if (!(header_len = pt3file_read_header(buffer, size, &pt3file, error))) goto fail; if (err_SIZE_MISMATCH (error, header_len + pt3file.number_of_records*sizeof(guint32), size, FALSE)) goto fail; if (pt3file.measurement_mode != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("T2 measurement mode is not implemented.")); goto fail; } if (pt3file.imaging.common.instrument != PICO_HARP_PIE710 && pt3file.imaging.common.instrument != PICO_HARP_KDT180) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only PI E710 and KDT180-100-Im imaging formats are " "implemented.")); goto fail; } /* Scan the records and find the line triggers */ p = buffer + header_len; if (!(linetriggers = pt3file_scan_line_triggers(&pt3file, p, error))) goto fail; container = gwy_container_new(); dfield = pt3file_extract_counts(&pt3file, linetriggers, p); 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("Photon count")); meta = pt3file_get_metadata(&pt3file); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); gmodel = pt3file_extract_decay(&pt3file, p); gwy_container_set_object_by_name(container, "/0/graph/graph/1", gmodel); g_object_unref(gmodel); fail: g_free(linetriggers); gwy_file_abandon_contents(buffer, size, NULL); return container; }
static GwyContainer* unisoku_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { UnisokuFile ufile; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gchar *text = NULL; gsize i, size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gchar *data_name; if (!g_file_get_contents(filename, &text, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } for (i = 0; i < size; i++) { if (!text[i]) text[i] = ' '; } gwy_clear(&ufile, 1); if (!unisoku_read_header(text, &ufile, error)) { unisoku_file_free(&ufile); g_free(text); return NULL; } g_free(text); if (ufile.data_type < UNISOKU_UINT8 || ufile.data_type > UNISOKU_FLOAT || type_sizes[ufile.data_type] == 0) { err_DATA_TYPE(error, ufile.data_type); unisoku_file_free(&ufile); return NULL; } if (!(data_name = unisoku_find_data_name(filename))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("No corresponding data file was found for header file.")); unisoku_file_free(&ufile); return NULL; } if (!gwy_file_get_contents(data_name, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); unisoku_file_free(&ufile); g_free(data_name); return NULL; } dfield = unisoku_read_data_field(buffer, size, &ufile, error); gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) { unisoku_file_free(&ufile); g_free(data_name); return NULL; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); gwy_app_channel_title_fall_back(container, 0); meta = unisoku_get_metadata(&ufile); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, data_name); unisoku_file_free(&ufile); g_free(data_name); 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 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 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* 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 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 GwyContainer* spmlab_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gchar *title = NULL; gint dir; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } /* 2048 is wrong. moreover it differs for r5 and r4, kasigra uses 5752 for * r5 */ if (size < 2048) { err_TOO_SHORT(error); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (buffer[0] != '#' || buffer[1] != 'R') { err_FILE_TYPE(error, "Thermicroscopes SpmLab"); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } switch (buffer[2]) { case '3': case '4': case '5': case '6': case '7': dfield = read_data_field(buffer, size, buffer[2], &title, &dir, error); break; default: g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Unknown format version %c."), buffer[2]); break; } gwy_file_abandon_contents(buffer, size, NULL); if (!dfield) return NULL; container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); g_object_unref(dfield); if (title) gwy_container_set_string_by_name(container, "/0/data/title", title); else gwy_app_channel_title_fall_back(container, 0); gwy_file_channel_import_log_add(container, 0, NULL, filename); /* TODO: Store direction to metadata, if known */ return container; }