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* 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 void apedax_get_channels_data(unzFile uFile, guchar *scanXmlContent, gsize contentSize, const gchar *filename, GwyContainer *container, GwyContainer *meta, const APEScanSize *scanSize, GError **error) { xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; xmlXPathContextPtr context; xmlXPathObjectPtr pathObj; xmlNodeSetPtr nodeset; xmlChar *buffer = NULL; gchar key[256]; gint i; gint power10 = 0; gdouble scaleFactor = 1.0; GwySIUnit *zUnit; gchar *zUnitString = NULL; gchar *binFileName = NULL; GwyDataField *dfield; GwyContainer *tmp; if (scanXmlContent == NULL || contentSize == 0) return; gwy_clear(key, sizeof(key)); doc = xmlReadMemory(scanXmlContent, contentSize, "scan.xml", NULL, 0); if (doc == NULL) goto fail; context = xmlXPathNewContext(doc); if (context == NULL) goto fail; pathObj = xmlXPathEvalExpression("/Scan/Channels/Channel", context); if (pathObj == NULL) { xmlXPathFreeContext(context); goto fail; } /*There must be at least one channel*/ if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) { xmlXPathFreeObject(pathObj); xmlXPathFreeContext(context); err_NO_DATA(error); return; } nodeset = pathObj->nodesetval; if (nodeset->nodeNr <= 0) goto fail; for (i = 0; i < nodeset->nodeNr; i++) { cur = nodeset->nodeTab[i]->xmlChildrenNode; while (cur) { /*Label*/ if (gwy_strequal((gchar*)cur->name, "Label")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); g_snprintf(key, sizeof(key), "/%d/data/title", i); gwy_container_set_string_by_name(container, key, g_strdup(buffer)); xmlFree(buffer); } /*Factor*/ if (gwy_strequal((gchar*)cur->name, "ConversionFactor")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); scaleFactor = g_ascii_strtod((gchar*)buffer, NULL); xmlFree(buffer); } /*Unit*/ if (gwy_strequal((gchar*)cur->name, "DataUnit")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); zUnitString = g_strdup((gchar*)buffer); zUnit = gwy_si_unit_new_parse(zUnitString, &power10); xmlFree(buffer); g_object_unref(zUnit); } /*Binary file name*/ if (gwy_strequal((gchar*)cur->name, "BINFile")) { buffer = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); binFileName = g_strdup((gchar*)buffer); xmlFree(buffer); } cur = cur->next; } scaleFactor *= pow(10.0, power10); dfield = apedax_get_data_field(uFile, binFileName, scanSize, zUnitString, scaleFactor, error); if (dfield) { g_snprintf(key, sizeof(key), "/%d/data", i); gwy_container_set_object_by_name(container, key, dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(container, i, NULL, filename); tmp = gwy_container_duplicate(meta); g_snprintf(key, sizeof(key), "/%d/meta", i); gwy_container_set_object_by_name(container, key, tmp); g_object_unref(tmp); } } xmlXPathFreeObject(pathObj); xmlXPathFreeContext(context); xmlFreeDoc(doc); return; fail: err_FILE_TYPE(error, FILE_TYPE); if (doc) xmlFreeDoc(doc); return; }
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 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* 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* gxsm_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const gchar *dimensions[] = { "time", "value", "dimy", "dimx" }; GwyContainer *data = NULL; GwyDataField *dfield; GwySIUnit *siunit; NetCDF cdffile; const NetCDFDim *dim; const NetCDFVar *var; const NetCDFAttr *attr; gdouble real; gint i, power10; if (!cdffile_load(&cdffile, filename, error)) return NULL; if (cdffile.nrecs) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("NetCDF records are not supported.")); goto gxsm_load_fail; } /* Look for variable "H" or "FloatField". This seems to be how GXSM calls * data. */ if (!(var = cdffile_get_var(&cdffile, "H")) && !(var = cdffile_get_var(&cdffile, "FloatField"))) { err_NO_DATA(error); goto gxsm_load_fail; } /* Check the dimensions. We only know how to handle time=1 and value=1. */ for (i = 0; i < var->ndims; i++) { dim = cdffile.dims + var->dimids[i]; if (!gwy_strequal(dim->name, dimensions[i]) || (i < 2 && dim->length != 1)) { /* XXX */ err_NO_DATA(error); goto gxsm_load_fail; } } if (err_DIMENSION(error, cdffile.dims[var->dimids[3]].length) || err_DIMENSION(error, cdffile.dims[var->dimids[2]].length)) goto gxsm_load_fail; dfield = read_data_field((const guchar*)(cdffile.buffer + var->begin), cdffile.dims[var->dimids[3]].length, cdffile.dims[var->dimids[2]].length, var->type); if ((siunit = read_real_size(&cdffile, "rangex", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_xreal(dfield, real*pow10(power10)); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangey", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_yreal(dfield, real*pow10(power10)); /* must be the same gwy_data_field_set_si_unit_xy(dfield, siunit); */ g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangez", &real, &power10))) { /* rangez seems to be some bogus value, take only units */ gwy_data_field_set_si_unit_z(dfield, siunit); gwy_data_field_multiply(dfield, pow10(power10)); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "dz", &real, &power10))) { /* on the other hand the units seem to be bogus here, take the range */ gwy_data_field_multiply(dfield, real); g_object_unref(siunit); } data = gwy_container_new(); gwy_container_set_object_by_name(data, "/0/data", dfield); g_object_unref(dfield); if ((attr = cdffile_get_attr(var->attrs, var->nattrs, "long_name")) && attr->type == NC_CHAR && attr->nelems) { gwy_container_set_string_by_name(data, "/0/data/title", g_strndup(attr->values, attr->nelems)); } gxsm_load_fail: gwy_file_abandon_contents(cdffile.buffer, cdffile.size, NULL); cdffile_free(&cdffile); return data; }
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* 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* rawxyz_load(const gchar *filename, GwyRunType mode, GError **error) { GwyContainer *settings, *container = NULL; GwySurface *surface = NULL; RawXYZArgs args; GwySIUnit *unit; gint power10; gdouble q; gchar *buffer = NULL; gsize size; GError *err = NULL; gboolean ok; guint k; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } surface = read_xyz_points(buffer); g_free(buffer); if (!surface->n) { err_NO_DATA(error); goto fail; } settings = gwy_app_settings_get(); rawxyz_load_args(settings, &args); if (mode == GWY_RUN_INTERACTIVE) { ok = rawxyz_dialog(&args, surface); rawxyz_save_args(settings, &args); if (!ok) { err_CANCELLED(error); goto fail; } } unit = gwy_si_unit_new_parse(args.xy_units, &power10); if (power10) { q = pow10(power10); for (k = 0; k < surface->n; k++) { surface->data[k].x *= q; surface->data[k].y *= q; } gwy_surface_invalidate(surface); } gwy_serializable_clone(G_OBJECT(unit), G_OBJECT(gwy_surface_get_si_unit_xy(surface))); unit = gwy_si_unit_new_parse(args.z_units, &power10); if (power10) { q = pow10(power10); for (k = 0; k < surface->n; k++) surface->data[k].z *= q; gwy_surface_invalidate(surface); } gwy_serializable_clone(G_OBJECT(unit), G_OBJECT(gwy_surface_get_si_unit_z(surface))); container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_surface_key_for_id(0), surface); gwy_app_xyz_title_fall_back(container, 0); gwy_file_xyz_import_log_add(container, 0, NULL, filename); fail: g_free(args.xy_units); g_free(args.z_units); GWY_OBJECT_UNREF(surface); return container; }
static GwyContainer* omicron_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { OmicronFile ofile; GwyContainer *container = NULL, *meta; gchar *text = NULL; GError *err = NULL; GwyDataField *dfield = NULL; GwySpectra *spectra = NULL; gchar key[32]; guint i; /* @text must not be destroyed while @ofile is still in used because * all strings are only references there */ if (!g_file_get_contents(filename, &text, NULL, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&ofile, 1); ofile.filename = filename; if (!omicron_read_header(text, &ofile, error)) goto fail; if (!ofile.topo_channels || !ofile.topo_channels->len) { err_NO_DATA(error); goto fail; } container = gwy_container_new(); /* First Load the Topographic Data */ for (i = 0; i < ofile.topo_channels->len; i++) { OmicronTopoChannel *channel; channel = g_ptr_array_index(ofile.topo_channels, i); dfield = omicron_read_data(&ofile, channel, error); if (!dfield) { gwy_object_unref(container); goto fail; } g_snprintf(key, sizeof(key), "/%u/data", i); gwy_container_set_object_by_name(container, key, dfield); g_object_unref(dfield); if (channel->name) { gchar *s; g_snprintf(key, sizeof(key), "/%u/data/title", i); if (channel->scandir == SCAN_FORWARD) s = g_strdup_printf("%s (Forward)", channel->name); else if (channel->scandir == SCAN_BACKWARD) s = g_strdup_printf("%s (Backward)", channel->name); else s = g_strdup(channel->name); gwy_container_set_string_by_name(container, key, s); } if ((meta = omicron_make_meta(&ofile))) { g_snprintf(key, sizeof(key), "/%u/meta", i); gwy_container_set_object_by_name(container, key, meta); g_object_unref(meta); } } /* Then load the spectroscopy data. */ /* * There are two types of spectroscopy file: * * a) Single Point Spectroscopy Files * Single point which is stored by SCALA as an ascii file. Any number of * single point spectrums may be aquired, but the number is normally * quite small. These files are identified by their filename *.cs[0..3] * * b) Binary Spectroscopy Files * When large numbers of spectra are aquired on a regular grid they are * stored in BE binary. These data are aquired during the scan, and so * can be aquired during the forward scan or the backward scan. * * Forwards scan files can be indentified from their filename *.sf[0..3] * Backward scan files can be indentified from their filename *.sb[0..3] */ if (ofile.spectro_channels) { for (i = 0; i < ofile.spectro_channels->len; i++) { OmicronSpectroChannel *channel; channel = g_ptr_array_index(ofile.spectro_channels, i); if (omicron_has_extension(channel->filename, "cs")) { gchar *t; GQuark quark; spectra = omicron_read_cs_data(&ofile, channel, error); if (!spectra) { gwy_object_unref(container); goto fail; } if (!gwy_spectra_get_n_spectra(spectra)) { gwy_debug("Spectra %u is empty, ignoring", i); g_object_unref(spectra); continue; } /* FIXME */ t = g_strconcat(channel->chan, "-", channel->param, NULL); gwy_spectra_set_title(spectra, t); g_free(t); quark = gwy_app_get_spectra_key_for_id(i); gwy_container_set_object(container, quark, spectra); g_object_unref(spectra); } else if (omicron_has_extension(channel->filename, "sf") || omicron_has_extension(channel->filename, "sb")) { /* FIXME */ } else { g_warning("Cannot determine spectra type of %s", channel->filename); } } } fail: omicron_file_free(&ofile); g_free(text); return container; }
static GwyGraphModel* sensofar_read_profile(SensofarDataDesc *data_desc, const guchar **p, gsize size, GError **error) { GwyGraphModel *gmodel; GwyGraphCurveModel *gcmodel; guint xres, yres, j, n; GwySIUnit *units = NULL; gdouble *xdata, *ydata; gdouble dx; yres = gwy_get_guint32_le(p); if (yres != 1) g_warning("ysize is not 1 for profile"); xres = gwy_get_guint32_le(p); gwy_debug("Data size: %dx%d", xres, yres); if (err_SIZE_MISMATCH(error, xres*yres*sizeof(gfloat), size - 2*sizeof(guint32), FALSE)) return NULL; if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; if (!((data_desc->axes_config.mppx = fabs(data_desc->axes_config.mppx)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); data_desc->axes_config.mppx = 1.0; } xdata = g_new(gdouble, xres); ydata = g_new(gdouble, xres); dx = data_desc->axes_config.mppx * Micrometer; for (j = n = 0; j < xres; j++) { gdouble v = gwy_get_gfloat_le(p); if (v != 1000001.0) { xdata[n] = dx*j; ydata[n] = v*Micrometer; n++; } } if (!n) { g_free(xdata); g_free(ydata); err_NO_DATA(error); return NULL; } gmodel = gwy_graph_model_new(); g_object_set(gmodel, "title", _("Profile"), NULL); units = gwy_si_unit_new("m"); // values are in um only g_object_set(gmodel, "si-unit-x", units, NULL); g_object_unref(units); units = gwy_si_unit_new("m"); // values are in um only g_object_set(gmodel, "si-unit-y", units, NULL); g_object_unref(units); gcmodel = gwy_graph_curve_model_new(); gwy_graph_curve_model_set_data(gcmodel, xdata, ydata, n); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "description", _("Profile"), NULL); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); return gmodel; }
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* 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* nanoscope_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *meta, *container = NULL; GError *err = NULL; gchar *buffer = NULL; gchar *p; const gchar *self; gsize size = 0; NanoscopeFileType file_type; NanoscopeData *ndata; NanoscopeValue *val; GHashTable *hash, *scannerlist = NULL, *scanlist = NULL; GList *l, *list = NULL; gint i, xres = 0, yres = 0; gboolean ok, has_version = FALSE; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } file_type = NANOSCOPE_FILE_TYPE_NONE; if (size > MAGIC_SIZE) { if (!memcmp(buffer, MAGIC_TXT, MAGIC_SIZE)) file_type = NANOSCOPE_FILE_TYPE_TXT; else if (!memcmp(buffer, MAGIC_BIN, MAGIC_SIZE)) file_type = NANOSCOPE_FILE_TYPE_BIN; } if (!file_type) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File is not a Nanoscope file, " "or it is a unknown subtype.")); g_free(buffer); return NULL; } gwy_debug("File type: %d", file_type); /* as already know file_type, fix the first char for hash reading */ *buffer = '\\'; p = buffer; while ((hash = read_hash(&p, &err))) { ndata = g_new0(NanoscopeData, 1); ndata->hash = hash; list = g_list_append(list, ndata); } if (err) { g_propagate_error(error, err); ok = FALSE; } else ok = TRUE; for (l = list; ok && l; l = g_list_next(l)) { ndata = (NanoscopeData*)l->data; hash = ndata->hash; self = g_hash_table_lookup(hash, "#self"); /* The alternate names were found in files written by some beast * called Nanoscope E software */ if (gwy_strequal(self, "Scanner list") || gwy_strequal(self, "Microscope list")) { scannerlist = hash; continue; } if (gwy_strequal(self, "File list")) { has_version = !!g_hash_table_lookup(hash, "Version"); gwy_debug("has Version: %d", has_version); continue; } if (gwy_strequal(self, "Ciao scan list") || gwy_strequal(self, "Afm list") || gwy_strequal(self, "NC Afm list")) { get_scan_list_res(hash, &xres, &yres); scanlist = hash; } if (!gwy_strequal(self, "Ciao image list") && !gwy_strequal(self, "AFM image list") && !gwy_strequal(self, "NCAFM image list")) continue; ndata->data_field = hash_to_data_field(hash, scannerlist, scanlist, file_type, has_version, size, buffer, xres, yres, &p, error); ok = ok && ndata->data_field; } if (ok) { gchar key[40]; i = 0; container = gwy_container_new(); for (l = list; l; l = g_list_next(l)) { ndata = (NanoscopeData*)l->data; if (ndata->data_field) { g_snprintf(key, sizeof(key), "/%d/data", i); gwy_container_set_object_by_name(container, key, ndata->data_field); if ((val = g_hash_table_lookup(ndata->hash, "@2:Image Data")) && val->soft_scale) { g_snprintf(key, sizeof(key), "/%d/data/title", i); gwy_container_set_string_by_name(container, key, g_strdup(val->soft_scale)); } meta = nanoscope_get_metadata(ndata->hash, list); g_snprintf(key, sizeof(key), "/%d/meta", i); gwy_container_set_object_by_name(container, key, meta); g_object_unref(meta); gwy_app_channel_check_nonsquare(container, i); i++; } } if (!i) gwy_object_unref(container); } for (l = list; l; l = g_list_next(l)) { ndata = (NanoscopeData*)l->data; gwy_object_unref(ndata->data_field); if (ndata->hash) g_hash_table_destroy(ndata->hash); g_free(ndata); } g_free(buffer); g_list_free(list); if (!container && ok) err_NO_DATA(error); 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* sly_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta = NULL; gchar *buffer = NULL; GError *err = NULL; GHashTable *hash = NULL; gchar *p, *line, *value; guint expecting_data = 0; SensolyticsChannel *channels = NULL; Dimensions dimensions; gint ndata = 0, i; if (!g_file_get_contents(filename, &buffer, NULL, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } p = buffer; line = gwy_str_next_line(&p); g_strstrip(line); if (!gwy_strequal(line, MAGIC)) { err_FILE_TYPE(error, "Sensolytics"); goto fail; } hash = g_hash_table_new(g_str_hash, g_str_equal); for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { if (!line[0]) continue; if (expecting_data) { expecting_data--; /* The columns are comma-separated and numbers use decimal points. * Do not tempt the number parsing functions more than necessary * and fix commas to tab characters. */ g_strdelimit(line, ",", '\t'); /* Ignore X, Y and Z, each is two values */ for (i = 0; i < 6; i++) g_ascii_strtod(line, &line); for (i = 0; i < ndata; i++) channels[i].data[expecting_data] = channels[i].q * g_ascii_strtod(line, &line); } else { g_strstrip(line); if (line[0] != '#') { g_warning("Comment line does not start with #."); continue; } do { line++; } while (g_ascii_isspace(*line)); if (g_str_has_prefix(line, "X [")) { if (channels) { g_warning("Multiple data headers!?"); continue; } if (!read_dimensions(hash, &ndata, &dimensions, error) || !(channels = create_fields(hash, line, ndata, &dimensions))) goto fail; expecting_data = dimensions.xres * dimensions.yres; continue; } value = strchr(line, ':'); if (!value) { if (!gwy_strequal(line, "ArrayScan")) g_warning("Non-parameter-like line %s", line); continue; } *value = '\0'; g_strchomp(line); do { value++; } while (g_ascii_isspace(*value)); if (gwy_strequal(line, "Warning")) continue; gwy_debug("<%s>=<%s>", line, value); g_hash_table_insert(hash, line, value); } } if (!channels) { err_NO_DATA(error); goto fail; } container = gwy_container_new(); for (i = 0; i < ndata; i++) { GQuark key = gwy_app_get_data_key_for_id(i); gwy_data_field_invert(channels[i].dfield, FALSE, TRUE, FALSE); gwy_container_set_object(container, key, channels[i].dfield); gwy_app_channel_check_nonsquare(container, i); if (channels[i].name) { gchar *s = g_strconcat(g_quark_to_string(key), "/title", NULL); gwy_container_set_string_by_name(container, s, g_strdup(channels[i].name)); g_free(s); } else gwy_app_channel_title_fall_back(container, i); gwy_file_channel_import_log_add(container, i, NULL, filename); } meta = get_meta(hash); clone_meta(container, meta, ndata); g_object_unref(meta); fail: g_free(buffer); if (hash) g_hash_table_destroy(hash); if (channels) { for (i = 0; i < ndata; i++) g_object_unref(channels[i].dfield); g_free(channels); } return container; }
static gboolean read_binary_data(X3PFile *x3pfile, unzFile *zipfile, GError **error) { GwyRawDataType rawtype; gsize size; guchar *bindata; gchar *s; guint i; s = g_hash_table_lookup(x3pfile->hash, DATA_LINK_PREFIX "/PointDataLink"); if (!s) { err_NO_DATA(error); return FALSE; } gwy_debug("binary data file %s", s); if (unzLocateFile(zipfile, s, 1) != UNZ_OK) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO, _("File %s is missing in the zip file."), s); return FALSE; } s = g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CZ/DataType"); if (!s) { err_MISSING_FIELD(error, AXES_PREFIX "CZ/DataType"); return FALSE; } if (!x3p_file_get_data_type(s, &rawtype, error)) return FALSE; if (!(bindata = x3p_get_file_content(zipfile, &size, error))) return FALSE; if (err_SIZE_MISMATCH(error, x3pfile->ndata * gwy_raw_data_size(rawtype), size, TRUE)) { g_free(bindata); return FALSE; } gwy_convert_raw_data(bindata, x3pfile->ndata, 1, rawtype, GWY_BYTE_ORDER_LITTLE_ENDIAN, x3pfile->values, x3pfile->dz, x3pfile->zoff); g_free(bindata); for (i = 0; i < x3pfile->ndata; i++) x3pfile->valid[i] = TRUE; s = g_hash_table_lookup(x3pfile->hash, DATA_LINK_PREFIX "/ValidPointsLink"); if (!s) return TRUE; if (unzLocateFile(zipfile, s, 1) != UNZ_OK) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO, _("File %s is missing in the zip file."), s); return FALSE; } if (!(bindata = x3p_get_file_content(zipfile, &size, error))) return FALSE; if (err_SIZE_MISMATCH(error, (x3pfile->ndata + 7)/8, size, TRUE)) { g_free(bindata); return FALSE; } for (i = 0; i < x3pfile->ndata; i++) x3pfile->valid[i] = bindata[i/8] & (1 << (i % 8)); g_free(bindata); return TRUE; }
static guint find_data_offsets(const gchar *buffer, gsize size, GPtrArray *ezdfile, GError **error) { EZDSection *dataset, *section; GString *grkey; guint required_size = 0; gint ngroups, nchannels, i, j, k; guint ndata = 0; gchar *p; /* Sanity check */ if (!ezdfile->len) { err_NO_DATA(error); return 0; } dataset = (EZDSection*)g_ptr_array_index(ezdfile, 0); if (strcmp(dataset->name, "DataSet")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("First section isn't DataSet")); return 0; } if (!(p = g_hash_table_lookup(dataset->meta, "GroupCount")) || (ngroups = atol(p)) <= 0) { err_INVALID(error, _("GroupCount in [DataSet]")); return 0; } /* Scan groups */ grkey = g_string_new(""); for (i = 0; i < ngroups; i++) { g_string_printf(grkey, "Gr%d-Count", i); if (!(p = g_hash_table_lookup(dataset->meta, grkey->str))) { g_warning("No count for group %u", i); continue; } if ((nchannels = atol(p)) <= 0) continue; /* Scan channels inside a group, note it's OK there's less channels * than specified */ for (j = 0; j < nchannels; j++) { g_string_printf(grkey, "Gr%d-Ch%d", i, j); if (!(p = g_hash_table_lookup(dataset->meta, grkey->str))) continue; section = NULL; for (k = 1; k < ezdfile->len; k++) { section = (EZDSection*)g_ptr_array_index(ezdfile, k); if (gwy_strequal(section->name, p)) break; } if (!section) { g_warning("Cannot find section for %s", p); continue; } /* Compute data position */ gwy_debug("Data %s at offset %u from data start", grkey->str, required_size); gwy_debug("xres = %d, yres = %d, bpp = %d, z-name = %s", section->xres, section->yres, section->bitdepth, section->zrange.name); if (section->yres < 2) { gwy_debug("Skipping 1D data Gr%d-Ch%d. FIXME.", i, j); continue; } ndata++; section->data = buffer + required_size; required_size += section->xres * section->yres * (section->bitdepth/8); if (required_size > size) { g_warning("Truncated file, %s doesn't fit", grkey->str); g_string_free(grkey, TRUE); section->data = NULL; return 0; } section->group = i; section->channel = j; } } g_string_free(grkey, TRUE); if (!ndata) err_NO_DATA(error); return ndata; }
static GwyContainer* ols_load_tiff(const GwyTIFF *tiff, const gchar *filename, GError **error) { const gchar *colour_channels[] = { "Red", "Green", "Blue" }; const gchar *colour_channel_gradients[] = { "RGB-Red", "RGB-Green", "RGB-Blue" }; GwyContainer *container = NULL; GwyDataField *dfield; GwySIUnit *siunit; GwyTIFFImageReader *reader = NULL; GwyTextHeaderParser parser; GHashTable *hash; gint i, power10; gchar *comment = NULL; const gchar *s1; GError *err = NULL; guint spp, ch, id = 0, dir_num = 0; gdouble *data; gdouble z_axis = 1.0, xy_axis, factor; GQuark quark; GString *key; /* Comment with parameters is common for all data fields */ if (!gwy_tiff_get_string0(tiff, GWY_TIFFTAG_IMAGE_DESCRIPTION, &comment) || !strstr(comment, MAGIC_COMMENT)) { g_free(comment); err_FILE_TYPE(error, "OLS"); return NULL; } /* Read the comment header. */ gwy_clear(&parser, 1); parser.key_value_separator = "="; parser.section_template = "[\x1a]"; parser.endsection_template = "[\x1a End]"; parser.section_accessor = "::"; hash = gwy_text_header_parse(comment, &parser, NULL, NULL); key = g_string_new(NULL); for (dir_num = 0; dir_num < gwy_tiff_get_n_dirs(tiff); dir_num++) { reader = gwy_tiff_image_reader_free(reader); /* Request a reader, this ensures dimensions and stuff are defined. */ reader = gwy_tiff_get_image_reader(tiff, dir_num, 3, &err); if (!reader) { g_warning("Ignoring directory %u: %s", dir_num, err->message); g_clear_error(&err); continue; } spp = reader->samples_per_pixel; g_string_printf(key, "Data %u Info::XY Convert Value", dir_num+1); if (!(s1 = g_hash_table_lookup(hash, key->str))) { g_warning("Cannot find 'XY Convert Value' for data %u.", dir_num+1); continue; } xy_axis = g_ascii_strtod(s1, NULL); if (!((xy_axis = fabs(xy_axis)) > 0)) { g_warning("Real size step is 0.0, fixing to 1.0"); xy_axis = 1.0; } g_string_printf(key, "Data %u Info::Z Convert Value", dir_num+1); if (!(s1 = g_hash_table_lookup(hash, key->str))) { g_warning("Cannot find 'Z Convert Value' for data %u.", dir_num+1); continue; } z_axis = g_ascii_strtod(s1, NULL); for (ch = 0; ch < spp; ch++) { siunit = gwy_si_unit_new_parse("nm", &power10); factor = pow10(power10); dfield = gwy_data_field_new(reader->width, reader->height, reader->width * xy_axis * factor, reader->height * xy_axis * factor, FALSE); // units gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); if (spp == 1) { if (dir_num == 1) siunit = gwy_si_unit_new_parse("nm", &power10); else siunit = gwy_si_unit_new_parse("1e-6", &power10); } else { siunit = gwy_si_unit_new(NULL); power10 = 0; } gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); factor = z_axis * pow10(power10); data = gwy_data_field_get_data(dfield); for (i = 0; i < reader->height; i++) gwy_tiff_read_image_row(tiff, reader, ch, i, factor, 0.0, data + i*reader->width); /* add read datafield to container */ if (!container) container = gwy_container_new(); quark = gwy_app_get_data_key_for_id(id); gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); g_string_printf(key, "%s/title", g_quark_to_string(quark)); if (spp == 1) { /* Channel 0 is texture */ if (dir_num == 0) { gwy_container_set_string_by_name(container, key->str, g_strdup("Texture")); } /* Channel 1 is topography */ else if (dir_num == 1) { g_string_printf(key, "%s/title", g_quark_to_string(quark)); gwy_container_set_string_by_name(container, key->str, g_strdup("Height")); } } else { gwy_container_set_string_by_name(container, key->str, g_strdup(colour_channels[ch])); g_string_printf(key, "/%d/base/palette", id); gwy_container_set_string_by_name (container, key->str, g_strdup(colour_channel_gradients[ch])); } gwy_file_channel_import_log_add(container, id, NULL, filename); id++; } } g_hash_table_destroy(hash); g_string_free(key, TRUE); g_free(comment); if (reader) { gwy_tiff_image_reader_free(reader); reader = NULL; } if (!container) err_NO_DATA(error); return container; }