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 gint burleigh_detect(const GwyFileDetectInfo *fileinfo, gboolean only_name) { const guchar *buffer; guint version_int, xres, yres; gdouble version; if (only_name) return g_str_has_suffix(fileinfo->name_lowercase, EXTENSION) ? 10 : 0; if (fileinfo->buffer_len < 4) return 0; buffer = fileinfo->head; version = gwy_get_gfloat_le(&buffer); version_int = GWY_ROUND(10*version); gwy_debug("Version: %g", version); if (version_int == 21) { if (fileinfo->file_size < TOTAL_SIZE_V21 + 2) return 0; xres = gwy_get_guint16_le(&buffer); yres = gwy_get_guint16_le(&buffer); if (fileinfo->file_size == TOTAL_SIZE_V21 + 2*xres*yres) return 100; return 0; } return 0; }
static const guchar* pt3file_read_board(PicoHarpBoard *board, const guchar *p) { guint i; get_CHARARRAY(board->hardware_ident, &p); get_CHARARRAY(board->hardware_version, &p); gwy_debug("<%.*s> <%.*s>", (gint)sizeof(board->hardware_ident), board->hardware_ident, (gint)sizeof(board->hardware_version), board->hardware_version); board->hardware_serial = gwy_get_guint32_le(&p); board->sync_divider = gwy_get_guint32_le(&p); board->cfd_zero_cross0 = gwy_get_guint32_le(&p); board->cfd_level0 = gwy_get_guint32_le(&p); board->cfd_zero_cross1 = gwy_get_guint32_le(&p); board->cfd_level1 = gwy_get_guint32_le(&p); board->resolution = gwy_get_gfloat_le(&p); board->router_model_code = gwy_get_guint32_le(&p); board->router_enabled = !!gwy_get_guint32_le(&p); for (i = 0; i < G_N_ELEMENTS(board->rt_channel); i++) { board->rt_channel[i].input_type = gwy_get_guint32_le(&p); board->rt_channel[i].input_level = gwy_get_gint32_le(&p); board->rt_channel[i].input_edge = gwy_get_guint32_le(&p); board->rt_channel[i].cfd_present = !!gwy_get_guint32_le(&p); board->rt_channel[i].cfd_level = gwy_get_gint32_le(&p); board->rt_channel[i].cfd_zero_cross = gwy_get_gint32_le(&p); } return p; }
static const gint16* burleigh_load_v21(IMGFile *imgfile, const guchar *buffer, gsize size, GError **error) { const guchar *p = buffer + 4; /* size of version */ guint32 n; /* Header */ imgfile->xres = gwy_get_guint16_le(&p); imgfile->yres = gwy_get_guint16_le(&p); n = imgfile->xres * imgfile->yres; if (err_SIZE_MISMATCH(error, 2*n + TOTAL_SIZE_V21, size, TRUE)) return NULL; /* Skip to footer */ p += 2*n; imgfile->xrangemax = gwy_get_guint32_le(&p); imgfile->yrangemax = gwy_get_guint32_le(&p); imgfile->zrangemax = gwy_get_guint32_le(&p); imgfile->xrange = gwy_get_guint32_le(&p); imgfile->yrange = gwy_get_guint32_le(&p); gwy_debug("xrange: %u, yrange: %u", imgfile->xrange, imgfile->yrange); imgfile->zrange = gwy_get_guint32_le(&p); gwy_debug("zrange: %u", imgfile->zrange); imgfile->scan_speed = gwy_get_guint16_le(&p); imgfile->zoom_level = gwy_get_guint16_le(&p); gwy_debug("zoom_level: %u", imgfile->zoom_level); imgfile->data_type = gwy_get_guint16_le(&p); gwy_debug("data_type: %u", imgfile->data_type); imgfile->z_gain = gwy_get_guint16_le(&p); imgfile->bias_volts = gwy_get_gfloat_le(&p); imgfile->tunneling_current = gwy_get_gfloat_le(&p); /* Use negated positive conditions to catch NaNs */ if (!((imgfile->xrange = fabs(imgfile->xrange)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); imgfile->xrange = 1.0; } if (!((imgfile->yrange = fabs(imgfile->yrange)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); imgfile->yrange = 1.0; } return (const gint16*)(buffer + HEADER_SIZE_V21); }
static void fill_data_fields(APEFile *apefile, const guchar *buffer) { GwyDataField *dfield; GwySIUnit *unit; gdouble *data; const gchar *zunit; guint b, n, i, j, k; gdouble q; apefile->data = g_new0(GwyDataField*, apefile->ndata); for (b = apefile->channels, n = 0, k = 0; b; b = b >> 1, k++) { if (!(b & 1)) continue; dfield = gwy_data_field_new(apefile->res, apefile->res, apefile->xreal, apefile->yreal, FALSE); unit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string(unit, "m"); data = gwy_data_field_get_data(dfield); buffer += (apefile->res + 1)*sizeof(float); switch (k) { case APE_HEIGHT: case APE_HEIGHT_R: case APE_AUX2: case APE_AUX2_R: q = apefile->z_piezo_factor * 1e-9; zunit = "m"; break; case APE_AUX1: case APE_AUX1_R: q = 1.0; zunit = apefile->pg850_image ? "A" : "V"; break; default: q = 1.0; zunit = "V"; break; } unit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_set_from_string(unit, zunit); for (i = 0; i < apefile->res; i++) { /* There is always one ignored record, do not ask me why... */ buffer += sizeof(float); for (j = 0; j < apefile->res; j++) { *(data++) = q*gwy_get_gfloat_le(&buffer); } } apefile->data[n] = dfield; n++; } }
static const guchar* read_pie710_imaging_header(PicoHarpImagingHeader *header, const guchar *p) { header->pie710.time_per_pixel = gwy_get_guint32_le(&p); header->pie710.acceleration = gwy_get_guint32_le(&p); header->pie710.bidirectional = !!gwy_get_guint32_le(&p); header->pie710.reserved = gwy_get_guint32_le(&p); header->pie710.xoff = gwy_get_gfloat_le(&p); header->pie710.yoff = gwy_get_gfloat_le(&p); header->pie710.xres = gwy_get_guint32_le(&p); header->pie710.yres = gwy_get_guint32_le(&p); header->pie710.pix_resol = gwy_get_gfloat_le(&p); header->pie710.t_start_to = gwy_get_gfloat_le(&p); header->pie710.t_stop_to = gwy_get_gfloat_le(&p); header->pie710.t_start_from = gwy_get_gfloat_le(&p); header->pie710.t_stop_from = gwy_get_gfloat_le(&p); gwy_debug("accel %u, bidirectional: %d", header->pie710.acceleration, header->pie710.bidirectional); gwy_debug("%g %g %g %g", header->pie710.t_start_to, header->pie710.t_stop_to, header->pie710.t_start_from, header->pie710.t_stop_from); return p; }
static RHKSpecInfo* rhk_sm4_read_spec_info(const RHKObject *obj, const guchar *buffer, gsize size, guint nspec) { enum { SPEC_INFO_SIZE = 28 }; const guchar *p = buffer + obj->offset; RHKSpecInfo *spec_infos = NULL; guint i; if (obj->size != SPEC_INFO_SIZE) return spec_infos; if (obj->offset + nspec*SPEC_INFO_SIZE >= size) return spec_infos; spec_infos = g_new(RHKSpecInfo, nspec); for (i = 0; i < nspec; i++) { RHKSpecInfo *spec_info = spec_infos + i; spec_info->ftime = gwy_get_gfloat_le(&p); spec_info->x_coord = gwy_get_gfloat_le(&p); spec_info->y_coord = gwy_get_gfloat_le(&p); gwy_debug("[%u] x_coord = %g, y_coord = %g", i, spec_info->x_coord, spec_info->y_coord); spec_info->dx = gwy_get_gfloat_le(&p); spec_info->dy = gwy_get_gfloat_le(&p); spec_info->cumulative_dx = gwy_get_gfloat_le(&p); spec_info->cumulative_dy = gwy_get_gfloat_le(&p); } return spec_infos; }
static const guchar* read_kdt180_imaging_header(PicoHarpImagingHeader *header, const guchar *p) { header->kdt180.velocity = gwy_get_guint32_le(&p); header->kdt180.acceleration = gwy_get_guint32_le(&p); header->kdt180.bidirectional = !!gwy_get_guint32_le(&p); header->kdt180.reserved = gwy_get_guint32_le(&p); header->kdt180.xoff = gwy_get_gfloat_le(&p); header->kdt180.yoff = gwy_get_gfloat_le(&p); header->kdt180.xres = gwy_get_guint32_le(&p); header->kdt180.yres = gwy_get_guint32_le(&p); header->kdt180.pix_resol = gwy_get_gfloat_le(&p); gwy_debug("accel %u, bidirectional: %d", header->pie710.acceleration, header->pie710.bidirectional); return p; }
static const gint16* burleigh_load_v21(IMGFile *imgfile, const guchar *buffer, gsize size, GError **error) { const guchar *p = buffer + 4; /* size of version */ guint32 n; /* Header */ imgfile->xres = gwy_get_guint16_le(&p); imgfile->yres = gwy_get_guint16_le(&p); n = imgfile->xres * imgfile->yres; if (size != 2*n + TOTAL_SIZE_V21) { err_SIZE_MISMATCH(error, 2*n + TOTAL_SIZE_V21, size); return NULL; } /* Skip to footer */ p += 2*n; imgfile->xrangemax = gwy_get_guint32_le(&p); imgfile->yrangemax = gwy_get_guint32_le(&p); imgfile->zrangemax = gwy_get_guint32_le(&p); imgfile->xrange = gwy_get_guint32_le(&p); imgfile->yrange = gwy_get_guint32_le(&p); gwy_debug("xrange: %u, yrange: %u", imgfile->xrange, imgfile->yrange); imgfile->zrange = gwy_get_guint32_le(&p); gwy_debug("zrange: %u", imgfile->zrange); imgfile->scan_speed = gwy_get_guint16_le(&p); imgfile->zoom_level = gwy_get_guint16_le(&p); gwy_debug("zoom_level: %u", imgfile->zoom_level); imgfile->data_type = gwy_get_guint16_le(&p); gwy_debug("data_type: %u", imgfile->data_type); imgfile->z_gain = gwy_get_guint16_le(&p); imgfile->bias_volts = gwy_get_gfloat_le(&p); imgfile->tunneling_current = gwy_get_gfloat_le(&p); return (const gint16*)(buffer + HEADER_SIZE_V21); }
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; }
// FIXME: In fact, there is an yres-long array of SpecInfo. static gboolean rhk_sm4_read_spec_info(RHKSpecInfo *spec_info, const RHKObject *obj, const guchar *buffer) { const guchar *p = buffer + obj->offset; if (obj->size < 28) return FALSE; spec_info->ftime = gwy_get_gfloat_le(&p); spec_info->x_coord = gwy_get_gfloat_le(&p); spec_info->y_coord = gwy_get_gfloat_le(&p); gwy_debug("x_coord = %g, y_coord = %g", spec_info->x_coord, spec_info->y_coord); spec_info->dx = gwy_get_gfloat_le(&p); spec_info->dy = gwy_get_gfloat_le(&p); spec_info->cumulative_dx = gwy_get_gfloat_le(&p); spec_info->cumulative_dy = gwy_get_gfloat_le(&p); return TRUE; }
static GwyContainer* surffile_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SurfFile surffile; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; const guchar *p; gsize expected_size, size = 0; GError *err = NULL; gchar signature[12]; gdouble max, min; gint add = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); g_clear_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.measurement_duration = gwy_get_guint16_le(&p); 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); 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); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } } p = buffer + SURF_HEADER_SIZE + add; if (!fill_data_fields(&surffile, p, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (!surffile.absolute) { max = gwy_data_field_get_max(surffile.dfield); min = gwy_data_field_get_min(surffile.dfield); gwy_data_field_add(surffile.dfield, -min); gwy_data_field_multiply(surffile.dfield, (surffile.zmax - surffile.zmin)/(max-min)); } 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; } 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); 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 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* 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 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 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* 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 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 read_file_info(const guchar *buffer, gsize size, FileInfo *info, GError **error) { guint expected_size, i; const guchar *p; gwy_clear(info, 1); p = buffer + MAGIC_SIZE; /* read structure variables from buffer */ for (i = 0; i < (HEADER_SIZE - MAGIC_SIZE)/8; i++) { gchar key[5]; guint32 value; key[4] = '\0'; memcpy(key, p, 4); p += 4; value = gwy_get_guint32_le(&p); if (!key[0]) continue; gwy_debug("%s: 0x%04x", key, value); /* Do not take values past the end of file and zeros into account at * all. The software seems to sometimes emit silly extra fields. */ if (!value || value >= size) continue; else if (gwy_strequal(key, "DESC")) info->desc_offset = value; else if (gwy_strequal(key, "DATE")) info->date_offset = value; else if (gwy_strequal(key, "PLET")) info->palette_offset = value; else if (gwy_strequal(key, "IMAG")) info->image_offset = value; else if (gwy_strequal(key, "HARD")) info->hard_offset = value; else if (gwy_strequal(key, "IMGP")) info->img_p_offset = value; else if (gwy_strequal(key, "SDES")) info->short_desc_offset = value; else if (gwy_strequal(key, "KEYS")) info->keys_offset = value; else { gwy_debug("Unknown field %s", key); } } /* Pixel image size */ if (!(p = get_param_pointer(buffer, size, info->image_offset, sizeof(guint16), "IMAG", error))) return FALSE; info->img_res = gwy_get_guint16_le(&p); if (err_DIMENSION(error, info->img_res)) return FALSE; /* Image data. It is the *same* pointer, just after the pixel size. */ info->image_data = (const guint16*)p; expected_size = (p - buffer) + info->img_res*info->img_res*sizeof(guint16); if (err_SIZE_MISMATCH(error, expected_size, size, FALSE)) return FALSE; /* Real image size */ if (!(p = get_param_pointer(buffer, size, info->hard_offset, sizeof(gfloat), "HARD", error))) return FALSE; info->real_size = gwy_get_gfloat_le(&p); if (!((info->real_size = fabs(info->real_size)) > 0)) { g_warning("Real size is 0.0, fixing to 1.0"); info->real_size = 1.0; } /* Value scale factor */ if (!(p = get_param_pointer(buffer, size, info->img_p_offset + 8, sizeof(gfloat), "IMGP", error))) return FALSE; info->z_scale = gwy_get_gfloat_le(&p); return TRUE; }
static RHKPage* rhk_sm3_read_page(const guchar **buffer, gsize *len, GError **error) { RHKPage *page; const guchar *p = *buffer; guint i, expected; if (!*len) return NULL; if (*len < HEADER_SIZE + 4) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached in page header.")); return NULL; } if (memcmp(p + MAGIC_OFFSET, MAGIC, MAGIC_SIZE) != 0) { err_INVALID(error, _("magic page header")); return NULL; } page = g_new0(RHKPage, 1); page->param_size = gwy_get_guint16_le(&p); gwy_debug("param_size = %u", page->param_size); if (*len < page->param_size + 4) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached in page header.")); goto FAIL; } /* TODO: Convert to UTF-8, store to meta */ memcpy(page->version, p, MAGIC_TOTAL_SIZE); p += MAGIC_TOTAL_SIZE; page->string_count = gwy_get_guint16_le(&p); gwy_debug("string_count = %u", page->string_count); page->type = gwy_get_guint32_le(&p); gwy_debug("type = %u", page->type); 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); 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); page->source_type = gwy_get_guint32_le(&p); 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 = %u", 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); 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); get_CHARARRAY(page->page_id, &p); p = *buffer + 2 + page->param_size; for (i = 0; i < page->string_count; i++) { gchar *s; gwy_debug("position %04x", p - *buffer); s = rhk_sm3_read_string(&p, *len - (p - *buffer)); if (!s) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached in string #%u."), i); goto FAIL; } if (i < RHK_STRING_NSTRINGS) page->strings[i] = s; else g_free(s); } expected = page->x_size * page->y_size * sizeof(gint32); gwy_debug("expecting %u bytes of page data now", expected); if (*len < (p - *buffer) + expected) { err_SIZE_MISMATCH(error, expected, *len - (p - *buffer)); goto FAIL; } if (page->type == RHK_TYPE_IMAGE) page->page_data = p; else page->spectral_data = p; p += expected; if (page->type == RHK_TYPE_IMAGE) { if (*len < (p - *buffer) + 4) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached in color data header.")); goto FAIL; } /* Info size includes itself */ page->color_info.size = gwy_get_guint32_le(&p) - 2; if (*len < (p - *buffer) + page->color_info.size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("End of file reached in color data.")); goto FAIL; } p += page->color_info.size; } *len -= p - *buffer; *buffer = p; return page; FAIL: rhk_sm3_page_free(page); return NULL; }
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 GwyDataField* unisoku_read_data_field(const guchar *buffer, gsize size, UnisokuFile *ufile, GError **error) { gint i, n, power10; const gchar *unit; GwyDataField *dfield; GwySIUnit *siunit; gdouble q, pmin, pmax, rmin, rmax; gdouble *data; n = ufile->xres * ufile->yres; if (err_SIZE_MISMATCH(error, n*type_sizes[ufile->data_type], size, FALSE)) return NULL; dfield = gwy_data_field_new(ufile->xres, ufile->yres, fabs((ufile->end_x - ufile->start_x)), fabs((ufile->end_y - ufile->start_y)), FALSE); data = gwy_data_field_get_data(dfield); /* FIXME: what to do when ascii_flag is set? */ switch (ufile->data_type) { case UNISOKU_UINT8: for (i = 0; i < n; i++) data[i] = buffer[i]; break; case UNISOKU_SINT8: for (i = 0; i < n; i++) data[i] = (signed char)buffer[i]; break; case UNISOKU_UINT16: { const guint16 *pdata = (const guint16*)buffer; for (i = 0; i < n; i++) data[i] = GUINT16_FROM_LE(pdata[i]); } break; case UNISOKU_SINT16: { const gint16 *pdata = (const gint16*)buffer; for (i = 0; i < n; i++) data[i] = GINT16_FROM_LE(pdata[i]); } break; case UNISOKU_FLOAT: for (i = 0; i < n; i++) data[i] = gwy_get_gfloat_le(&buffer); break; default: g_return_val_if_reached(NULL); break; } unit = ufile->unit_x; if (!*unit) unit = "nm"; siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_xy(dfield, siunit); q = pow10((gdouble)power10); gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield)); gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield)); g_object_unref(siunit); unit = ufile->unit_z; /* XXX: No fallback yet, just make z unitless */ siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); q = pow10((gdouble)power10); pmin = q*ufile->min_z; pmax = q*ufile->max_z; rmin = ufile->min_raw_z; rmax = ufile->max_raw_z; gwy_data_field_multiply(dfield, (pmax - pmin)/(rmax - rmin)); gwy_data_field_add(dfield, (pmin*rmax - pmax*rmin)/(rmax - rmin)); g_object_unref(siunit); return dfield; }
static GwySpectra* rhkspm32_read_spectra(RHKPage *rhkpage) { guint i, j; gdouble *data; GwySIUnit *siunit = NULL; GwyDataLine *dline; GwySpectra *spectra = NULL; GPtrArray *spectrum = NULL; // i'm leaving this alone, though it probably doesn't make sense, // and i should just create graphs straight away - but in case of // future use, i'll just convert the data later to graphs // xres stores number of data points per spectra, // yres stores the number of spectra // reading data gwy_debug("rhk-spm32: %d spectra in this page\n", rhkpage->yres); for (i = 0; i < rhkpage->yres; i++) { dline = gwy_data_line_new(rhkpage->xres, rhkpage->x.scale, FALSE); gwy_data_line_set_offset(dline, (rhkpage->x.offset)); data = gwy_data_line_get_data(dline); // store line data in physical units - which are the z values, not y if ((rhkpage->data_type) == RHK_DATA_INT16) { const guint16 *p = (const guint16*)(rhkpage->buffer + rhkpage->data_offset); for (j = 0; j < rhkpage->xres; j++) { data[j] = GINT16_FROM_LE(p[i*(rhkpage->xres) + j]) *(rhkpage->z.scale)+(rhkpage->z.offset); } } else if ((rhkpage->data_type) == RHK_DATA_SINGLE) { const guchar *p = (const guchar*)(rhkpage->buffer + rhkpage->data_offset); for (j = 0; j < rhkpage->xres; j++) { data[j] = gwy_get_gfloat_le(&p)*rhkpage->z.scale + rhkpage->z.offset; } } siunit = gwy_si_unit_new(rhkpage->x.units); gwy_data_line_set_si_unit_x(dline, siunit); g_object_unref(siunit); // the y units (and data) for a 1D graph are stored in Z in the rhk // spm32 format! /* Fix "/\xfbHz" to "/Hz". * XXX: It might be still wrong as the strange character might mean * sqrt. */ if (g_str_has_suffix(rhkpage->z.units, "/\xfbHz")) { gchar *s = gwy_strkill(g_strdup(rhkpage->z.units), "\xfb"); siunit = gwy_si_unit_new(s); g_free(s); } else siunit = gwy_si_unit_new(rhkpage->z.units); gwy_data_line_set_si_unit_y(dline, siunit); g_object_unref(siunit); if (!spectrum) spectrum = g_ptr_array_sized_new(rhkpage->yres); g_ptr_array_add(spectrum, dline); } gwy_debug("rhk-spm32: finished parsing sps data\n"); spectra = gwy_spectra_new(); for (i = 0; i < rhkpage->yres; i++) { dline = g_ptr_array_index(spectrum, i); // since RHK spm32 does not record where it took the spectra, // i'm setting these to zero gwy_spectra_add_spectrum(spectra, dline, 0, 0); g_object_unref(dline); } gwy_spectra_set_title(spectra, rhkpage->label); if (spectrum) g_ptr_array_free(spectrum, TRUE); return spectra; }
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 gdouble get_gfloat_le_as_double(const guchar **p) { return gwy_get_gfloat_le(p); }
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 gboolean mif_read_image_header(MIFImageHeader *header, const guchar **p, gsize size, guint file_version, GError **error) { const guchar *buffer = *p; guint i; gwy_clear(header, 1); if (size < IMAGE_HEADER_START_SIZE) return err_IMAGE_HEADER_TOO_SHORT(error); get_CHARARRAY(header->time, p); get_CHARARRAY(header->title, p); get_CHARARRAY(header->comment, p); gwy_debug("image <%.*s>", (guint)sizeof(header->title), header->title); if (!mif_read_scan_setup(&header->setup, p, size - (*p - buffer), file_version, error)) return FALSE; if (!mif_read_image_configuration(&header->configuration, p, size - (*p - buffer), file_version, error)) return FALSE; if (file_version == 0x107) { /* TODO: Check size */ header->tunnel_current = gwy_get_gfloat_le(p); gwy_debug("tunnel_current: %g", header->tunnel_current); header->bias_voltage = gwy_get_gfloat_le(p); gwy_debug("bias_voltage: %g", header->bias_voltage); header->force = gwy_get_gfloat_le(p); gwy_debug("force: %g", header->force); header->as_measured = *((*p)++); gwy_debug_bool(header, as_measured); header->n_curves = gwy_get_guint32_le(p); gwy_debug("n_curves: %u", header->n_curves); for (i = 0; i < MAX_CURVES; i++) { header->curve_points[i].x = gwy_get_guint32_le(p); header->curve_points[i].y = gwy_get_guint32_le(p); } header->low_fraction = gwy_get_gfloat_le(p); header->high_fraction = gwy_get_gfloat_le(p); gwy_debug("low_fraction: %g, high_fraction: %g", header->low_fraction, header->high_fraction); if (!mif_read_axis_info(&header->z_axis, p, size - (*p - buffer), file_version, error)) return FALSE; if (!mif_read_id(&header->id.primary, p, size - (*p - buffer), error) || !mif_read_id(&header->id.secondary, p, size - (*p - buffer), error)) return FALSE; } else { g_return_val_if_reached(FALSE); } return TRUE; }
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* gsf_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta = NULL; GwyDataField *dfield = NULL; GwyTextHeaderParser parser; GwySIUnit *unit; guchar *p, *value, *buffer = NULL, *header = NULL; const guchar *datap; GHashTable *hash = NULL; gsize size, expected_size; GError *err = NULL; gdouble xreal, yreal, xoff, yoff; guint i, xres, yres; gdouble *d; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < MAGIC_SIZE || memcmp(buffer, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "Gwyddion Simple Field"); goto fail; } p = buffer + MAGIC_SIZE; datap = memchr(p, '\0', size - (p - buffer)); if (!datap) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated.")); goto fail; } header = g_strdup(p); datap += 4 - ((datap - buffer) % 4); gwy_clear(&parser, 1); parser.key_value_separator = "="; if (!(hash = gwy_text_header_parse(header, &parser, NULL, NULL))) { g_propagate_error(error, err); goto fail; } xres = read_pixel_size(hash, "XRes", error); yres = read_pixel_size(hash, "YRes", error); if (!xres || !yres) goto fail; expected_size = (datap - buffer) + sizeof(gfloat)*xres*yres; if (err_SIZE_MISMATCH(error, expected_size, size, TRUE)) goto fail; xreal = read_real_size(hash, "XReal"); yreal = read_real_size(hash, "YReal"); dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); xoff = read_real_offset(hash, "XOffset"); yoff = read_real_offset(hash, "YOffset"); gwy_data_field_set_xoffset(dfield, xoff); gwy_data_field_set_yoffset(dfield, yoff); value = g_hash_table_lookup(hash, "XYUnits"); unit = gwy_si_unit_new(value); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); value = g_hash_table_lookup(hash, "ZUnits"); unit = gwy_si_unit_new(value); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); d = gwy_data_field_get_data(dfield); for (i = xres*yres; i; i--) *(d++) = gwy_get_gfloat_le(&datap); 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, "Title"))) { /* FIXME: Ensure valid UTF-8 */ gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(value)); } else gwy_app_channel_title_fall_back(container, 0); meta = gwy_container_new(); g_hash_table_foreach(hash, add_meta, meta); if (gwy_container_get_n_items(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_file_abandon_contents(buffer, size, NULL); if (header) g_free(header); if (hash) g_hash_table_destroy(hash); return container; }