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 gboolean x3p_file_get_data_type(const gchar *type, GwyRawDataType *rawtype, GError **error) { if (gwy_strequal(type, "I")) { *rawtype = GWY_RAW_DATA_SINT16; return TRUE; } if (gwy_strequal(type, "L")) { *rawtype = GWY_RAW_DATA_SINT32; return TRUE; } if (gwy_strequal(type, "F")) { *rawtype = GWY_RAW_DATA_FLOAT; return TRUE; } if (gwy_strequal(type, "D")) { *rawtype = GWY_RAW_DATA_DOUBLE; return TRUE; } err_UNSUPPORTED(error, AXES_PREFIX "/CZ/DataType"); return FALSE; }
static GwyDataField* read_binary_data(const gchar *buffer, gsize size, GHashTable *hash, GError **error) { ShimadzuDataType data_type; gint xres, yres, i; guint expected; gdouble xreal, yreal, zscale, xoff, yoff, zoff; GwySIUnit *unitxy, *unitz; GwyDataField *dfield = NULL; gdouble *d; const gchar *s; if (!(s = g_hash_table_lookup(hash, "DataType"))) { err_MISSING_FIELD(error, "DataType"); return NULL; } if (g_ascii_strcasecmp(s, "short") == 0) data_type = SHIMADZU_SHORT; else if (g_ascii_strcasecmp(s, "float") == 0) data_type = SHIMADZU_FLOAT; else { err_UNSUPPORTED(error, "DataType"); return NULL; } unitxy = gwy_si_unit_new(NULL); unitz = gwy_si_unit_new(NULL); if (!get_scales(hash, FALSE, &xres, &yres, &xreal, &yreal, &xoff, &yoff, unitxy, &zscale, &zoff, unitz, error)) goto fail; expected = data_type*xres*yres + HEADER_SIZE; if (err_SIZE_MISMATCH(error, expected, size, FALSE)) goto fail; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_xoffset(dfield, xoff); gwy_data_field_set_yoffset(dfield, yoff); gwy_data_field_set_si_unit_xy(dfield, unitxy); gwy_data_field_set_si_unit_z(dfield, unitz); d = gwy_data_field_get_data(dfield); if (data_type == SHIMADZU_SHORT) { const gint16 *d16 = (const gint16*)(buffer + HEADER_SIZE); for (i = 0; i < xres*yres; i++) d[i] = zscale*GUINT16_FROM_LE(d16[i]) + zoff; } else if (data_type == SHIMADZU_FLOAT) { const guchar *p = buffer + HEADER_SIZE; for (i = 0; i < xres*yres; i++) d[i] = zscale*gwy_get_gfloat_le(&p) + zoff; } else { g_assert_not_reached(); } gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); fail: g_object_unref(unitxy); g_object_unref(unitz); return dfield; }
static GwyDataField* apedax_get_data_field(unzFile uFile, const gchar *chFileName, const APEScanSize *scanSize, gchar *zUnit, gdouble scale, GError **error) { GwyDataField *dfield = NULL; GwySIUnit *xyUnit; GwySIUnit *zSIUnit; gdouble *data; guchar *buffer; gsize size, expectedSize; unz_file_info uFileInfo; /*Checking the dimensions*/ if (err_DIMENSION(error, scanSize->XRes)) { return NULL; } if (err_DIMENSION(error, scanSize->YRes)) { return NULL; } /*If XReal it's not greater than 0 or XReal is NaN*/ if (!(fabs(scanSize->XReal) > 0)) { err_UNSUPPORTED(error, "X scan size"); return NULL; } /*Same for YReal*/ if (!(fabs(scanSize->YReal) > 0)) { err_UNSUPPORTED(error, "Y scan size"); return NULL; } expectedSize = scanSize->XRes * scanSize->YRes * sizeof(gdouble); unzGoToFirstFile(uFile); if (unzLocateFile(uFile, chFileName, 0) != UNZ_OK) { gwy_debug("Binary file not found"); err_NO_DATA(error); return NULL; } if (unzGetCurrentFileInfo(uFile, &uFileInfo, NULL, 0L, NULL, 0L, NULL, 0L) != UNZ_OK) { err_NO_DATA(error); return NULL; } buffer = apedax_get_file_content(uFile, &uFileInfo, &size, error); if (buffer == NULL) { err_NO_DATA(error); return NULL; } if (err_SIZE_MISMATCH(error, expectedSize, size, FALSE)) { return NULL; } dfield = gwy_data_field_new(scanSize->XRes, scanSize->YRes, scanSize->XReal, scanSize->YReal, FALSE); data = gwy_data_field_get_data(dfield); xyUnit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string(xyUnit, "m"); zSIUnit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_set_from_string(zSIUnit, zUnit); gwy_debug("Reading RAW data"); gwy_convert_raw_data(buffer, scanSize->XRes * scanSize->YRes, 1, GWY_RAW_DATA_DOUBLE, GWY_BYTE_ORDER_LITTLE_ENDIAN, data, scale, 0.0); return dfield; }
/* 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 gboolean mprofile_read_header(const guchar *buffer, gsize size, MProFile *mprofile, GError **error) { const guchar *p; guint i; p = buffer; if (size < HEADER_SIZE + 2) { err_TOO_SHORT(error); return FALSE; } get_CHARARRAY(mprofile->magic, &p); if (memcmp(mprofile->magic, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "MetroPro"); return FALSE; } mprofile->header_format = gwy_get_guint16_be(&p); if (mprofile->header_format != 1) { err_UNSUPPORTED(error, "FormatVersion"); return FALSE; } mprofile->header_size = gwy_get_guint32_be(&p); gwy_debug("header_format: %d, header_size: %d", mprofile->header_format, mprofile->header_size); if (mprofile->header_size < 570) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is too short.")); return FALSE; } if (mprofile->header_size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is larger than file.")); return FALSE; } mprofile->software_type = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->software_date, &p); gwy_debug("software_type: %d, software_date: %s", mprofile->software_type, mprofile->software_date); mprofile->version_major = gwy_get_guint16_be(&p); mprofile->version_minor = gwy_get_guint16_be(&p); mprofile->version_micro = gwy_get_guint16_be(&p); gwy_debug("version: %d.%d.%d", mprofile->version_major, mprofile->version_minor, mprofile->version_micro); mprofile->intens_xoff = gwy_get_guint16_be(&p); mprofile->intens_yoff = gwy_get_guint16_be(&p); mprofile->intens_xres = gwy_get_guint16_be(&p); mprofile->intens_yres = gwy_get_guint16_be(&p); gwy_debug("INTENS xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->intens_xres, mprofile->intens_yres, mprofile->intens_xoff, mprofile->intens_yoff); mprofile->nbuckets = gwy_get_guint16_be(&p); mprofile->intens_range = gwy_get_guint16_be(&p); mprofile->intens_nbytes = gwy_get_guint32_be(&p); gwy_debug("intens_nbytes: %d, expecting: %d", mprofile->intens_nbytes, 2*mprofile->intens_xres*mprofile->intens_yres*mprofile->nbuckets); mprofile->phase_xoff = gwy_get_guint16_be(&p); mprofile->phase_yoff = gwy_get_guint16_be(&p); mprofile->phase_xres = gwy_get_guint16_be(&p); mprofile->phase_yres = gwy_get_guint16_be(&p); gwy_debug("PHASE xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->phase_xres, mprofile->phase_yres, mprofile->phase_xoff, mprofile->phase_yoff); mprofile->phase_nbytes = gwy_get_guint32_be(&p); gwy_debug("phase_nbytes: %d, expecting: %d", mprofile->phase_nbytes, 4*mprofile->phase_xres*mprofile->phase_yres); mprofile->timestamp = gwy_get_guint32_be(&p); get_CHARARRAY0(mprofile->comment, &p); gwy_debug("comment: %s", mprofile->comment); mprofile->source = gwy_get_guint16_be(&p); mprofile->scale_factor = gwy_get_gfloat_be(&p); mprofile->wavelength_in = gwy_get_gfloat_be(&p); mprofile->numeric_aperture = gwy_get_gfloat_be(&p); mprofile->obliquity_factor = gwy_get_gfloat_be(&p); mprofile->magnification = gwy_get_gfloat_be(&p); mprofile->camera_res = gwy_get_gfloat_be(&p); mprofile->acquire_mode = gwy_get_guint16_be(&p); gwy_debug("acquire_mode: %d", mprofile->acquire_mode); mprofile->intens_avgs = gwy_get_guint16_be(&p); if (!mprofile->intens_avgs) mprofile->intens_avgs = 1; mprofile->pzt_cal = gwy_get_guint16_be(&p); mprofile->pzt_gain_tolerance = gwy_get_guint16_be(&p); mprofile->pzt_gain = gwy_get_guint16_be(&p); mprofile->part_thickness = gwy_get_gfloat_be(&p); mprofile->agc = gwy_get_guint16_be(&p); mprofile->target_range = gwy_get_gfloat_be(&p); p += 2; mprofile->min_mod = gwy_get_guint32_be(&p); mprofile->min_mod_pts = gwy_get_guint32_be(&p); mprofile->phase_res = gwy_get_guint16_be(&p); mprofile->min_area_size = gwy_get_guint32_be(&p); mprofile->discont_action = gwy_get_guint16_be(&p); mprofile->discont_filter = gwy_get_gfloat_be(&p); mprofile->connection_order = gwy_get_guint16_be(&p); mprofile->data_inverted = gwy_get_guint16_be(&p); mprofile->camera_width = gwy_get_guint16_be(&p); mprofile->camera_height = gwy_get_guint16_be(&p); mprofile->system_type = gwy_get_guint16_be(&p); mprofile->system_board = gwy_get_guint16_be(&p); mprofile->system_serial = gwy_get_guint16_be(&p); mprofile->instrument_id = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->objective_name, &p); get_CHARARRAY0(mprofile->part_num, &p); gwy_debug("part_num: %s", mprofile->part_num); mprofile->code_vtype = gwy_get_guint16_be(&p); mprofile->phase_avgs = gwy_get_guint16_be(&p); mprofile->subtract_sys_err = gwy_get_guint16_be(&p); p += 16; get_CHARARRAY0(mprofile->part_ser_num, &p); mprofile->refactive_index = gwy_get_gfloat_be(&p); mprofile->remove_tilt_bias = gwy_get_guint16_be(&p); mprofile->remove_fringes = gwy_get_guint16_be(&p); mprofile->max_area_size = gwy_get_guint32_be(&p); mprofile->setup_type = gwy_get_guint16_be(&p); p += 2; mprofile->pre_connect_filter = gwy_get_gfloat_be(&p); mprofile->wavelength2 = gwy_get_gfloat_be(&p); mprofile->wavelength_fold = gwy_get_guint16_be(&p); mprofile->wavelength1 = gwy_get_gfloat_be(&p); mprofile->wavelength3 = gwy_get_gfloat_be(&p); mprofile->wavelength4 = gwy_get_gfloat_be(&p); get_CHARARRAY0(mprofile->wavelength_select, &p); mprofile->fda_res = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->scan_description, &p); gwy_debug("scan_description: %s", mprofile->scan_description); mprofile->nfiducials = gwy_get_guint16_be(&p); for (i = 0; i < G_N_ELEMENTS(mprofile->fiducials); i++) mprofile->fiducials[i] = gwy_get_gfloat_be(&p); mprofile->pixel_width = gwy_get_gfloat_be(&p); mprofile->pixel_height = gwy_get_gfloat_be(&p); mprofile->exit_pupil_diam = gwy_get_gfloat_be(&p); mprofile->light_level_pct = gwy_get_gfloat_be(&p); mprofile->coords_state = gwy_get_guint32_be(&p); mprofile->xpos = gwy_get_gfloat_be(&p); mprofile->ypos = gwy_get_gfloat_be(&p); mprofile->zpos = gwy_get_gfloat_be(&p); mprofile->xrot = gwy_get_gfloat_be(&p); mprofile->yrot = gwy_get_gfloat_be(&p); mprofile->zrot = gwy_get_gfloat_be(&p); mprofile->coherence_mode = gwy_get_guint16_be(&p); mprofile->surface_filter = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->sys_err_file, &p); get_CHARARRAY0(mprofile->zoom_desc, &p); return TRUE; }
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; }