static gboolean rhk_sm4_read_drift_header(RHKSpecDriftHeader *drift_header, const RHKObject *obj, const guchar *buffer) { const guchar *p = buffer + obj->offset; if (obj->size < 16) return FALSE; drift_header->start_time = gwy_get_guint64_le(&p); drift_header->drift_opt = gwy_get_gint16_le(&p); drift_header->nstrings = gwy_get_guint16_le(&p); /* TODO: Read the strings. */ return TRUE; }
static RHKSpecDriftHeader* rhk_sm4_read_drift_header(const RHKObject *obj, const guchar *buffer) { RHKSpecDriftHeader *drift_header = NULL; const guchar *p = buffer + obj->offset; if (obj->size < 16) return drift_header; drift_header = g_new0(RHKSpecDriftHeader, 1); drift_header->start_time = gwy_get_guint64_le(&p); drift_header->drift_opt = gwy_get_gint16_le(&p); drift_header->nstrings = gwy_get_guint16_le(&p); /* TODO: Read the strings. */ return drift_header; }
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; }