static gboolean read_dimensions(GHashTable *hash, gint *ndata, Dimensions *dimensions, GError **error) { const gchar *value; /* Number of fields */ if (!(value = g_hash_table_lookup(hash, "Channels"))) { err_MISSING_FIELD(error, "Channels"); return FALSE; } *ndata = atoi(value); if (*ndata <= 0 || *ndata > 1024) { err_INVALID(error, "Channels"); return FALSE; } /* Pixel sizes */ if (!(value = g_hash_table_lookup(hash, "Lines"))) { err_MISSING_FIELD(error, "Lines"); return FALSE; } dimensions->yres = atoi(value); if (err_DIMENSION(error, dimensions->yres)) return FALSE; if (!(value = g_hash_table_lookup(hash, "Rows"))) { err_MISSING_FIELD(error, "Rows"); return FALSE; } /* XXX: When the file says Rows, it actually means Columns-1. Bite me. */ dimensions->xres = atoi(value) + 1; if (err_DIMENSION(error, dimensions->xres)) return FALSE; /* Real sizes */ if (!(value = g_hash_table_lookup(hash, "X-Length"))) { err_MISSING_FIELD(error, "X-Length"); return FALSE; } dimensions->xreal = Micrometer * g_ascii_strtod(value, NULL); if (!((dimensions->xreal = fabs(dimensions->xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); dimensions->xreal = 1.0; } if (!(value = g_hash_table_lookup(hash, "Y-Length"))) { err_MISSING_FIELD(error, "Y-Length"); return FALSE; } dimensions->yreal = Micrometer * g_ascii_strtod(value, NULL); if (!((dimensions->yreal = fabs(dimensions->yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); dimensions->yreal = 1.0; } return TRUE; }
static gboolean check_params(const SDFile *sdfile, guint len, GError **error) { if (sdfile->data_type >= SDF_NTYPES) { err_DATA_TYPE(error, sdfile->data_type); return FALSE; } if (err_DIMENSION(error, sdfile->xres) || err_DIMENSION(error, sdfile->yres)) return FALSE; if (err_SIZE_MISMATCH(error, sdfile->expected_size, len, FALSE)) return FALSE; if (sdfile->compression) { err_UNSUPPORTED(error, "Compression"); return FALSE; } if (sdfile->check_type) { err_UNSUPPORTED(error, "CheckType"); return FALSE; } return TRUE; }
static GwyDataField* mif_read_data_field(const MIFImageHeader *image_header, const MIFBlock *block, const guchar *buffer, gsize size, GError **error) { gint xres = image_header->setup.xres; gint yres = image_header->setup.yres; gdouble xreal = image_header->setup.xreal; gdouble yreal = image_header->setup.yreal; gdouble xoff = image_header->setup.xoff; gdouble yoff = image_header->setup.yoff; gdouble q = image_header->configuration.scan_int_to_meter; GwyDataField *dfield; gdouble *data; const gint16 *d16; gint i, j; if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; if (!block->size || block->offset > size || block->size > size || block->offset + block->size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Image data are outside the file.")); return NULL; } if (err_SIZE_MISMATCH(error, xres*yres*sizeof(gint16), block->size, FALSE)) return NULL; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_xoffset(dfield, xoff); gwy_data_field_set_yoffset(dfield, yoff); data = gwy_data_field_get_data(dfield); d16 = (const gint16*)(buffer + block->offset); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m"); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), "m"); // FIXME: Don't know why this factor. It seems to match what MIF spmview // profile reader shows though. q *= 1.0e4; for (i = 0; i < yres; i++) { for (j = 0; j < yres; j++) { data[(yres-1 - i)*xres + j] = q*GINT16_FROM_LE(d16[i*xres + j]); } } return dfield; }
static gboolean parse_dim(gchar **p, const gchar *name, gint *value, GError **error) { gchar *vp, *line; line = gwy_str_next_line(p); if (!line) { err_MISSING_FIELD(error, name); return FALSE; } vp = strchr(line, ':'); if (!vp) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); return FALSE; } *vp = '\0'; vp++; gwy_debug("<%s> = <%s>", name, vp); if (!gwy_strequal(line, name)) { err_MISSING_FIELD(error, name); return FALSE; } *value = strtol(vp, NULL, 10); if (err_DIMENSION(error, *value)) return FALSE; return TRUE; }
static guint read_pixel_size(GHashTable *hash, const gchar *key, GError **error) { gchar *value; guint size; if (!(value = g_hash_table_lookup(hash, key))) { err_MISSING_FIELD(error, key); return 0; } size = atoi(g_hash_table_lookup(hash, key)); if (err_DIMENSION(error, size)) return 0; return size; }
/* This is the main verification function that checks we have everything we * need and the data are of a supported type. */ static gboolean data_start(X3PFile *x3pfile, GError **error) { static const GwyEnum features[] = { { "SUR", X3P_FEATURE_SUR, }, { "PRF", X3P_FEATURE_PRF, }, { "PCL", X3P_FEATURE_PCL, }, }; gchar *s; if (x3pfile->values) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File main.xml contains multiple data elements.")); return FALSE; } /* First check axes to get meaningful error messages if their types are * not as expected. */ if (!require_keys(x3pfile->hash, error, "/ISO5436_2/Record1/FeatureType", AXES_PREFIX "/CX/AxisType", AXES_PREFIX "/CY/AxisType", AXES_PREFIX "/CZ/AxisType", NULL)) return FALSE; s = (gchar*)g_hash_table_lookup(x3pfile->hash, "/ISO5436_2/Record1/FeatureType"); if ((x3pfile->feature_type = gwy_string_to_enum(s, features, G_N_ELEMENTS(features))) == -1) { err_UNSUPPORTED(error, "/ISO5436_2/Record1/FeatureType"); return FALSE; } if (x3pfile->feature_type != X3P_FEATURE_SUR && x3pfile->feature_type != X3P_FEATURE_PRF) { err_UNSUPPORTED(error, "/ISO5436_2/Record1/FeatureType"); return FALSE; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CX/AxisType"); if (!gwy_strequal(s, "I")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, /* TRANSLATORS: type and axis are symbols such as I, CX, ...*/ _("Only type %s is supported for axis %s."), "I", "CX"); return FALSE; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CY/AxisType"); if (x3pfile->feature_type != X3P_FEATURE_PRF && !gwy_strequal(s, "I")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only type %s is supported for axis %s."), "I", "CY"); return FALSE; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CZ/AxisType"); if (!gwy_strequal(s, "A")) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only type %s is supported for axis %s."), "A", "CZ"); return FALSE; } /* Then check sizes, offsets and steps when we know the grid is regular. */ if (!require_keys(x3pfile->hash, error, AXES_PREFIX "/CX/Increment", AXES_PREFIX "/CY/Increment", AXES_PREFIX "/CX/Offset", AXES_PREFIX "/CY/Offset", MAT_DIM_PREFIX "/SizeX", MAT_DIM_PREFIX "/SizeY", MAT_DIM_PREFIX "/SizeZ", NULL)) return FALSE; s = (gchar*)g_hash_table_lookup(x3pfile->hash, MAT_DIM_PREFIX "/SizeX"); x3pfile->xres = atoi(s); s = (gchar*)g_hash_table_lookup(x3pfile->hash, MAT_DIM_PREFIX "/SizeY"); x3pfile->yres = atoi(s); s = (gchar*)g_hash_table_lookup(x3pfile->hash, MAT_DIM_PREFIX "/SizeZ"); x3pfile->zres = atoi(s); gwy_debug("xres=%u, yres=%u, zres=%u", x3pfile->xres, x3pfile->yres, x3pfile->zres); if (err_DIMENSION(error, x3pfile->xres) || err_DIMENSION(error, x3pfile->yres) || err_DIMENSION(error, x3pfile->zres)) return FALSE; /* PRF feature types are sets of profiles N×1×M. */ if (x3pfile->feature_type == X3P_FEATURE_PRF && x3pfile->yres != 1) { err_UNSUPPORTED(error, MAT_DIM_PREFIX "/SizeY"); return FALSE; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CX/Increment"); x3pfile->dx = g_ascii_strtod(s, NULL); if (!((x3pfile->dx = fabs(x3pfile->dx)) > 0)) { g_warning("Real x step is 0.0, fixing to 1.0"); x3pfile->dx = 1.0; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CY/Increment"); x3pfile->dy = g_ascii_strtod(s, NULL); if (!((x3pfile->dy = fabs(x3pfile->dy)) > 0)) { g_warning("Real x step is 0.0, fixing to 1.0"); x3pfile->dy = 1.0; } s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CX/Offset"); x3pfile->xoff = g_ascii_strtod(s, NULL); s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CY/Offset"); x3pfile->yoff = g_ascii_strtod(s, NULL); /* Defaults that are good for floating point data conversion. If a file * with floating point data specifies Increment and Offset, we apply them * without hesitation. The behaviour is probably undefined. */ x3pfile->dz = 1.0; x3pfile->zoff = 0.0; s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CZ/Increment"); if (s) x3pfile->dz = g_ascii_strtod(s, NULL); s = (gchar*)g_hash_table_lookup(x3pfile->hash, AXES_PREFIX "/CZ/Offset"); if (s) x3pfile->zoff = g_ascii_strtod(s, NULL); gwy_debug("dz=%g, zoff=%g", x3pfile->dz, x3pfile->zoff); x3pfile->ndata = x3pfile->xres*x3pfile->yres*x3pfile->zres; x3pfile->values = g_new(gdouble, x3pfile->ndata); x3pfile->valid = g_new(gboolean, x3pfile->ndata); x3pfile->datapos = 0; return TRUE; }
static GwyContainer* plt_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; GwyDataField *dfield = NULL; GwyTextHeaderParser parser; GwySIUnit *xunit, *yunit, *zunit; gchar *p, *value, *buffer = NULL; GHashTable *hash = NULL; gsize size; GError *err = NULL; G_GNUC_UNUSED gdouble xreal, yreal, zreal; gint i, xres, yres; gdouble *data; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } if (strncmp(buffer, MAGIC1, MIN(size, sizeof(MAGIC1)-1))) { err_FILE_TYPE(error, "Nanosurf PLT"); goto fail; } /* Find the first line not starting with '#' */ for (p = buffer; (p - buffer) + 1 < size; p++) { if ((p[0] == '\n' || p[0] == '\r') && (p[1] != '\n' && p[1] != '#')) { break; } } *p = '\0'; p++; gwy_clear(&parser, 1); parser.line_prefix = "#"; parser.key_value_separator = ":"; hash = gwy_text_header_parse(buffer, &parser, NULL, NULL); if (!require_keys(hash, error, "Channel", "Lines", "Points", "XRange", "YRange", "ZRange", NULL)) goto fail; xres = atoi(g_hash_table_lookup(hash, "Points")); yres = atoi(g_hash_table_lookup(hash, "Lines")); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; value = g_hash_table_lookup(hash, "XRange"); xreal = g_ascii_strtod(value, &value); xunit = gwy_si_unit_new(value); value = g_hash_table_lookup(hash, "YRange"); yreal = g_ascii_strtod(value, &value); yunit = gwy_si_unit_new(value); value = g_hash_table_lookup(hash, "ZRange"); zreal = g_ascii_strtod(value, &value); zunit = gwy_si_unit_new(value); /* 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; } if (!gwy_si_unit_equal(xunit, yunit)) g_warning("X and Y units differ, using X"); dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_si_unit_xy(dfield, xunit); gwy_data_field_set_si_unit_z(dfield, zunit); g_object_unref(xunit); g_object_unref(yunit); g_object_unref(zunit); data = gwy_data_field_get_data(dfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = g_ascii_strtod(value, &p); value = p; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if ((value = g_hash_table_lookup(hash, "Channel"))) 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: g_free(buffer); g_hash_table_destroy(hash); return container; }
static GwyDataField* read_data_field(const guchar *buffer, guint size, guchar version, gchar **title, gint *direction, GError **error) { enum { MIN_REMAINDER = 2620 }; /* information offsets in different versions, in r5+ relative to data * start, in order: * data offset, * pixel dimensions, * physical dimensions, * value multiplier, * unit string, * data type, (if zero, use channel title) * channel title (if zero, use data type) */ const guint offsets34[] = { 0x0104, 0x0196, 0x01a2, 0x01b2, 0x01c2, 0x0400, 0x0000 }; const guint offsets56[] = { 0x0104, 0x025c, 0x0268, 0x0288, 0x02a0, 0x0708, 0x0000 }; const guint offsets7[] = { 0x0104, 0x029c, 0x02a8, 0x02c8, 0x02e0, 0x0000, 0x0b90 }; gint xres, yres, doffset, i, power10, type; gdouble xreal, yreal, q, z0; GwyDataField *dfield; GwySIUnit *unitxy, *unitz; gdouble *data; const guint *offset; const guchar *p, *r, *last; /* get floats in single precision from r4 but double from r5+ */ gdouble (*getflt)(const guchar**); *title = NULL; *direction = -1; if (version == '5' || version == '6' || version == '7') { /* There are more headers in r5, * try to find something that looks like #R5. */ last = r = buffer; while ((p = memchr(r, '#', size - (r - buffer) - MIN_REMAINDER))) { if (p[1] == 'R' && p[2] == version && p[3] == '.') { gwy_debug("pos: %ld", (long)(p - buffer)); last = p; r = p + MIN_REMAINDER-1; } else r = p + 1; } offset = (version == '7') ? &offsets7[0] : &offsets56[0]; buffer = last; getflt = &gwy_get_gdouble_le; } else { offset = &offsets34[0]; getflt = &get_gfloat_le_as_double; } p = buffer + *(offset++); doffset = gwy_get_guint32_le(&p); /* this appears to be the same number as in the ASCII miniheader -- so get it here since it's easier */ gwy_debug("data offset = %u", doffset); p = buffer + *(offset++); xres = gwy_get_guint32_le(&p); yres = gwy_get_guint32_le(&p); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; p = buffer + *(offset++); xreal = -getflt(&p); xreal += getflt(&p); yreal = -getflt(&p); yreal += getflt(&p); 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; } p = buffer + *(offset++); q = getflt(&p); z0 = getflt(&p); gwy_debug("xreal.raw = %g, yreal.raw = %g, q.raw = %g, z0.raw = %g", xreal, yreal, q, z0); p = buffer + *(offset++); unitz = gwy_si_unit_new_parse(p, &power10); q *= pow10(power10); z0 *= pow10(power10); unitxy = gwy_si_unit_new_parse(p + 10, &power10); xreal *= pow10(power10); yreal *= pow10(power10); gwy_debug("xres = %d, yres = %d, xreal = %g, yreal = %g, q = %g, z0 = %g", xres, yres, xreal, yreal, q, z0); gwy_debug("unitxy = %s, unitz = %s", p, p + 10); if (offset[1]) { /* We know channel title */ offset++; p = buffer + *(offset++); *title = g_strndup(p, size - (p - buffer)); gwy_debug("title = <%s>", *title); } else { /* We know data type */ p = buffer + *(offset++); type = gwy_get_guint16_le(&p); *direction = gwy_get_guint16_le(&p); gwy_debug("type = %d, dir = %d", type, *direction); offset++; *title = type_to_title(type); } p = buffer + doffset; if (err_SIZE_MISMATCH(error, 2*xres*yres, size - (p - buffer), FALSE)) return NULL; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_si_unit_xy(dfield, unitxy); g_object_unref(unitxy); gwy_data_field_set_si_unit_z(dfield, unitz); g_object_unref(unitz); data = gwy_data_field_get_data(dfield); for (i = 0; i < xres*yres; i++) data[i] = (p[2*i] + 256.0*p[2*i + 1])*q + z0; return dfield; }
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* hitachi_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta; GdkPixbuf *pixbuf = NULL; GwyDataField *dfield = NULL; gchar *value, *imagename = NULL, *header = NULL; guchar *pixels; GHashTable *hash = NULL; GError *err = NULL; gdouble dx; gint pxres, pyres, hxres, hyres, rowstride, nchannels, i, j; gdouble *data; if (!(hash = hitachi_load_header(filename, &header, error))) return NULL; if (!require_keys(hash, error, "ImageName", "DataSize", "PixelSize", NULL)) goto fail; value = g_hash_table_lookup(hash, "ImageName"); if (!(imagename = hitachi_find_data_name(filename, value))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("No corresponding data file was found for header file.")); goto fail; } if (!(pixbuf = gdk_pixbuf_new_from_file(imagename, &err))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_IO, _("Cannot load image: %s"), err->message); g_clear_error(&err); goto fail; } /* We know the image dimensions so check them. */ pxres = gdk_pixbuf_get_width(pixbuf); pyres = gdk_pixbuf_get_height(pixbuf); value = g_hash_table_lookup(hash, "DataSize"); if (sscanf(value, "%ux%u", &hxres, &hyres) != 2) { err_INVALID(error, "DataSize"); goto fail; } if (hxres != pxres || hyres != pyres) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Field DataSize %ux%u does not match image dimensions " "%ux%u."), hxres, hyres, pxres, pyres); goto fail; } if (err_DIMENSION(error, hxres) || err_DIMENSION(error, hyres)) goto fail; dx = g_ascii_strtod(g_hash_table_lookup(hash, "PixelSize"), NULL); /* Use negated positive conditions to catch NaNs */ if (!((dx = fabs(dx)) > 0)) { g_warning("Pixel size is 0.0, fixing to 1.0"); dx = 1.0; } dx *= Nanometre; dfield = gwy_data_field_new(hxres, hyres, hxres*dx, hyres*dx, FALSE); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m"); data = gwy_data_field_get_data(dfield); pixels = gdk_pixbuf_get_pixels(pixbuf); rowstride = gdk_pixbuf_get_rowstride(pixbuf); nchannels = gdk_pixbuf_get_n_channels(pixbuf); for (i = 0; i < hyres; i++) { gdouble *drow = data + i*hxres; guchar *p = pixels + i*rowstride; for (j = 0; j < hxres; j++, p += nchannels) drow[j] = (p[0] + p[1] + p[2])/765.0; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if ((value = g_hash_table_lookup(hash, "SampleName")) && *value) gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(value)); else gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("SEM")); meta = gwy_container_new(); g_hash_table_foreach(hash, store_meta, meta); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: gwy_object_unref(pixbuf); g_free(imagename); g_free(header); g_hash_table_destroy(hash); return container; }
static 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* 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 GwyDataField* mif_read_data_field(const MIFImageHeader *image_header, const MIFBlock *block, const guchar *buffer, gsize size, GError **error) { const MIFScanSetup *setup = &image_header->setup; const MIFImageConfiguration *configuration = &image_header->configuration; gint xres = setup->xres; gint yres = setup->yres; gdouble xreal = setup->xreal * image_header->configuration.xcal; gdouble yreal = setup->yreal * image_header->configuration.ycal; gdouble xoff = setup->xoff; gdouble yoff = setup->yoff; gdouble q = configuration->zcal/65536.0; GwyDataField *dfield; gdouble *data, *linecorrdata = NULL; gsize datasize; const gint16 *d16; gint i, j; if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; if (!block->size || block->offset > size || block->size > size || block->offset + block->size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Image data are outside the file.")); return NULL; } datasize = xres*yres*sizeof(gint16); if (err_SIZE_MISMATCH(error, datasize, block->size, FALSE)) return NULL; if (datasize + yres*sizeof(gint16) <= block->size) { gwy_debug("There may be %u correction data after the image.", yres); linecorrdata = g_new(gdouble, yres); d16 = (const gint16*)(buffer + block->offset + datasize); for (i = 0; i < yres; i++) { linecorrdata[i] = pow(2.0, d16[i] - 13); gwy_debug("corr[%u] %g", i, linecorrdata[i]); } } dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_xoffset(dfield, xoff); gwy_data_field_set_yoffset(dfield, yoff); data = gwy_data_field_get_data(dfield); d16 = (const gint16*)(buffer + block->offset); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(dfield), "m"); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), "m"); // XXX: Don't know why this range. A user got it from DME. Have no idea // why scan_int_to_meter does not appear here. if (!configuration->z_linearized) q *= 15e-6; else q *= 20e-6; for (i = 0; i < yres; i++) { gdouble qi = linecorrdata ? q*linecorrdata[i] : q; for (j = 0; j < yres; j++) { data[(yres-1 - i)*xres + j] = qi*GINT16_FROM_LE(d16[i*xres + j]); } } g_free(linecorrdata); return dfield; }
static GwyDataField* sensofar_read_data_field(SensofarDataDesc *data_desc, GwyDataField **maskfield, const guchar **p, gsize size, GError **error) { GwyDataField *dfield, *mfield; guint xres, yres, i, j, mcount; GwySIUnit *units = NULL; gdouble *data, *mdata; if (maskfield) *maskfield = NULL; yres = gwy_get_guint32_le(p); 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; } if (!((data_desc->axes_config.mppy = fabs(data_desc->axes_config.mppy)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); data_desc->axes_config.mppy = 1.0; } dfield = gwy_data_field_new(xres, yres, data_desc->axes_config.mppx * xres * Micrometer, data_desc->axes_config.mppy * yres * Micrometer, FALSE); units = gwy_si_unit_new("m"); // values are in um only gwy_data_field_set_si_unit_xy(dfield, units); g_object_unref(units); units = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, units); g_object_unref(units); mfield = gwy_data_field_new_alike(dfield, FALSE); gwy_data_field_fill(mfield, 1.0); data = gwy_data_field_get_data(dfield); mdata = gwy_data_field_get_data(mfield); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { gdouble v = gwy_get_gfloat_le(p); if (v == 1000001.0) mdata[i*xres + j] = 0.0; else data[i*xres + j] = v*Micrometer; } } gwy_debug("Offset: %g %g", data_desc->axes_config.x_0, data_desc->axes_config.y_0); //FIXME: offset later, support of offset determined by version? //gwy_data_field_set_xoffset(d, pow10(power10)*data_desc.axes_config.x_0); //gwy_data_field_set_yoffset(d, pow10(power10)*data_desc.axes_config.y_0); mcount = gwy_app_channel_remove_bad_data(dfield, mfield); if (maskfield && mcount) *maskfield = mfield; else g_object_unref(mfield); return dfield; }
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* 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* 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 gboolean rhkspm32_read_header(RHKPage *rhkpage, GError **error) { const gchar *buffer; gchar *end; guint pos; buffer = rhkpage->buffer; rhkpage->date = g_strstrip(g_strndup(buffer + MAGIC_SIZE, 0x20 - MAGIC_SIZE)); if (sscanf(buffer + 0x20, "%d %d %d %d %d %d %d", (gint*)&rhkpage->type, (gint*)&rhkpage->data_type, &rhkpage->line_type, &rhkpage->xres, &rhkpage->yres, &rhkpage->size, (gint*)&rhkpage->page_type) != 7) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Invalid file header.")); return FALSE; } gwy_debug("type = %u, data = %u, line = %u, image = %u", rhkpage->type, rhkpage->data_type, rhkpage->line_type, rhkpage->page_type); gwy_debug("xres = %d, yres = %d", rhkpage->xres, rhkpage->yres); if (err_DIMENSION(error, rhkpage->xres) || err_DIMENSION(error, rhkpage->yres)) return FALSE; if (!((rhkpage->type == RHK_TYPE_IMAGE) || (rhkpage->type == RHK_TYPE_LINE))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only image and line files are supported.")); return FALSE; } if ((rhkpage->type == RHK_TYPE_IMAGE) && (rhkpage->data_type != RHK_DATA_INT16)) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Invalid data type %d for image data."), rhkpage->data_type); return FALSE; } if ((rhkpage->type == RHK_TYPE_LINE) && !((rhkpage->data_type == RHK_DATA_INT16) || (rhkpage->data_type == RHK_DATA_SINGLE))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Invalid data type %d for line data."), rhkpage->data_type); return FALSE; } if ((rhkpage->data_type) == RHK_DATA_INT8) rhkpage->item_size = 1; else if ((rhkpage->data_type) == RHK_DATA_INT16) rhkpage->item_size = 2; else if ((rhkpage->data_type) == RHK_DATA_INT32) rhkpage->item_size = 4; else if ((rhkpage->data_type) == RHK_DATA_SINGLE) rhkpage->item_size = 4; //rhkpage->item_size = rhkpage->data_type; // niv if (!rhkspm32_read_range(buffer + 0x40, "X", &rhkpage->x) || !rhkspm32_read_range(buffer + 0x60, "Y", &rhkpage->y) || !rhkspm32_read_range(buffer + 0x80, "Z", &rhkpage->z)) { err_INVALID(error, _("data ranges")); return FALSE; } /* Use negated positive conditions to catch NaNs */ // niv - modifying this - otherwise it messes with the spectra // (but i don;t really understand it) if (!((fabs(rhkpage->x.scale)) > 0)) { g_warning("Real x scale is 0.0, fixing to 1.0"); rhkpage->x.scale = 1.0; } if (!((fabs(rhkpage->y.scale)) > 0)) { /* The y scale seem unused for non-image data */ if (rhkpage->type == RHK_TYPE_IMAGE) g_warning("Real y scale is 0.0, fixing to 1.0"); rhkpage->y.scale = 1.0; } if (!g_str_has_prefix(buffer + 0xa0, "XY ")) { err_MISSING_FIELD(error, "XY"); return FALSE; } pos = 0xa0 + sizeof("XY"); rhkpage->xyskew = g_ascii_strtod(buffer + pos, &end); if (end == buffer + pos) { err_INVALID(error, "XY"); return FALSE; } pos = (end - buffer) + 2; /* Don't check failure, it seems the value is optional */ rhkpage->alpha = g_ascii_strtod(buffer + pos, &end); // not failing, but setting an existance flag, this happens for spectra, // but otherwise i want to add this to the metadata if (end == buffer + pos) rhkpage->e_alpha = FALSE; else rhkpage->e_alpha = TRUE; if (!rhkspm32_read_range(buffer + 0xc0, "IV", &rhkpage->iv)) { err_INVALID(error, "IV"); return FALSE; } if (g_str_has_prefix(buffer + 0xe0, "scan ")) pos = 0xe0 + sizeof("scan"); rhkpage->scan = strtol(buffer + pos, &end, 10); if (end == buffer + pos) { err_INVALID(error, "scan"); return FALSE; } pos = (end - buffer); rhkpage->period = g_ascii_strtod(buffer + pos, &end); if (end == buffer + pos) { err_INVALID(error, "period"); return FALSE; } if (sscanf(buffer + 0x100, "id %u %u", &rhkpage->id, &rhkpage->data_offset) != 2) { /* XXX: Some braindamaged files encountered in practice do not contain * the data offset. Cross fingers and substitute HEADER_SIZE. */ g_warning("Data offset is missing, just guessing from now..."); rhkpage->id = 0; rhkpage->data_offset = HEADER_SIZE; } gwy_debug("data_offset = %u", rhkpage->data_offset); if (rhkpage->data_offset < HEADER_SIZE) { err_INVALID(error, _("data offset")); return FALSE; } /* XXX: The same braindamaged files overwrite the label and comment part * with some XML mumbo jumbo. Sigh and ignore it. */ if (strncmp(buffer + 0x140, "\x0d\x0a<?", 4) != 0) { rhkpage->label = g_strstrip(g_strndup(buffer + 0x140, 0x20)); rhkpage->comment = g_strstrip(g_strndup(buffer + 0x160, HEADER_SIZE - 0x160)); } return TRUE; }
static gboolean get_scales(GHashTable *hash, gboolean is_text, gint *xres, gint *yres, gdouble *xreal, gdouble *yreal, gdouble *xoff, gdouble *yoff, GwySIUnit *si_unit_xy, gdouble *zscale, gdouble *zoff, GwySIUnit *si_unit_z, GError **error) { GwySIUnit *unit; gint power10, zp; gchar *p; gboolean has_unit = FALSE; /* Dimensions are mandatory. */ if (!require_keys(hash, error, "SCANNING PARAMS::PixelsX", "SCANNING PARAMS::PixelsY", "SCANNING PARAMS::PixelsZ", "SCANNING PARAMS::SizeX", "SCANNING PARAMS::SizeY", "SCANNING PARAMS::SizeZ", NULL)) return FALSE; *xres = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsX")); if (err_DIMENSION(error, *xres)) return FALSE; *yres = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsY")); if (err_DIMENSION(error, *yres)) return FALSE; unit = gwy_si_unit_new(NULL); p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeX"); *xreal = fabs(g_ascii_strtod(p, &p)); if (!*xreal) { g_warning("Real x size is 0.0, fixing to 1.0"); *xreal = 1.0; } gwy_si_unit_set_from_string_parse(si_unit_xy, p, &power10); *xreal *= pow10(power10); p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeY"); *yreal = fabs(g_ascii_strtod(p, &p)); if (!*yreal) { g_warning("Real y size is 0.0, fixing to 1.0"); *yreal = 1.0; } gwy_si_unit_set_from_string_parse(unit, p, &power10); *yreal *= pow10(power10); if (!gwy_si_unit_equal(unit, si_unit_xy)) { g_warning("X and Y units differ, using X"); } zp = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsZ")); if (!zp) { g_warning("Z pixels is 0, fixing to 1"); zp = 1; } p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeZ"); *zscale = g_ascii_strtod(p, &p); *zoff = 0.0; gwy_si_unit_set_from_string_parse(si_unit_z, p, &power10); *zscale *= pow10(power10)/zp; /* XXX: Version 4 can have UNIT section that takes precedence. The Conv * factor may not be enough. Apparently, binary phase data need * subtracting 180 deg because data are unsinged. Bite me. */ if ((p = g_hash_table_lookup(hash, "UNIT::Unit"))) { const gchar *s = g_hash_table_lookup(hash, "UNIT::Name"); has_unit = TRUE; gwy_si_unit_set_from_string_parse(si_unit_z, p, &power10); *zscale *= pow10(power10); if ((p = g_hash_table_lookup(hash, "UNIT::Conv"))) *zscale *= g_ascii_strtod(p, NULL); if (!is_text && gwy_strequal(s, "Phase")) *zoff = -180.0; } /* Offsets are optional. */ *xoff = 0.0; if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetX"))) { *xoff = g_ascii_strtod(p, &p); gwy_si_unit_set_from_string_parse(unit, p, &power10); if (gwy_si_unit_equal(unit, si_unit_xy)) *xoff *= pow10(power10); else { g_warning("X offset units differ from X size units, ignoring."); *xoff = 0.0; } } *yoff = 0.0; if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetY"))) { *yoff = g_ascii_strtod(p, &p); gwy_si_unit_set_from_string_parse(unit, p, &power10); if (gwy_si_unit_equal(unit, si_unit_xy)) *yoff *= pow10(power10); else { g_warning("Y offset units differ from Y size units, ignoring."); *yoff = 0.0; } } // Don't know what to do with the offset when UNIT section is present. // It seems to be always 0 in wrong units, so skip it. if (!has_unit) { if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetZ"))) { *zoff = g_ascii_strtod(p, &p); gwy_si_unit_set_from_string_parse(unit, p, &power10); if (gwy_si_unit_equal(unit, si_unit_z)) *zoff *= pow10(power10); else { g_warning("Z offset units differ from Z size units, ignoring."); *zoff = 0.0; } } } g_object_unref(unit); return TRUE; }
static GwyContainer* asc_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; GwyDataField *dfield = NULL, *mfield = NULL; GwyTextHeaderParser parser; GwySIUnit *unit; gchar *line, *p, *value, *buffer = NULL; GHashTable *hash = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal, q; gint i, xres, yres; gdouble *data; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } p = buffer; line = gwy_str_next_line(&p); if (!gwy_strequal(line, MAGIC_BARE)) { err_FILE_TYPE(error, "SPIP ASCII data"); goto fail; } gwy_clear(&parser, 1); parser.line_prefix = "#"; parser.key_value_separator = "="; parser.terminator = "# Start of Data:"; parser.error = &header_error; parser.end = &header_end; if (!(hash = gwy_text_header_parse(p, &parser, &p, &err))) { g_propagate_error(error, err); goto fail; } if (!require_keys(hash, error, "x-pixels", "y-pixels", "x-length", "y-length", NULL)) goto fail; xres = atoi(g_hash_table_lookup(hash, "x-pixels")); yres = atoi(g_hash_table_lookup(hash, "y-pixels")); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; xreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "x-length"), NULL); yreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "y-length"), NULL); /* 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; } dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); if ((value = g_hash_table_lookup(hash, "z-unit"))) { gint power10; unit = gwy_si_unit_new_parse(value, &power10); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); q = pow10(power10); } else if ((value = g_hash_table_lookup(hash, "Bit2nm"))) { q = Nanometer * g_ascii_strtod(value, NULL); unit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); } else q = 1.0; data = gwy_data_field_get_data(dfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = q*g_ascii_strtod(value, &p); if (p == value && (!*p || g_ascii_isspace(*p))) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached when reading sample #%d of %d"), i, xres*yres); goto fail; } if (p == value) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Malformed data encountered when reading sample " "#%d of %d"), i, xres*yres); goto fail; } value = p; } if ((value = g_hash_table_lookup(hash, "voidpixels")) && atoi(value)) { mfield = gwy_data_field_new_alike(dfield, FALSE); data = gwy_data_field_get_data(mfield); value = p; for (i = 0; i < xres*yres; i++) { data[i] = 1.0 - g_ascii_strtod(value, &p); value = p; } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) GWY_OBJECT_UNREF(mfield); } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: GWY_OBJECT_UNREF(dfield); g_free(buffer); if (hash) g_hash_table_destroy(hash); return container; }
static gboolean read_parameters(const guchar *buffer, guint size, StmprgFile *stmprgfile, GError **error) { const guchar *p = buffer + MAGIC_SIZE; StmprgMainfield *mainfield; StmprgControl *control; StmprgOtherControl *other_control; gwy_debug("tp file size is %u, expecting %u", size, PARAM_SIZE); if (size < PARAM_SIZE) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Parameter file is too short.")); return FALSE; } /* mainfield */ mainfield = &stmprgfile->mainfield; mainfield->start_x = gwy_get_gfloat_be(&p); mainfield->start_y = gwy_get_gfloat_be(&p); mainfield->field_x = gwy_get_gfloat_be(&p); mainfield->field_y = gwy_get_gfloat_be(&p); mainfield->inc_x = gwy_get_gfloat_be(&p); mainfield->inc_y = gwy_get_gfloat_be(&p); mainfield->points = gwy_get_gint32_be(&p); mainfield->lines = gwy_get_gint32_be(&p); mainfield->angle = gwy_get_gfloat_be(&p); mainfield->sol_x = gwy_get_gfloat_be(&p); mainfield->sol_y = gwy_get_gfloat_be(&p); mainfield->sol_z = gwy_get_gfloat_be(&p); mainfield->sol_ext1 = gwy_get_gfloat_be(&p); mainfield->sol_ext2 = gwy_get_gfloat_be(&p); mainfield->sol_h = gwy_get_gfloat_be(&p); g_assert(p - buffer == MAGIC_SIZE + MAINFIELD_SIZE); gwy_debug("start_x = %g", mainfield->start_x); gwy_debug("start_y = %g", mainfield->start_y); gwy_debug("field_x = %g", mainfield->field_x); gwy_debug("field_y = %g", mainfield->field_y); gwy_debug("inc_x = %g", mainfield->inc_x); gwy_debug("inc_y = %g", mainfield->inc_y); gwy_debug("points = %d", mainfield->points); gwy_debug("lines = %d", mainfield->lines); gwy_debug("angle = %g", mainfield->angle); gwy_debug("sol_x = %g", mainfield->sol_x); gwy_debug("sol_y = %g", mainfield->sol_y); gwy_debug("sol_z = %g", mainfield->sol_z); gwy_debug("sol_ext1 = %g", mainfield->sol_ext1); gwy_debug("sol_ext2 = %g", mainfield->sol_ext2); gwy_debug("sol_h = %g", mainfield->sol_h); if (err_DIMENSION(error, mainfield->points) || err_DIMENSION(error, mainfield->lines)) return FALSE; /* control */ control = &stmprgfile->control; control->mode = *(p++); control->channel1 = *(p++); control->channel2 = *(p++); control->channel3 = *(p++); control->spectr = *(p++); control->cfree = *(p++); control->type = gwy_get_gint16_be(&p); control->steps_x = gwy_get_gint32_be(&p); control->steps_y = gwy_get_gint32_be(&p); control->dac_speed = gwy_get_gint32_be(&p); control->poi_inc = gwy_get_gfloat_be(&p); control->lin_inc = gwy_get_gfloat_be(&p); control->ad1_reads = gwy_get_gint32_be(&p); control->ad2_reads = gwy_get_gint32_be(&p); control->ad3_reads = gwy_get_gint32_be(&p); control->analog_ave = gwy_get_gint32_be(&p); control->speed = gwy_get_gint32_be(&p); control->voltage = gwy_get_gfloat_be(&p); control->voltage_l = gwy_get_gfloat_be(&p); control->voltage_r = gwy_get_gfloat_be(&p); control->volt_flag = gwy_get_gint32_be(&p); control->volt_region = gwy_get_gint32_be(&p); control->current = gwy_get_gfloat_be(&p); control->current_l = gwy_get_gfloat_be(&p); control->current_r = gwy_get_gfloat_be(&p); control->curr_flag = gwy_get_gint32_be(&p); control->curr_region = gwy_get_gint32_be(&p); control->spec_lstart = gwy_get_gfloat_be(&p); control->spec_lend = gwy_get_gfloat_be(&p); control->spec_linc = gwy_get_gfloat_be(&p); control->spec_lsteps = gwy_get_guint32_be(&p); control->spec_rstart = gwy_get_gfloat_be(&p); control->spec_rend = gwy_get_gfloat_be(&p); control->spec_rinc = gwy_get_gfloat_be(&p); control->spec_rsteps = gwy_get_guint32_be(&p); control->version = gwy_get_gfloat_be(&p); control->free_lend = gwy_get_gfloat_be(&p); control->free_linc = gwy_get_gfloat_be(&p); control->free_lsteps = gwy_get_guint32_be(&p); control->free_rstart = gwy_get_gfloat_be(&p); control->free_rend = gwy_get_gfloat_be(&p); control->free_rinc = gwy_get_gfloat_be(&p); control->free_rsteps = gwy_get_guint32_be(&p); control->timer1 = gwy_get_guint32_be(&p); control->timer2 = gwy_get_guint32_be(&p); control->timer3 = gwy_get_guint32_be(&p); control->timer4 = gwy_get_guint32_be(&p); control->m_time = gwy_get_guint32_be(&p); control->u_divider = gwy_get_gfloat_be(&p); control->fb_control = gwy_get_gint32_be(&p); control->fb_delay = gwy_get_gint32_be(&p); control->point_time = gwy_get_gint32_be(&p); control->spec_time = gwy_get_gint32_be(&p); control->spec_delay = gwy_get_gint32_be(&p); control->fm = gwy_get_gint16_be(&p); control->fm_prgmode = gwy_get_gint16_be(&p); control->fm_channel1 = gwy_get_gint32_be(&p); control->fm_channel2 = gwy_get_gint32_be(&p); control->fm_wait = gwy_get_gint32_be(&p); control->fm_frames = gwy_get_gint32_be(&p); control->fm_delay = gwy_get_gint16_be(&p); control->spectr_edit = gwy_get_gint16_be(&p); control->fm_speed = gwy_get_gint16_be(&p); control->fm_reads = gwy_get_gint16_be(&p); g_assert(p - buffer == MAGIC_SIZE + MAINFIELD_SIZE + CONTROL_SIZE); gwy_debug("type = %d", control->type); gwy_debug("steps_x = %d", control->steps_x); gwy_debug("steps_y = %d", control->steps_y); gwy_debug("dac_speed = %d", control->dac_speed); gwy_debug("poi_inc = %g", control->poi_inc); gwy_debug("lin_inc = %g", control->lin_inc); gwy_debug("ad1_reads = %d", control->ad1_reads); gwy_debug("ad2_reads = %d", control->ad2_reads); gwy_debug("ad3_reads = %d", control->ad3_reads); gwy_debug("analog_ave = %d", control->analog_ave); gwy_debug("speed = %d", control->speed); gwy_debug("voltage = %g", control->voltage); gwy_debug("voltage_l = %g", control->voltage_l); gwy_debug("voltage_r = %g", control->voltage_r); gwy_debug("volt_flag = %d", control->volt_flag); gwy_debug("volt_region = %d", control->volt_region); gwy_debug("current = %g", control->current); gwy_debug("current_l = %g", control->current_l); gwy_debug("current_r = %g", control->current_r); gwy_debug("curr_flag = %d", control->curr_flag); gwy_debug("curr_region = %d", control->curr_region); gwy_debug("spec_lstart = %g", control->spec_lstart); gwy_debug("spec_lend = %g", control->spec_lend); gwy_debug("spec_linc = %g", control->spec_linc); gwy_debug("spec_lsteps = %u", control->spec_lsteps); gwy_debug("spec_rstart = %g", control->spec_rstart); gwy_debug("spec_rend = %g", control->spec_rend); gwy_debug("spec_rinc = %g", control->spec_rinc); gwy_debug("spec_rsteps = %u", control->spec_rsteps); gwy_debug("version = %g", control->version); gwy_debug("free_lend = %g", control->free_lend); gwy_debug("free_linc = %g", control->free_linc); gwy_debug("free_lsteps = %u", control->free_lsteps); gwy_debug("free_rstart = %g", control->free_rstart); gwy_debug("free_rend = %g", control->free_rend); gwy_debug("free_rinc = %g", control->free_rinc); gwy_debug("free_rsteps = %u", control->free_rsteps); gwy_debug("timer1 = %u", control->timer1); gwy_debug("timer2 = %u", control->timer2); gwy_debug("timer3 = %u", control->timer3); gwy_debug("timer4 = %u", control->timer4); gwy_debug("m_time = %u", control->m_time); gwy_debug("u_divider = %g", control->u_divider); gwy_debug("fb_control = %d", control->fb_control); gwy_debug("fb_delay = %d", control->fb_delay); gwy_debug("point_time = %d", control->point_time); gwy_debug("spec_time = %d", control->spec_time); gwy_debug("spec_delay = %d", control->spec_delay); gwy_debug("fm = %d", control->fm); gwy_debug("fm_prgmode = %d", control->fm_prgmode); gwy_debug("fm_channel1 = %d", control->fm_channel1); gwy_debug("fm_channel2 = %d", control->fm_channel2); gwy_debug("fm_wait = %d", control->fm_wait); gwy_debug("fm_frames = %d", control->fm_frames); gwy_debug("fm_delay = %d", control->fm_delay); gwy_debug("spectr_edit = %d", control->spectr_edit); gwy_debug("fm_speed = %d", control->fm_speed); gwy_debug("fm_reads = %d", control->fm_reads); /* other_control */ other_control = &stmprgfile->other_control; other_control->version = gwy_get_gfloat_be(&p); other_control->adc_data_l = gwy_get_gint32_be(&p); other_control->adc_data_r = gwy_get_gint32_be(&p); other_control->first_zp = gwy_get_gint16_be(&p); other_control->last_zp = gwy_get_gint16_be(&p); other_control->zdrift = gwy_get_gfloat_be(&p); other_control->savememory = gwy_get_gint32_be(&p); get_CHARARRAY0(other_control->date, &p); get_CHARARRAY0(other_control->comment, &p); get_CHARARRAY0(other_control->username, &p); get_CHARARRAY0(other_control->macro_file, &p); get_CHARARRAY0(other_control->cext_a, &p); get_CHARARRAY0(other_control->cext_b, &p); other_control->contscan = gwy_get_gint32_be(&p); other_control->spec_loop = gwy_get_gint32_be(&p); other_control->ext_c = gwy_get_gint32_be(&p); other_control->fm_zlift = gwy_get_gfloat_be(&p); other_control->ext_a = gwy_get_gint32_be(&p); other_control->vme_release = gwy_get_gfloat_be(&p); g_assert(p - buffer == PARAM_SIZE); gwy_debug("version = %g", other_control->version); gwy_debug("adc_data_l = %d", other_control->adc_data_l); gwy_debug("adc_data_r = %d", other_control->adc_data_r); gwy_debug("first_zp = %d", other_control->first_zp); gwy_debug("last_zp = %d", other_control->last_zp); gwy_debug("zdrift = %g", other_control->zdrift); gwy_debug("savememory = %d", other_control->savememory); gwy_debug("date = %s", other_control->date); gwy_debug("comment = %s", other_control->comment); gwy_debug("username = %s", other_control->username); gwy_debug("macro_file = %s", other_control->macro_file); gwy_debug("cext_a = %s", other_control->cext_a); gwy_debug("cext_b = %s", other_control->cext_b); gwy_debug("contscan = %d", other_control->contscan); gwy_debug("spec_loop = %d", other_control->spec_loop); gwy_debug("ext_c = %d", other_control->ext_c); gwy_debug("fm_zlift = %g", other_control->fm_zlift); gwy_debug("ext_a = %d", other_control->ext_a); gwy_debug("vme_release = %g", other_control->vme_release); return TRUE; }
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 gboolean unisoku_read_header(gchar *buffer, UnisokuFile *ufile, GError **error) { gchar *line; gint type1, type2; line = gwy_str_next_line(&buffer); if (!line) return FALSE; NEXT(buffer, line, error); /* garbage */ NEXT(buffer, line, error); if (unisoku_sscanf(line, "i", &ufile->format_version) != 1) { err_UNSUPPORTED(error, _("format version")); return FALSE; } NEXT(buffer, line, error); ufile->date = g_strdup(line); NEXT(buffer, line, error); ufile->time = g_strdup(line); NEXT(buffer, line, error); ufile->sample_name = g_strdup(line); NEXT(buffer, line, error); ufile->remark = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &ufile->ascii_flag, &type1) != 2) { err_INVALID(error, _("format flags")); return FALSE; } ufile->data_type = type1; NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &ufile->xres, &ufile->yres) != 2) { err_INVALID(error, _("resolution")); return FALSE; } if (err_DIMENSION(error, ufile->xres) || err_DIMENSION(error, ufile->yres)) return FALSE; NEXT(buffer, line, error); if (unisoku_sscanf(line, "ii", &type1, &type2) != 2) { /* FIXME */ g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing or invalid some integers heaven knows what " "they mean but that should be here.")); return FALSE; } ufile->dim_x = type1; ufile->dim_y = type2; NEXT(buffer, line, error); ufile->unit_x = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddi", &ufile->start_x, &ufile->end_x, &ufile->log_flag_x) != 3) { err_INVALID(error, _("x scale parameters")); return FALSE; } NEXT(buffer, line, error); ufile->unit_y = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddii", &ufile->start_y, &ufile->end_y, &ufile->ineq_flag, &ufile->log_flag_y) != 4) { err_INVALID(error, _("y scale parameters")); return FALSE; } /* Use negated positive conditions to catch NaNs */ if (!(ufile->end_x - ufile->start_x > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); ufile->start_x = 0.0; ufile->end_x = 1.0; } if (!(ufile->end_y - ufile->start_y > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); ufile->start_y = 0.0; ufile->end_y = 1.0; } NEXT(buffer, line, error); ufile->unit_z = g_strdup(line); NEXT(buffer, line, error); if (unisoku_sscanf(line, "ddddi", &ufile->max_raw_z, &ufile->min_raw_z, &ufile->max_z, &ufile->min_z, &ufile->log_flag_z) != 5) { err_INVALID(error, _("z scale parameters")); return FALSE; } NEXT(buffer, line, error); if (unisoku_sscanf(line, "dddi", &ufile->stm_voltage, &ufile->stm_current, &ufile->scan_time, &ufile->accum) != 4) { err_INVALID(error, _("data type parameters")); return FALSE; } NEXT(buffer, line, error); /* reserved */ NEXT(buffer, line, error); ufile->stm_voltage_unit = g_strdup(line); NEXT(buffer, line, error); ufile->stm_current_unit = g_strdup(line); NEXT(buffer, line, error); ufile->ad_name = g_strdup(line); /* There is more stuff after that, but heaven knows what it means... */ return TRUE; }
static gboolean rhk_sm4_read_page_header(RHKPage *page, const RHKObject *obj, const guchar *buffer, gsize size, GError **error) { const guchar *p; guint i; if (obj->size < PAGE_HEADER_SIZE) { err_OBJECT_TRUNCATED(error, RHK_OBJECT_PAGE_HEADER); return FALSE; } p = buffer + obj->offset; page->field_size = gwy_get_guint16_le(&p); if (obj->size < page->field_size) { err_OBJECT_TRUNCATED(error, RHK_OBJECT_PAGE_HEADER); return FALSE; } page->string_count = gwy_get_guint16_le(&p); gwy_debug("string_count = %u", page->string_count); page->page_type = gwy_get_guint32_le(&p); gwy_debug("page_type = %u", page->page_type); page->data_sub_source = gwy_get_guint32_le(&p); page->line_type = gwy_get_guint32_le(&p); page->x_coord = gwy_get_gint32_le(&p); page->y_coord = gwy_get_gint32_le(&p); gwy_debug("x_coord = %u, y_coord = %u", page->x_coord, page->y_coord); page->x_size = gwy_get_guint32_le(&p); page->y_size = gwy_get_guint32_le(&p); gwy_debug("x_size = %u, y_size = %u", page->x_size, page->y_size); if (err_DIMENSION(error, page->x_size) || err_DIMENSION(error, page->y_size)) return FALSE; page->image_type = gwy_get_guint32_le(&p); gwy_debug("image_type = %u", page->image_type); page->scan_dir = gwy_get_guint32_le(&p); gwy_debug("scan_dir = %u", page->scan_dir); page->group_id = gwy_get_guint32_le(&p); gwy_debug("group_id = 0x%08x", page->group_id); page->data_size = gwy_get_guint32_le(&p); gwy_debug("data_size = %u", page->data_size); page->min_z_value = gwy_get_gint32_le(&p); page->max_z_value = gwy_get_gint32_le(&p); gwy_debug("min,max_z_value = %d %d", page->min_z_value, page->max_z_value); page->x_scale = gwy_get_gfloat_le(&p); page->y_scale = gwy_get_gfloat_le(&p); page->z_scale = gwy_get_gfloat_le(&p); gwy_debug("x,y,z_scale = %g %g %g", page->x_scale, page->y_scale, page->z_scale); /* Use negated positive conditions to catch NaNs */ /* Must not take the absolute value here, spectra may have valid negative * scales. */ if (!(page->x_scale != 0)) { g_warning("Real x scale is 0.0, fixing to 1.0"); page->x_scale = 1.0; } if (!(page->y_scale != 0)) { g_warning("Real y scale is 0.0, fixing to 1.0"); page->y_scale = 1.0; } page->xy_scale = gwy_get_gfloat_le(&p); page->x_offset = gwy_get_gfloat_le(&p); page->y_offset = gwy_get_gfloat_le(&p); page->z_offset = gwy_get_gfloat_le(&p); gwy_debug("x,y,z_offset = %g %g %g", page->x_offset, page->y_offset, page->z_offset); page->period = gwy_get_gfloat_le(&p); page->bias = gwy_get_gfloat_le(&p); page->current = gwy_get_gfloat_le(&p); page->angle = gwy_get_gfloat_le(&p); gwy_debug("period = %g, bias = %g, current = %g, angle = %g", page->period, page->bias, page->current, page->angle); page->color_info_count = gwy_get_guint32_le(&p); gwy_debug("color_info_count = %u", page->color_info_count); page->grid_x_size = gwy_get_guint32_le(&p); page->grid_y_size = gwy_get_guint32_le(&p); gwy_debug("gird_x,y = %u %u", page->grid_x_size, page->grid_y_size); page->object_count = gwy_get_guint32_le(&p); for (i = 0; i < G_N_ELEMENTS(page->reserved); i++) page->reserved[i] = gwy_get_guint32_le(&p); if (!(page->objects = rhk_sm4_read_objects(buffer, p, size, page->object_count, RHK_OBJECT_PAGE_HEADER, error))) return FALSE; return TRUE; }
static gboolean omicron_read_header(gchar *buffer, OmicronFile *ofile, GError **error) { gchar *line, *val, *comment; ofile->meta = g_hash_table_new(g_str_hash, g_str_equal); while ((line = gwy_str_next_line(&buffer))) { /* FIXME: This strips 2nd and following lines from possibly multiline * fields like Comment. */ if (!line[0] || line[0] == ';' || g_ascii_isspace(line[0])) continue; val = strchr(line, ':'); if (!val) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Missing colon in header line.")); return FALSE; } if (val == line) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Header line starts with a colon.")); return FALSE; } *val = '\0'; val++; g_strstrip(line); comment = strchr(val, ';'); if (comment) { /* If the coment has the form ;[units], move the [units] part after * the number. */ if (comment[1] == '[' && (g_ascii_isalpha(comment[2]) || comment[2] == '%')) { gchar *c, *s = comment-1; while (g_ascii_isspace(*s)) s--; s++; c = comment + 1; *c = ' '; while (*c && *c != ']') *(s++) = *(c++); *s = '\0'; } else *comment = '\0'; comment++; g_strstrip(comment); } g_strstrip(val); if (gwy_strequal(line, "Topographic Channel")) { OmicronTopoChannel *channel; gwy_debug("Topographic Channel found (type %c)", val[0]); channel = g_new0(OmicronTopoChannel, 1); channel->type = val[0]; if (!omicron_read_topo_header(&buffer, channel, error)) { g_free(channel); return FALSE; } if (!ofile->topo_channels) ofile->topo_channels = g_ptr_array_new(); g_ptr_array_add(ofile->topo_channels, channel); } else if (gwy_strequal(line, "Spectroscopy Channel")) { OmicronSpectroChannel *channel; gwy_debug("Spectroscopic Channel found (chan %s)", val); channel = g_new0(OmicronSpectroChannel, 1); channel->chan = val; if (!omicron_read_spectro_header(&buffer, channel, error)) { g_free(channel); return FALSE; } if (!ofile->spectro_channels) ofile->spectro_channels = g_ptr_array_new(); g_ptr_array_add(ofile->spectro_channels, channel); } else { gwy_debug("<%s> = <%s>", line, val); g_hash_table_insert(ofile->meta, line, val); } } GET_FIELD(ofile->meta, val, "Image Size in X", error); ofile->xres = abs(atoi(val)); GET_FIELD(ofile->meta, val, "Image Size in Y", error); ofile->yres = abs(atoi(val)); if (err_DIMENSION(error, ofile->xres) || err_DIMENSION(error, ofile->yres)) return FALSE; GET_FIELD(ofile->meta, val, "Field X Size in nm", error); ofile->xreal = g_ascii_strtod(val, NULL); GET_FIELD(ofile->meta, val, "Field Y Size in nm", error); ofile->yreal = g_ascii_strtod(val, NULL); /* Use negated positive conditions to catch NaNs */ if (!((ofile->xreal = fabs(ofile->xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); ofile->xreal = 1.0; } if (!((ofile->yreal = fabs(ofile->yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); ofile->yreal = 1.0; } ofile->xreal *= Nanometer; ofile->yreal *= Nanometer; return TRUE; }
static gsize pt3file_read_header(const guchar *buffer, gsize size, PicoHarpFile *pt3file, GError **error) { const guchar* (*read_imaging_header)(PicoHarpImagingHeader *header, const guchar *p); PicoHarpInstrument instr; const guchar *p; guint i, expected_size; p = buffer; if (size < HEADER_MIN_SIZE + 2) { err_TOO_SHORT(error); return 0; } get_CHARARRAY(pt3file->ident, &p); get_CHARARRAY(pt3file->format_version, &p); get_CHARARRAY(pt3file->creator_name, &p); get_CHARARRAY(pt3file->creator_version, &p); gwy_debug("<%.*s> <%.*s> <%.*s> <%.*s>", (gint)sizeof(pt3file->ident), pt3file->ident, (gint)sizeof(pt3file->format_version), pt3file->format_version, (gint)sizeof(pt3file->creator_name), pt3file->creator_name, (gint)sizeof(pt3file->creator_version), pt3file->creator_version); get_CHARARRAY(pt3file->file_time, &p); get_CHARARRAY(pt3file->crlf, &p); get_CHARARRAY(pt3file->comment, &p); if (memcmp(pt3file->ident, MAGIC, MAGIC_SIZE) != 0 || pt3file->crlf[0] != '\r' || pt3file->crlf[1] != '\n') { err_FILE_TYPE(error, "PicoHarp"); return 0; } pt3file->number_of_curves = gwy_get_guint32_le(&p); gwy_debug("number_of_curves: %u", pt3file->number_of_curves); pt3file->bits_per_record = gwy_get_guint32_le(&p); gwy_debug("bits_per_record: %u", pt3file->bits_per_record); pt3file->routing_channels = gwy_get_guint32_le(&p); gwy_debug("routing_channels: %u", pt3file->routing_channels); pt3file->number_of_boards = gwy_get_guint32_le(&p); gwy_debug("number_of_boards: %u", pt3file->number_of_boards); if (pt3file->number_of_boards != 1) { g_warning("Number of boards is %u instead of 1. Reading one.", pt3file->number_of_boards); pt3file->number_of_boards = MAX(pt3file->number_of_boards, 1); if (size < HEADER_MIN_SIZE + BOARD_SIZE*pt3file->number_of_boards) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated.")); return 0; } } pt3file->active_curve = gwy_get_guint32_le(&p); pt3file->measurement_mode = gwy_get_guint32_le(&p); gwy_debug("measurement_mode: %u", pt3file->measurement_mode); pt3file->sub_mode = gwy_get_guint32_le(&p); gwy_debug("sub_mode: %u", pt3file->sub_mode); pt3file->range_no = gwy_get_guint32_le(&p); pt3file->offset = gwy_get_gint32_le(&p); pt3file->acquisition_time = gwy_get_guint32_le(&p); pt3file->stop_at = gwy_get_guint32_le(&p); pt3file->stop_on_ovfl = gwy_get_guint32_le(&p); pt3file->restart = gwy_get_guint32_le(&p); pt3file->display_lin_log = !!gwy_get_guint32_le(&p); pt3file->display_time_axis_from = gwy_get_guint32_le(&p); pt3file->display_time_axis_to = gwy_get_guint32_le(&p); pt3file->display_counts_axis_from = gwy_get_guint32_le(&p); pt3file->display_counts_axis_to = gwy_get_guint32_le(&p); for (i = 0; i < G_N_ELEMENTS(pt3file->display_curve); i++) { pt3file->display_curve[i].map_to = gwy_get_guint32_le(&p); pt3file->display_curve[i].show = gwy_get_guint32_le(&p); } for (i = 0; i < G_N_ELEMENTS(pt3file->auto_param); i++) { pt3file->auto_param[i].start = gwy_get_gfloat_le(&p); pt3file->auto_param[i].step = gwy_get_gfloat_le(&p); pt3file->auto_param[i].end = gwy_get_gfloat_le(&p); } pt3file->repeat_mode = gwy_get_guint32_le(&p); pt3file->repeats_per_curve = gwy_get_guint32_le(&p); pt3file->repeat_time = gwy_get_guint32_le(&p); pt3file->repeat_wait_time = gwy_get_guint32_le(&p); get_CHARARRAY(pt3file->script_name, &p); p = pt3file_read_board(&pt3file->board, p); p += BOARD_SIZE*(pt3file->number_of_boards - 1); pt3file->ext_devices = gwy_get_guint32_le(&p); pt3file->reserved1 = gwy_get_guint32_le(&p); pt3file->reserved2 = gwy_get_guint32_le(&p); pt3file->input0_rate = gwy_get_guint32_le(&p); pt3file->input1_rate = gwy_get_guint32_le(&p); pt3file->stop_after = gwy_get_guint32_le(&p); pt3file->stop_reason = gwy_get_guint32_le(&p); pt3file->number_of_records = gwy_get_guint32_le(&p); gwy_debug("number_of_records: %u", pt3file->number_of_records); pt3file->spec_header_length = 4*gwy_get_guint32_le(&p); gwy_debug("spec_header_length: %u", pt3file->spec_header_length); gwy_debug("now at pos 0x%0lx", (gulong)(p - buffer)); if (pt3file->measurement_mode != 2 && pt3file->measurement_mode != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Measurement mode must be 2 or 3; %u is invalid."), pt3file->measurement_mode); return 0; } if (pt3file->sub_mode != PICO_HARP_IMAGE) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only area imaging files are supported.")); return 0; } if (pt3file->bits_per_record != 32) { err_BPP(error, pt3file->bits_per_record); return 0; } pt3file->imaging.common.dimensions = gwy_get_guint32_le(&p); gwy_debug("imaging dimensions: %u", pt3file->imaging.common.dimensions); if (pt3file->imaging.common.dimensions != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only area imaging files are supported.")); return 0; } pt3file->imaging.common.instrument = instr = gwy_get_guint32_le(&p); gwy_debug("imaging instrument: %u", pt3file->imaging.common.instrument); if (instr == PICO_HARP_PIE710) { expected_size = IMAGING_PIE710_SIZE; read_imaging_header = &read_pie710_imaging_header; } else if (instr == PICO_HARP_KDT180) { expected_size = IMAGING_KDT180_SIZE; read_imaging_header = &read_kdt180_imaging_header; } else if (instr == PICO_HARP_LSM) { expected_size = IMAGING_LSM_SIZE; read_imaging_header = &read_lsm_imaging_header; } else { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Unknown instrument number %u."), instr); return 0; } if (pt3file->spec_header_length != expected_size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Wrong imaging header size: %u instead of %u."), pt3file->spec_header_length, expected_size); return 0; } if ((p - buffer) + expected_size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated.")); return 0; } p = read_imaging_header(&pt3file->imaging, p); gwy_debug("xres: %u", pt3file->imaging.common.xres); gwy_debug("yres: %u", pt3file->imaging.common.yres); if (err_DIMENSION(error, pt3file->imaging.common.xres) || err_DIMENSION(error, pt3file->imaging.common.xres)) return 0; return (gsize)(p - buffer); }
static GwyContainer* int_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta; GwyDataField *dfield = NULL, *mfield = NULL; CodeVGridDataType type; gchar *line, *p, *comment, *end, *buffer = NULL; const gchar *unit, *title; gchar **fields = NULL; gsize size; GError *err = NULL; gdouble xreal, yreal; gint i, xres, yres, no_data_value = 32767; guint fi; gdouble scale_size, wavelength, q = 1.0, x_scale = 1.0; gboolean nearest_neighbour = FALSE; gdouble *data, *mdata; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } /* Skip comments. */ p = buffer; for (line = gwy_str_next_line(&p); line && line[0] == '!'; line = gwy_str_next_line(&p)) { gwy_debug("comment <%s>", line); } if (!line) { err_FILE_TYPE(error, "Code V INT"); goto fail; } /* The title. */ comment = line; if (!(line = gwy_str_next_line(&p))) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("comment <%s>", comment); fields = split_line_in_place(line); if (!fields || g_strv_length(fields) < 8 || !gwy_strequal(fields[0], "GRD") || !(xres = atoi(fields[1])) || !(yres = atoi(fields[2])) || !(type = gwy_stramong(fields[3], "SUR", "WFR", "FIL", "THV", "BIR", "CAO", NULL)) || !gwy_strequal(fields[4], "WVL") || (!(wavelength = g_ascii_strtod(fields[5], &end)) && end == fields[5])) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("type %u (%s)", type, fields[3]); gwy_debug("xres %d, yres %d", xres, yres); gwy_debug("wavelength %g", wavelength); fi = 6; if (gwy_strequal(fields[fi], "NNB")) { nearest_neighbour = TRUE; fi++; } gwy_debug("nearest_neighbour %d", nearest_neighbour); if (!fields[fi] || !gwy_strequal(fields[fi], "SSZ")) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; if (!(scale_size = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } gwy_debug("scale_size %g", scale_size); if (!scale_size) { g_warning("Zero SSZ, fixing to 1.0"); scale_size = 1.0; } fi++; if (fields[fi] && gwy_strequal(fields[fi], "NDA")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } no_data_value = atoi(fields[fi]); fi++; } gwy_debug("no_data_value %d", no_data_value); if (fields[fi] && gwy_strequal(fields[fi], "XSC")) { fi++; if (!fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } if (!(x_scale = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) { err_FILE_TYPE(error, "Code V INT"); goto fail; } fi++; } gwy_debug("x_scale %g", x_scale); if (!x_scale) { g_warning("Zero XSC, fixing to 1.0"); x_scale = 1.0; } /* There may be more stuff but we do not know anything about it. */ if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) goto fail; yreal = 1.0; xreal = x_scale*yreal; dfield = gwy_data_field_new(xres, yres, xreal, yreal, TRUE); if (type == CODEV_INT_SURFACE_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Surface"; } else if (type == CODEV_INT_WAVEFRONT_DEFORMATION) { q = 1e-6*wavelength/scale_size; unit = "m"; title = "Wavefront"; } else { g_warning("Don't know how to convert this grid data type to physical " "units."); title = fields[3]; } gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), unit); mfield = gwy_data_field_new_alike(dfield, TRUE); data = gwy_data_field_get_data(dfield); mdata = gwy_data_field_get_data(mfield); for (i = 0; i < xres*yres; i++, p = end) { gint value = strtol(p, &end, 10); if (value != no_data_value && (type != CODEV_INT_INTENSITY_FILTER || value >= 0)) { mdata[i] = 1.0; data[i] = q*value; } } if (!gwy_app_channel_remove_bad_data(dfield, mfield)) gwy_object_unref(mfield); container = gwy_container_new(); /* gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); from F. Riguet : apparently no flip is needed (the raw data import module gives the correct orientation without further flipping) */ gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); gwy_app_channel_check_nonsquare(container, 0); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(title)); if (mfield) { /* gwy_data_field_invert(mfield, FALSE, TRUE, FALSE); */ gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } meta = gwy_container_new(); gwy_container_set_string_by_name(meta, "Comment", g_strdup(comment)); gwy_container_set_string_by_name(meta, "Interpolation", g_strdup(nearest_neighbour ? "NNB" : "Linear")); gwy_container_set_string_by_name(meta, "Wavelength", g_strdup_printf("%g μm", wavelength)); gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: g_free(fields); g_free(buffer); return container; }
static GwyContainer* 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* surffile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SurfFile surffile; gint coef = 0; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; const guchar *p; gsize expected_size, size = 0; GError *err = NULL; gchar signature[12]; gint add = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(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.dayof = gwy_get_guint16_le(&p); surffile.measurement_duration = gwy_get_gfloat_le(&p); p += 10; 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); if (err_DIMENSION(error, surffile.xres) || err_DIMENSION(error, surffile.yres)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } 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, TRUE); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } /* Use negated positive conditions to catch NaNs */ if (!((surffile.dx = fabs(surffile.dx)) > 0)) { g_warning("Real x step is 0.0, fixing to 1.0"); surffile.dx = 1.0; } if (!((surffile.dy = fabs(surffile.dy)) > 0)) { g_warning("Real y step is 0.0, fixing to 1.0"); surffile.dy = 1.0; } p = buffer + SURF_HEADER_SIZE + add; /*units*/ coef = 0; surffile.xyunit = gwy_si_unit_new_parse(surffile.dx_unit, &coef); surffile.dx *= pow10(coef); coef = 0; surffile.xyunit = gwy_si_unit_new_parse(surffile.dy_unit, &coef); surffile.dy *= pow10(coef); coef = 0; surffile.zunit = gwy_si_unit_new_parse (surffile.dz_unit, &coef); if (!fill_data_fields(&surffile, p, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } 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; } gwy_data_field_multiply(surffile.dfield, pow10(coef)); surffile.ZOffset *= pow10(coef); gwy_data_field_add(surffile.dfield, surffile.ZOffset); 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); gwy_file_channel_import_log_add(container, 0, NULL, filename); return container; }