static gboolean mif_read_image_configuration(MIFImageConfiguration *config, const guchar **p, gsize size, guint file_version, GError **error) { if (file_version >= 0x107 && file_version <= 0x109) { if (size < IMAGE_CONFIGURATION_SIZE_1_3) return err_IMAGE_HEADER_TOO_SHORT(error); config->scan_int_to_meter = gwy_get_gdouble_le(p); gwy_debug("scan_int_to_meter: %g", config->scan_int_to_meter); config->xcal = gwy_get_gdouble_le(p); config->ycal = gwy_get_gdouble_le(p); config->zcal = gwy_get_gdouble_le(p); gwy_debug("calibration: %g %g %g", config->xcal, config->ycal, config->zcal); get_CHARARRAY(config->direction, p); gwy_debug_chars(config, direction); get_CHARARRAY(config->signal, p); gwy_debug_chars(config, signal); get_CHARARRAY(config->scan_head, p); gwy_debug_chars(config, scan_head); config->scan_head_code = *((*p)++); get_CHARARRAY(config->scan_mode, p); gwy_debug_chars(config, scan_mode); config->z_linearized = !!*((*p)++); gwy_debug_bool(config, z_linearized); config->z_correction = gwy_get_gfloat_le(p); gwy_debug("z_correction: %g", config->z_correction); config->is_zcorrected = !!*((*p)++); gwy_debug_bool(config, is_zcorrected); config->is_flattened = !!*((*p)++); gwy_debug_bool(config, is_flattened); get_CHARARRAY(config->scan_head_name, p); gwy_debug_chars(config, scan_head_name); } else { g_return_val_if_reached(FALSE); } return TRUE; }
static gboolean sdfile_read_header_bin(const guchar **p, gsize *len, SDFile *sdfile, GError **error) { if (*len < SDF_HEADER_SIZE_BIN) { err_TOO_SHORT(error); return FALSE; } gwy_clear(sdfile, 1); get_CHARARRAY(sdfile->version, p); get_CHARARRAY(sdfile->manufacturer, p); get_CHARARRAY(sdfile->creation, p); get_CHARARRAY(sdfile->modification, p); sdfile->xres = gwy_get_guint16_le(p); sdfile->yres = gwy_get_guint16_le(p); sdfile->xscale = gwy_get_gdouble_le(p); sdfile->yscale = gwy_get_gdouble_le(p); sdfile->zscale = gwy_get_gdouble_le(p); sdfile->zres = gwy_get_gdouble_le(p); sdfile->compression = **p; (*p)++; sdfile->data_type = **p; (*p)++; sdfile->check_type = **p; (*p)++; sdfile->data = (gchar*)*p; if (sdfile->data_type < SDF_NTYPES) sdfile->expected_size = type_sizes[sdfile->data_type] * sdfile->xres * sdfile->yres; else sdfile->expected_size = -1; *len -= SDF_HEADER_SIZE_BIN; return TRUE; }
static gboolean mif_read_scan_setup(MIFScanSetup *setup, const guchar **p, gsize size, guint file_version, GError **error) { if (file_version >= 0x103 && file_version <= 0x107) { if (size < SCAN_SETUP_SIZE_1_2) return err_IMAGE_HEADER_TOO_SHORT(error); setup->xres = gwy_get_guint32_le(p); setup->yres = gwy_get_guint32_le(p); gwy_debug("xres: %u, yres: %u", setup->xres, setup->yres); setup->xreal = gwy_get_gdouble_le(p); setup->yreal = gwy_get_gdouble_le(p); gwy_debug("xreal: %g, yreal: %g", setup->xreal, setup->yreal); /* Use negated positive conditions to catch NaNs */ if (!((setup->xreal = fabs(setup->xreal)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); setup->xreal = 1.0; } if (!((setup->yreal = fabs(setup->yreal)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); setup->yreal = 1.0; } setup->xoff = gwy_get_gdouble_le(p); setup->yoff = gwy_get_gdouble_le(p); gwy_debug("xoff: %g, yoff: %g", setup->xoff, setup->yoff); setup->xscandir = gwy_get_gdouble_le(p); setup->yscandir = gwy_get_gdouble_le(p); gwy_debug("xscandir: %g, yscandir: %g", setup->xscandir, setup->yscandir); setup->scan_speed = gwy_get_gfloat_le(p); gwy_debug("scan_speed: %g", setup->scan_speed); setup->sample_pause = gwy_get_guint16_le(p); gwy_debug("sample_pause: %u", setup->sample_pause); setup->loop_gain = gwy_get_gfloat_le(p); gwy_debug("loop_gain: %g", setup->loop_gain); get_CHARARRAY(setup->loop_filter, p); gwy_debug_chars(setup, loop_filter); get_CHARARRAY(setup->lead_filter, p); gwy_debug_chars(setup, lead_filter); get_CHARARRAY(setup->lead_lag_mix, p); gwy_debug_chars(setup, lead_lag_mix); } else { g_return_val_if_reached(FALSE); } return TRUE; }
static gboolean read_aist_raster(const guchar **p, gsize *size, AistContext *context) { AistRaster raster; GwyDataField *dfield, *mfield; GwySIUnit *xyunit, *zunit; gboolean ok = FALSE; guint i, j, n, len; const guchar *data; gchar *s; gchar key[32]; gdouble *d; gdouble qxy, qz; gwy_clear(&raster, 1); gwy_debug("reading common"); if (!read_aist_common(p, size, &raster.common)) goto fail; gwy_debug("reading raster"); if (!read_qt_int(p, size, &raster.xres) || !read_qt_int(p, size, &raster.yres) || !read_qt_double(p, size, &raster.left) || !read_qt_double(p, size, &raster.right) || !read_qt_double(p, size, &raster.top) || !read_qt_double(p, size, &raster.bottom) || !read_qt_string(p, size, &raster.xunits) || !read_qt_string(p, size, &raster.yunits) || !read_qt_string(p, size, &raster.zunits)) goto fail; if (!read_qt_byte_array(p, size, &len, &data)) goto fail; n = raster.xres * raster.yres; if (len != n*sizeof(gdouble)) goto fail; xyunit = extract_units(raster.xunits, &qxy); zunit = extract_units(raster.zunits, &qz); dfield = gwy_data_field_new(raster.xres, raster.yres, qxy*fabs(raster.right - raster.left), qxy*fabs(raster.bottom - raster.top), FALSE); gwy_data_field_set_si_unit_xy(dfield, xyunit); gwy_data_field_set_si_unit_z(dfield, zunit); /* Apparently this is not generally wanted. gwy_data_field_set_xoffset(dfield, qxy*MIN(raster.left, raster.right)); gwy_data_field_set_yoffset(dfield, qxy*MIN(raster.top, raster.bottom)); */ g_object_unref(xyunit); g_object_unref(zunit); d = gwy_data_field_get_data(dfield); for (i = 0; i < raster.yres; i++) { for (j = 0; j < raster.xres; j++) { d[(raster.yres-1 - i)*raster.xres + j] = qz*gwy_get_gdouble_le(&data); } } g_snprintf(key, sizeof(key), "/%d/data", context->channel_id); gwy_container_set_object_by_name(context->container, key, dfield); g_object_unref(dfield); gwy_file_channel_import_log_add(context->container, context->channel_id, NULL, context->filename); if ((s = strchr(raster.common.name, '['))) s = g_strchomp(g_strndup(raster.common.name, s - raster.common.name)); else s = g_strdup(raster.common.name); g_snprintf(key, sizeof(key), "/%d/data/title", context->channel_id); gwy_container_set_string_by_name(context->container, key, s); g_snprintf(key, sizeof(key), "/%d/mask", context->channel_id); context->channel_id++; /* At this moment we consider the loading successful. */ ok = TRUE; /* The mask raster is byte-valued. It contains nonzeroes in points that * were measured (the opposite of how we normally create masks upon * import). */ if (read_qt_byte_array(p, size, &len, &data)) { if (len == raster.xres*raster.yres) { mfield = make_mask_field(dfield, data); if (mfield) { gwy_app_channel_remove_bad_data(dfield, mfield); gwy_container_set_object_by_name(context->container, key, mfield); g_object_unref(mfield); } } /* Here's something called view data. It means the data was processed * (by whatever means) hence we are not interesed in it. */ read_qt_byte_array(p, size, &len, &data); } fail: free_aist_common(&raster.common); g_free(raster.xunits); g_free(raster.yunits); g_free(raster.zunits); return ok; }
static GwyContainer* sensofar_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SensofarDataDesc data_desc; GwyContainer *container = NULL; GwyDataField *dfield, *mfield; GwyGraphModel *gmodel; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < HEADER_SIZE + 12) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated")); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* Date block */ p = buffer; memcpy(&data_desc.date.str, p, DATE_SIZE); data_desc.date.str[DATE_SIZE-1] = '\0'; p += DATE_SIZE; data_desc.date.t = gwy_get_guint32_le(&p); /* Comment block */ memcpy(&data_desc.user_comment, p, COMMENT_SIZE); data_desc.user_comment[COMMENT_SIZE-1] = '\0'; p += COMMENT_SIZE; /* Calbration block */ data_desc.axes_config.yres = gwy_get_guint32_le(&p); data_desc.axes_config.xres = gwy_get_guint32_le(&p); data_desc.axes_config.N_tall = gwy_get_guint32_le(&p); data_desc.axes_config.dy_multip = gwy_get_gfloat_le(&p); data_desc.axes_config.mppx = gwy_get_gfloat_le(&p); data_desc.axes_config.mppy = gwy_get_gfloat_le(&p); data_desc.axes_config.x_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.y_0 = gwy_get_gfloat_le(&p); data_desc.axes_config.mpp_tall = gwy_get_gfloat_le(&p); data_desc.axes_config.z_0 = gwy_get_gfloat_le(&p); /* Measurement block */ data_desc.measure_config.type = gwy_get_guint32_le(&p); data_desc.measure_config.algorithm = gwy_get_guint32_le(&p); data_desc.measure_config.method = gwy_get_guint32_le(&p); data_desc.measure_config.objective = gwy_get_guint32_le(&p); data_desc.measure_config.area = gwy_get_guint32_le(&p); data_desc.measure_config.xres_area = gwy_get_guint32_le(&p); data_desc.measure_config.yres_area = gwy_get_guint32_le(&p); data_desc.measure_config.xres = gwy_get_guint32_le(&p); data_desc.measure_config.yres = gwy_get_guint32_le(&p); data_desc.measure_config.na = gwy_get_guint32_le(&p); data_desc.measure_config.incr_z = gwy_get_gdouble_le(&p); data_desc.measure_config.range = gwy_get_gfloat_le(&p); data_desc.measure_config.n_planes = gwy_get_guint32_le(&p); data_desc.measure_config.tpc_umbral_F = gwy_get_guint32_le(&p); data_desc.measure_config.restore = gwy_get_gboolean8(&p); data_desc.measure_config.num_layers = *(p++); data_desc.measure_config.version = *(p++); data_desc.measure_config.config_hardware = *(p++); data_desc.measure_config.stack_im_num = *(p++); data_desc.measure_config.reserved = *(p++); p += 2; // struct padding data_desc.measure_config.factor_delmacio = gwy_get_guint32_le(&p); gwy_debug("File date=<%s>, data type=%d, xres=%d, yres=%d, version=%d", data_desc.date.str, data_desc.measure_config.type, data_desc.measure_config.xres, data_desc.measure_config.yres, data_desc.measure_config.version); switch (data_desc.measure_config.type) { case MES_TOPO: case MES_IMATGE: dfield = sensofar_read_data_field(&data_desc, &mfield, &p, size - (p - buffer), error); if (!dfield) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if (mfield) { gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0), mfield); g_object_unref(mfield); } gwy_app_channel_title_fall_back(container, 0); break; case MES_PERFIL: case MES_GRUIX: gmodel = sensofar_read_profile(&data_desc, &p, size - (p - buffer), error); if (!gmodel) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_graph_key_for_id(0), gmodel); g_object_unref(gmodel); break; default: err_DATA_TYPE(error, data_desc.measure_config.type); break; } return container; }
static GwyContainer* 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 void jeol_read_image_header(const guchar *p, JEOLImageHeader *header) { p += TIFF_HEADER_SIZE; header->winspm_version = gwy_get_guint16_le(&p); gwy_debug("version: %u", header->winspm_version); p += 80; /* there isn't anything interesting in internal_filename_old */ header->xres = gwy_get_guint16_le(&p); header->yres = gwy_get_guint16_le(&p); header->xreal = gwy_get_gfloat_le(&p); header->yreal = gwy_get_gfloat_le(&p); gwy_debug("res: (%d,%d), real: (%g,%g)", header->xres, header->yres, header->xreal, header->yreal); header->z0 = gwy_get_gfloat_le(&p); header->z255 = gwy_get_gfloat_le(&p); header->adc_min = gwy_get_guint16_le(&p); header->adc_max = gwy_get_guint16_le(&p); header->initial_scan_scale = gwy_get_gfloat_le(&p); get_CHARARRAY0(header->internal_filename, &p); get_CHARARRAY0(header->info[0], &p); get_CHARARRAY0(header->info[1], &p); get_CHARARRAY0(header->info[2], &p); get_CHARARRAY0(header->info[3], &p); get_CHARARRAY0(header->info[4], &p); get_CHARARRAY(header->history, &p); header->has_current_info = gwy_get_guint16_le(&p); header->bias = gwy_get_gfloat_le(&p); gwy_debug("bias: %g", header->bias); header->reference_value = gwy_get_gfloat_le(&p); gwy_debug("reference_value: %g", header->reference_value); p += 2; /* reserved */ header->measurement_date.day = *(p++); header->measurement_date.month = *(p++); header->measurement_date.year_1980 = gwy_get_guint16_le(&p); header->measurement_date.weekday_sun = *(p++); header->save_date.day = *(p++); header->save_date.month = *(p++); header->save_date.year_1980 = gwy_get_guint16_le(&p); header->save_date.weekday_sun = *(p++); header->measurement_time.hour = *(p++); header->measurement_time.minute = *(p++); header->measurement_time.second= *(p++); header->measurement_time.second_100 = *(p++); header->save_time.hour = *(p++); header->save_time.minute = *(p++); header->save_time.second= *(p++); header->save_time.second_100 = *(p++); p += 0x100; /* lookup table */ header->fft_offset = gwy_get_guint32_le(&p); header->transform_off = gwy_get_guint16_le(&p); p += 8; /* extra */ header->compressed = gwy_get_gboolean8(&p); header->bpp = *(p++); gwy_debug("bpp: %d", header->bpp); header->cits_offset = gwy_get_guint32_le(&p); header->backscan_tip_voltage = gwy_get_gfloat_le(&p); header->sts_point_x = gwy_get_guint16_le(&p); header->sts_point_y = gwy_get_guint16_le(&p); p += 20; /* reserved */ header->tip_speed_x = gwy_get_gfloat_le(&p); header->tip_speed_y = gwy_get_gfloat_le(&p); p += 42; /* piezo_sensitivity */ header->spm_param.clock = gwy_get_gfloat_le(&p); header->spm_param.rotation = gwy_get_gfloat_le(&p); header->spm_param.feedback_filter = gwy_get_gfloat_le(&p); header->spm_param.present_filter = gwy_get_gfloat_le(&p); header->spm_param.head_amp_gain = gwy_get_gfloat_le(&p); header->spm_param.loop_gain = gwy_get_guint16_le(&p); header->spm_param.x_off = gwy_get_gfloat_le(&p); header->spm_param.y_off = gwy_get_gfloat_le(&p); header->spm_param.z_gain = gwy_get_gfloat_le(&p); header->spm_param.z_off = gwy_get_gfloat_le(&p); header->spm_param.o_gain = gwy_get_gfloat_le(&p); header->spm_param.o_off = gwy_get_gfloat_le(&p); gwy_debug("z_gain: %g o_gain: %g", header->spm_param.z_gain, header->spm_param.o_gain); header->spm_param.back_scan_bias = gwy_get_gfloat_le(&p); /* XXX: This does not match what the documentation says, there seems to be * a four-byte quantity missing between back_scan_bias and mode (the size * of SPM params struct is also 4 bytes shorter than the space alloted for * it). */ p += 4; /* whatever */ header->spm_param.mode = gwy_get_guint32_le(&p); gwy_debug("mode: %d", header->spm_param.mode); p += 2; /* reserved */ header->montage_offset = gwy_get_guint32_le(&p); get_CHARARRAY0(header->image_location, &p); p += 2*4; /* reserved */ header->spm_misc_param.dds_frequency = gwy_get_gfloat_le(&p); header->spm_misc_param.dds_low_filter = gwy_get_guint16_le(&p); header->spm_misc_param.dds_high_filter = gwy_get_guint16_le(&p); header->spm_misc_param.dds_center_filter = gwy_get_guint16_le(&p); header->spm_misc_param.dds_enable = gwy_get_guint16_le(&p); header->spm_misc_param.scan_filter = gwy_get_guint16_le(&p); header->spm_misc_param.afm_mode = gwy_get_guint32_le(&p); gwy_debug("afm_mode: 0x%x", header->spm_misc_param.afm_mode); header->spm_misc_param.slope_gain = gwy_get_guint32_le(&p); header->spm_misc_param.x_addition_signal = gwy_get_guint16_le(&p); header->spm_misc_param.y_addition_signal = gwy_get_guint16_le(&p); header->spm_misc_param.z_addition_signal = gwy_get_guint16_le(&p); header->spm_misc_param.bias_addition_signal = gwy_get_guint16_le(&p); header->spm_misc_param.active_dialog = gwy_get_guint32_le(&p); header->spm_misc_param.spm_mode = gwy_get_guint32_le(&p); gwy_debug("spm_mode: 0x%x", header->spm_misc_param.spm_mode); header->spm_misc_param.measurement_signal = gwy_get_guint32_le(&p); gwy_debug("signal: 0x%x", header->spm_misc_param.measurement_signal); header->spm_misc_param.phase_vco_scan = gwy_get_guint16_le(&p); header->spm_misc_param.sps_mode = gwy_get_guint32_le(&p); header->spm_misc_param.dds_amplitude = gwy_get_gdouble_le(&p); header->spm_misc_param.dds_center_locked_freq = gwy_get_gdouble_le(&p); header->spm_misc_param.dds_phase_shift = gwy_get_gfloat_le(&p); header->spm_misc_param.dds_high_gain = gwy_get_guint16_le(&p); header->spm_misc_param.dds_phase_polarity = gwy_get_guint16_le(&p); header->spm_misc_param.dds_pll_excitation = gwy_get_guint16_le(&p); header->spm_misc_param.dds_external = gwy_get_guint16_le(&p); header->spm_misc_param.dds_rms_filter = gwy_get_guint32_le(&p); header->spm_misc_param.dds_pll_loop_gain = gwy_get_guint32_le(&p); header->spm_misc_param.dds_beat_noise = gwy_get_guint32_le(&p); header->spm_misc_param.dds_dynamic_range = gwy_get_guint32_le(&p); header->spm_misc_param.cantilever_peak_freq = gwy_get_guint32_le(&p); header->spm_misc_param.cantilever_q_factor = gwy_get_guint32_le(&p); p += 10; /* reserved */ p += 0x300; /* RGB lookup table */ header->sub_revision_no = gwy_get_guint32_le(&p); header->image_type = gwy_get_guint32_le(&p); gwy_debug("image_type: %d", header->image_type); header->data_source = gwy_get_guint32_le(&p); gwy_debug("data_source: %d", header->data_source); header->display_mode = gwy_get_guint32_le(&p); p += 2*8; /* measurement_start_time, measurement_end_time */ p += 254; /* profile_roughness */ p += 446; /* settings_3d */ header->lut_brightness = gwy_get_gfloat_le(&p); header->lut_contrast = gwy_get_gfloat_le(&p); header->software_version = gwy_get_guint16_le(&p); header->software_subversion = gwy_get_guint32_le(&p); p += 20; /* extracted_region */ header->lut_gamma = gwy_get_gfloat_le(&p); header->n_of_sps = gwy_get_guint16_le(&p); header->sps_offset = gwy_get_guint32_le(&p); header->line_trace_end_x = gwy_get_guint16_le(&p); header->line_trace_end_y = gwy_get_guint16_le(&p); header->forward = gwy_get_guint16_le(&p); gwy_debug("forward: %d", header->forward); header->lift_signal = gwy_get_guint16_le(&p); /* stuff... */ }
static GwyDataField* read_data_field_old(const guchar *buffer, guint size, GError **error) { gint xres, yres, n, i, j, vx, vy; G_GNUC_UNUSED gint vz; gdouble xscale, yscale, zscale, xreal, yreal, q; G_GNUC_UNUSED gdouble xunit, yunit, zunit; GwyDataField *dfield; GwySIUnit *siunit; gdouble *data, *row; const gint16 *pdata; const guchar *p; p = buffer + RES_OFFSET_OLD; xres = gwy_get_guint16_le(&p); yres = gwy_get_guint16_le(&p); gwy_debug("xres: %d, yres: %d", xres, yres); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; n = xres*yres; if (err_SIZE_MISMATCH(error, 2*n + HEADER_SIZE_OLD, size, TRUE)) return NULL; p = buffer + SCALE_OFFSET_OLD; xscale = gwy_get_gdouble_le(&p); yscale = gwy_get_gdouble_le(&p); zscale = gwy_get_gdouble_le(&p); p = buffer + UNIT_OFFSET_OLD; xunit = gwy_get_gdouble_le(&p); yunit = gwy_get_gdouble_le(&p); zunit = gwy_get_gdouble_le(&p); p = buffer + SPEED_OFFSET_OLD; vx = gwy_get_guint32_le(&p); vy = gwy_get_guint32_le(&p); vz = gwy_get_guint32_le(&p); xreal = xscale * vx; yreal = yscale * vy; q = zscale; gwy_debug("xreal: %g, yreal: %g, zscale: %g", xreal, yreal, q); /* 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); data = gwy_data_field_get_data(dfield); pdata = (const gint16*)(buffer + HEADER_SIZE_OLD); for (i = 0; i < yres; i++) { row = data + i*xres; for (j = 0; j < xres; j++) row[j] = GUINT16_FROM_LE(pdata[i*xres + j])*q; } siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); return dfield; }
static GwyDataField* read_data_field(const guchar *buffer, guint size, GError **error) { gint xres, yres, n, i, j; gdouble xreal, yreal, q; GwyDataField *dfield; GwySIUnit *siunit; gdouble *data, *row; const gint16 *pdata; const guchar *p; p = buffer + RES_OFFSET; xres = gwy_get_guint32_le(&p); yres = gwy_get_guint32_le(&p); gwy_debug("xres: %d, yres: %d", xres, yres); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; n = xres*yres; if (err_SIZE_MISMATCH(error, 2*n + HEADER_SIZE, size, TRUE)) return NULL; p = buffer + XREAL_OFFSET; xreal = gwy_get_gdouble_le(&p) * Nanometer; p = buffer + YREAL_OFFSET; yreal = gwy_get_gdouble_le(&p) * Nanometer; p = buffer + ZSCALE_OFFSET; q = gwy_get_gdouble_le(&p) * Nanometer; gwy_debug("xreal: %g, yreal: %g, zreal: %g", xreal/Nanometer, yreal/Nanometer, q/Nanometer); /* 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; } /* XXX: I don't know where the factor of 0.5 comes from. But it makes * the imported data match the original software. */ q /= 2.0; q /= 65536.0; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); data = gwy_data_field_get_data(dfield); pdata = (const gint16*)(buffer + HEADER_SIZE); for (i = 0; i < yres; i++) { row = data + (yres-1 - i)*xres; for (j = 0; j < xres; j++) row[j] = GUINT16_FROM_LE(pdata[i*xres + j])*q; } siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); siunit = gwy_si_unit_new("m"); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); return dfield; }
static GwyContainer* microprof_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { enum { XRES = 0x0026, YRES = 0x002a, XRANGE = 0x0038, YRANGE = 0x0040, ZRANGE = 0x006e, }; GwyContainer *container = NULL; guchar *buffer = NULL; const guchar *p; MicroProfFile mfile; gsize size = 0; GError *err = NULL; guint i, ndata, datasize; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < MICROPROF_HEADER_SIZE) { err_TOO_SHORT(error); goto fail; } if (memcmp(buffer, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "MicroProf"); goto fail; } p = buffer + XRES; mfile.xres = gwy_get_guint16_le(&p); if (err_DIMENSION(error, mfile.xres)) goto fail; p = buffer + YRES; mfile.yres = gwy_get_guint16_le(&p); if (err_DIMENSION(error, mfile.xres)) goto fail; p = buffer + XRANGE; mfile.xrange = gwy_get_gdouble_le(&p); if (!(mfile.xrange = fabs(mfile.xrange))) { g_warning("Real x size is 0.0, fixing to 1.0"); mfile.xrange = 1.0; } p = buffer + YRANGE; mfile.yrange = gwy_get_gdouble_le(&p); if (!(mfile.yrange = fabs(mfile.yrange))) { g_warning("Real y size is 0.0, fixing to 1.0"); mfile.yrange = 1.0; } p = buffer + ZRANGE; mfile.zscale = gwy_get_gdouble_le(&p); datasize = 2*mfile.xres*mfile.yres; if (err_SIZE_MISMATCH(error, datasize, size - MICROPROF_HEADER_SIZE, FALSE)) goto fail; /* FIXME: There is weird stuff between channels. Need specs. ndata = (size - MICROPROF_HEADER_SIZE)/datasize; if (!ndata) { err_NO_DATA(error); goto fail; } */ ndata = 1; container = gwy_container_new(); mfile.data = buffer + MICROPROF_HEADER_SIZE; for (i = 0; i < ndata; i++) { GwyDataField *dfield; GQuark quark; dfield = microprof_read_data_field(&mfile, mfile.data + i*datasize); quark = gwy_app_get_data_key_for_id(i); gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); gwy_app_channel_title_fall_back(container, i); gwy_file_channel_import_log_add(container, i, NULL, filename); } fail: gwy_file_abandon_contents(buffer, size, NULL); return container; }
static GwyDataField* sdfile_read_data_bin(SDFile *sdfile) { gint i, n; GwyDataField *dfield; gdouble *data; const guchar *p; dfield = gwy_data_field_new(sdfile->xres, sdfile->yres, sdfile->xres * sdfile->xscale, sdfile->yres * sdfile->yscale, FALSE); data = gwy_data_field_get_data(dfield); n = sdfile->xres * sdfile->yres; /* We assume Intel byteorder, although the format does not specify * any order. But it was developed in PC context... */ switch (sdfile->data_type) { case SDF_UINT8: for (i = 0; i < n; i++) data[i] = sdfile->data[i]; break; case SDF_SINT8: for (i = 0; i < n; i++) data[i] = (signed char)sdfile->data[i]; break; case SDF_UINT16: { const guint16 *pdata = (const guint16*)(sdfile->data); for (i = 0; i < n; i++) data[i] = GUINT16_FROM_LE(pdata[i]); } break; case SDF_SINT16: { const gint16 *pdata = (const gint16*)(sdfile->data); for (i = 0; i < n; i++) data[i] = GINT16_FROM_LE(pdata[i]); } break; case SDF_UINT32: { const guint32 *pdata = (const guint32*)(sdfile->data); for (i = 0; i < n; i++) data[i] = GUINT32_FROM_LE(pdata[i]); } break; case SDF_SINT32: { const gint32 *pdata = (const gint32*)(sdfile->data); for (i = 0; i < n; i++) data[i] = GINT32_FROM_LE(pdata[i]); } break; case SDF_FLOAT: p = sdfile->data; for (i = 0; i < n; i++) data[i] = gwy_get_gfloat_le(&p); break; case SDF_DOUBLE: p = sdfile->data; for (i = 0; i < n; i++) data[i] = gwy_get_gdouble_le(&p); break; default: g_object_unref(dfield); g_return_val_if_reached(NULL); break; } return dfield; }