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 gboolean mif_read_header(const guchar *buffer, gsize size, MIFHeader *header, GError **error) { const guchar *p = buffer; if (size <= HEADER_SIZE) { err_TOO_SHORT(error); return FALSE; } if (memcmp(buffer, MAGIC, MAGIC_SIZE)) { err_FILE_TYPE(error, "MIF"); return FALSE; } gwy_clear(header, 1); get_CHARARRAY(header->magic, &p); header->software_version = gwy_get_guint16_be(&p); header->file_version = gwy_get_guint16_be(&p); gwy_debug("sw version: %u.%u, file version: %u.%u", header->software_version/0x100, header->software_version % 0x100, header->file_version/0x100, header->file_version % 0x100); /* Version 1.7 is the only actually implemented. Other can be added upon * request and, namely, provision of the files as each file version is * different. */ if (header->file_version != 0x107) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Loading of file version %u.%u is not implemented."), header->file_version/0x100, header->file_version % 0x100); return FALSE; } get_CHARARRAY(header->time, &p); get_CHARARRAY(header->comment, &p); header->nimages = gwy_get_guint16_le(&p); gwy_debug("n images: %u", header->nimages); header->info.offset = gwy_get_guint32_le(&p); header->info.size = gwy_get_guint32_le(&p); gwy_debug("info offset: %zu, info size: %zu", header->info.offset, header->info.size); get_CHARARRAY(header->unused, &p); if (header->info.offset < HEADER_SIZE || header->info.offset > size || header->info.size > size || header->info.offset + header->info.size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File information block is outside the file.")); return FALSE; } 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 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_axis_info(MIFAxisInfo *axis, const guchar **p, gsize size, guint file_version, GError **error) { gwy_clear(axis, 1); if (file_version >= 0x105) { if (size < AXIS_INFO_SIZE_1_1) return err_AXIS_INFO_TOO_SHORT(error); get_CHARARRAY(axis->units, p); gwy_debug_chars(axis, units); get_CHARARRAY(axis->units_str_1_1, p); gwy_debug_chars(axis, units_str_1_1); axis->show = *((*p)++); gwy_debug_bool(axis, show); } else if (file_version >= 0x104) { if (size < AXIS_INFO_SIZE_1_0) return err_AXIS_INFO_TOO_SHORT(error); get_CHARARRAY(axis->units, p); gwy_debug_chars(axis, units); get_CHARARRAY(axis->units_str_1_0, p); gwy_debug_chars(axis, units_str_1_0); axis->show = *((*p)++); gwy_debug_bool(axis, show); } else { g_return_val_if_reached(FALSE); } return TRUE; }
G_GNUC_UNUSED static gboolean mif_read_id(MIFUniqueID *id, const guchar **p, gsize size, GError **error) { gwy_clear(id, 1); if (size < ID_SIZE) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Unique id record is too short.")); return FALSE; } id->ms = gwy_get_guint32_le(p); id->ls = gwy_get_guint32_le(p); gwy_debug("id: %08x %08x", id->ms, id->ls); id->index = gwy_get_guint32_le(p); gwy_debug("index: %u", id->index); get_CHARARRAY(id->workstation, p); gwy_debug_chars(id, workstation); 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 GwyContainer* surffile_load(const gchar *filename) { SurfFile surffile; GObject *object = NULL; guchar *buffer = NULL; const guchar *p; gsize size = 0; gsize estsize; GError *err = NULL; gchar signature[12]; gdouble max, min; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { g_warning("Cannot read file %s", filename); g_clear_error(&err); return NULL; } p = buffer; get_CHARARRAY(signature, &p); if (strncmp(signature, "DIGITAL SURF", 12) != 0) { g_warning("File %s is not a Surf file", filename); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } if (size < 500) { g_warning("File %s is too short to be Surf file", filename); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } surffile.format = get_WORD_LE(&p); surffile.nobjects = get_WORD_LE(&p); surffile.version = get_WORD_LE(&p); surffile.type = get_WORD_LE(&p); get_CHARS0(surffile.object_name, &p, 30); get_CHARS0(surffile.operator_name, &p, 30); surffile.material_code = get_WORD_LE(&p); surffile.acquisition = get_WORD_LE(&p); surffile.range = get_WORD_LE(&p); surffile.special_points = get_WORD_LE(&p); surffile.absolute = get_WORD_LE(&p); /*reserved*/ p += 8; surffile.pointsize = get_WORD_LE(&p); surffile.zmin = get_DWORD(&p); surffile.zmax = get_DWORD(&p); surffile.xres = get_DWORD(&p); surffile.yres = get_DWORD(&p); surffile.nofpoints = get_DWORD(&p); //surffile.xres = 200; surffile.yres = 200; surffile.dx = get_FLOAT_LE(&p); surffile.dy = get_FLOAT_LE(&p); surffile.dz = get_FLOAT_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 = get_FLOAT_LE(&p); surffile.yunit_ratio = get_FLOAT_LE(&p); surffile.zunit_ratio = get_FLOAT_LE(&p); surffile.imprint = get_WORD_LE(&p); surffile.inversion = get_WORD_LE(&p); surffile.leveling = get_WORD_LE(&p); p += 12; surffile.seconds = get_WORD_LE(&p); surffile.minutes = get_WORD_LE(&p); surffile.hours = get_WORD_LE(&p); surffile.day = get_WORD_LE(&p); surffile.month = get_WORD_LE(&p); surffile.year = get_WORD_LE(&p); surffile.measurement_duration = get_WORD_LE(&p); surffile.comment_size = get_WORD_LE(&p); surffile.private_size = get_WORD_LE(&p); get_CHARARRAY(surffile.client_zone, &p); surffile.XOffset = get_FLOAT_LE(&p); surffile.YOffset = get_FLOAT_LE(&p); surffile.ZOffset = get_FLOAT_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); p = buffer + 512; estsize = 512 + surffile.pointsize*surffile.xres*surffile.yres/8; if (size < estsize) { g_warning("File %s is too short to contain Surf data %d %d", filename, (int)size, (int)estsize); gwy_file_abandon_contents(buffer, size, NULL); return NULL; } fill_data_fields(&surffile, p); gwy_file_abandon_contents(buffer, size, NULL); if (surffile.absolute == 0) { 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)); } if (surffile.inversion == 1) gwy_data_field_invert(surffile.dfield, FALSE, FALSE, TRUE); if (surffile.inversion == 2) gwy_data_field_invert(surffile.dfield, FALSE, TRUE, TRUE); if (surffile.inversion == 3) gwy_data_field_invert(surffile.dfield, TRUE, FALSE, TRUE); if (surffile.dfield) { object = gwy_container_new(); gwy_container_set_object_by_name(GWY_CONTAINER(object), "/0/data", G_OBJECT(surffile.dfield)); store_metadata(&surffile, GWY_CONTAINER(object)); } return (GwyContainer*)object; return NULL; }
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 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 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 gboolean mprofile_read_header(const guchar *buffer, gsize size, MProFile *mprofile, GError **error) { const guchar *p; guint i; p = buffer; if (size < HEADER_SIZE + 2) { err_TOO_SHORT(error); return FALSE; } get_CHARARRAY(mprofile->magic, &p); if (memcmp(mprofile->magic, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "MetroPro"); return FALSE; } mprofile->header_format = gwy_get_guint16_be(&p); if (mprofile->header_format != 1) { err_UNSUPPORTED(error, "FormatVersion"); return FALSE; } mprofile->header_size = gwy_get_guint32_be(&p); gwy_debug("header_format: %d, header_size: %d", mprofile->header_format, mprofile->header_size); if (mprofile->header_size < 570) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is too short.")); return FALSE; } if (mprofile->header_size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is larger than file.")); return FALSE; } mprofile->software_type = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->software_date, &p); gwy_debug("software_type: %d, software_date: %s", mprofile->software_type, mprofile->software_date); mprofile->version_major = gwy_get_guint16_be(&p); mprofile->version_minor = gwy_get_guint16_be(&p); mprofile->version_micro = gwy_get_guint16_be(&p); gwy_debug("version: %d.%d.%d", mprofile->version_major, mprofile->version_minor, mprofile->version_micro); mprofile->intens_xoff = gwy_get_guint16_be(&p); mprofile->intens_yoff = gwy_get_guint16_be(&p); mprofile->intens_xres = gwy_get_guint16_be(&p); mprofile->intens_yres = gwy_get_guint16_be(&p); gwy_debug("INTENS xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->intens_xres, mprofile->intens_yres, mprofile->intens_xoff, mprofile->intens_yoff); mprofile->nbuckets = gwy_get_guint16_be(&p); mprofile->intens_range = gwy_get_guint16_be(&p); mprofile->intens_nbytes = gwy_get_guint32_be(&p); gwy_debug("intens_nbytes: %d, expecting: %d", mprofile->intens_nbytes, 2*mprofile->intens_xres*mprofile->intens_yres*mprofile->nbuckets); mprofile->phase_xoff = gwy_get_guint16_be(&p); mprofile->phase_yoff = gwy_get_guint16_be(&p); mprofile->phase_xres = gwy_get_guint16_be(&p); mprofile->phase_yres = gwy_get_guint16_be(&p); gwy_debug("PHASE xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->phase_xres, mprofile->phase_yres, mprofile->phase_xoff, mprofile->phase_yoff); mprofile->phase_nbytes = gwy_get_guint32_be(&p); gwy_debug("phase_nbytes: %d, expecting: %d", mprofile->phase_nbytes, 4*mprofile->phase_xres*mprofile->phase_yres); mprofile->timestamp = gwy_get_guint32_be(&p); get_CHARARRAY0(mprofile->comment, &p); gwy_debug("comment: %s", mprofile->comment); mprofile->source = gwy_get_guint16_be(&p); mprofile->scale_factor = gwy_get_gfloat_be(&p); mprofile->wavelength_in = gwy_get_gfloat_be(&p); mprofile->numeric_aperture = gwy_get_gfloat_be(&p); mprofile->obliquity_factor = gwy_get_gfloat_be(&p); mprofile->magnification = gwy_get_gfloat_be(&p); mprofile->camera_res = gwy_get_gfloat_be(&p); mprofile->acquire_mode = gwy_get_guint16_be(&p); gwy_debug("acquire_mode: %d", mprofile->acquire_mode); mprofile->intens_avgs = gwy_get_guint16_be(&p); if (!mprofile->intens_avgs) mprofile->intens_avgs = 1; mprofile->pzt_cal = gwy_get_guint16_be(&p); mprofile->pzt_gain_tolerance = gwy_get_guint16_be(&p); mprofile->pzt_gain = gwy_get_guint16_be(&p); mprofile->part_thickness = gwy_get_gfloat_be(&p); mprofile->agc = gwy_get_guint16_be(&p); mprofile->target_range = gwy_get_gfloat_be(&p); p += 2; mprofile->min_mod = gwy_get_guint32_be(&p); mprofile->min_mod_pts = gwy_get_guint32_be(&p); mprofile->phase_res = gwy_get_guint16_be(&p); mprofile->min_area_size = gwy_get_guint32_be(&p); mprofile->discont_action = gwy_get_guint16_be(&p); mprofile->discont_filter = gwy_get_gfloat_be(&p); mprofile->connection_order = gwy_get_guint16_be(&p); mprofile->data_inverted = gwy_get_guint16_be(&p); mprofile->camera_width = gwy_get_guint16_be(&p); mprofile->camera_height = gwy_get_guint16_be(&p); mprofile->system_type = gwy_get_guint16_be(&p); mprofile->system_board = gwy_get_guint16_be(&p); mprofile->system_serial = gwy_get_guint16_be(&p); mprofile->instrument_id = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->objective_name, &p); get_CHARARRAY0(mprofile->part_num, &p); gwy_debug("part_num: %s", mprofile->part_num); mprofile->code_vtype = gwy_get_guint16_be(&p); mprofile->phase_avgs = gwy_get_guint16_be(&p); mprofile->subtract_sys_err = gwy_get_guint16_be(&p); p += 16; get_CHARARRAY0(mprofile->part_ser_num, &p); mprofile->refactive_index = gwy_get_gfloat_be(&p); mprofile->remove_tilt_bias = gwy_get_guint16_be(&p); mprofile->remove_fringes = gwy_get_guint16_be(&p); mprofile->max_area_size = gwy_get_guint32_be(&p); mprofile->setup_type = gwy_get_guint16_be(&p); p += 2; mprofile->pre_connect_filter = gwy_get_gfloat_be(&p); mprofile->wavelength2 = gwy_get_gfloat_be(&p); mprofile->wavelength_fold = gwy_get_guint16_be(&p); mprofile->wavelength1 = gwy_get_gfloat_be(&p); mprofile->wavelength3 = gwy_get_gfloat_be(&p); mprofile->wavelength4 = gwy_get_gfloat_be(&p); get_CHARARRAY0(mprofile->wavelength_select, &p); mprofile->fda_res = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->scan_description, &p); gwy_debug("scan_description: %s", mprofile->scan_description); mprofile->nfiducials = gwy_get_guint16_be(&p); for (i = 0; i < G_N_ELEMENTS(mprofile->fiducials); i++) mprofile->fiducials[i] = gwy_get_gfloat_be(&p); mprofile->pixel_width = gwy_get_gfloat_be(&p); mprofile->pixel_height = gwy_get_gfloat_be(&p); mprofile->exit_pupil_diam = gwy_get_gfloat_be(&p); mprofile->light_level_pct = gwy_get_gfloat_be(&p); mprofile->coords_state = gwy_get_guint32_be(&p); mprofile->xpos = gwy_get_gfloat_be(&p); mprofile->ypos = gwy_get_gfloat_be(&p); mprofile->zpos = gwy_get_gfloat_be(&p); mprofile->xrot = gwy_get_gfloat_be(&p); mprofile->yrot = gwy_get_gfloat_be(&p); mprofile->zrot = gwy_get_gfloat_be(&p); mprofile->coherence_mode = gwy_get_guint16_be(&p); mprofile->surface_filter = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->sys_err_file, &p); get_CHARARRAY0(mprofile->zoom_desc, &p); return TRUE; }
static 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... */ }
/* Reads @header and initializes @reader for the correct byte order. Returns * the number of bytes read, 0 on error. */ static guint igor_read_headers(IgorFile *igorfile, const guchar *buffer, gsize size, gboolean check_only, GError **error) { IgorBinHeader *header; gsize headers_size; guint version, chksum, i; gboolean lsb; const guchar *p = buffer; if (size < HEADER_SIZE1) { err_TOO_SHORT(error); return 0; } /* The lower byte of version is nonzero. Use it to detect endianess. */ version = gwy_get_guint16_le(&p); gwy_debug("raw version: 0x%04x", version); /* Keep the rejection code path fast by performing version sanity check * as the very first thing. */ if ((lsb = (version & 0xff))) { gwy_debug("little endian"); } else { gwy_debug("big endian"); version /= 0x100; } /* Check if version is known and the buffer size */ if (version == 1) headers_size = HEADER_SIZE1 + WAVE_SIZE2; else if (version == 2) headers_size = HEADER_SIZE2 + WAVE_SIZE2; else if (version == 3) headers_size = HEADER_SIZE3 + WAVE_SIZE2; else if (version == 5) headers_size = HEADER_SIZE5 + WAVE_SIZE5; else { err_FILE_TYPE(error, "IGOR Pro"); return 0; } gwy_debug("expected headers_size %lu", (gulong)headers_size); if (size < headers_size) { err_TOO_SHORT(error); return 0; } /* Check the checksum */ chksum = igor_checksum(buffer, headers_size, lsb); gwy_debug("checksum %u", chksum); if (chksum) { err_FILE_TYPE(error, "IGOR Pro"); return 0; } /* If only detection is required, we can stop now. */ if (check_only) return headers_size; /* If the checksum is correct the file is likely IGOR file and we can * start the expensive actions. */ gwy_clear(igorfile, 1); header = &igorfile->header; header->version = version; igorfile->headers_size = headers_size; gwy_debug("format version: %u", header->version); if (lsb) { igorfile->get_guint16 = gwy_get_guint16_le; igorfile->get_gint16 = gwy_get_gint16_le; igorfile->get_guint32 = gwy_get_guint32_le; igorfile->get_gint32 = gwy_get_gint32_le; igorfile->get_gfloat = gwy_get_gfloat_le; igorfile->get_gdouble = gwy_get_gdouble_le; } else { igorfile->get_guint16 = gwy_get_guint16_be; igorfile->get_gint16 = gwy_get_gint16_be; igorfile->get_guint32 = gwy_get_guint32_be; igorfile->get_gint32 = gwy_get_gint32_be; igorfile->get_gfloat = gwy_get_gfloat_be; igorfile->get_gdouble = gwy_get_gdouble_be; } /* Read the rest of the binary header */ if (header->version == 1) { igorfile->wave_header_size = 110; header->wfm_size = igorfile->get_guint32(&p); header->checksum = igorfile->get_guint16(&p); } else if (header->version == 2) { igorfile->wave_header_size = 110; header->wfm_size = igorfile->get_guint32(&p); header->note_size = igorfile->get_guint32(&p); header->pict_size = igorfile->get_guint32(&p); header->checksum = igorfile->get_guint16(&p); } else if (header->version == 3) { igorfile->wave_header_size = 110; header->wfm_size = igorfile->get_guint32(&p); header->note_size = igorfile->get_guint32(&p); header->formula_size = igorfile->get_guint32(&p); header->pict_size = igorfile->get_guint32(&p); header->checksum = igorfile->get_guint16(&p); } else if (header->version == 5) { igorfile->wave_header_size = 320; header->checksum = igorfile->get_guint16(&p); header->wfm_size = igorfile->get_guint32(&p); header->formula_size = igorfile->get_guint32(&p); gwy_debug("formula_size: %u", header->formula_size); header->note_size = igorfile->get_guint32(&p); gwy_debug("note_size: %u", header->note_size); header->data_e_units_size = igorfile->get_guint32(&p); gwy_debug("data_e_units_size: %u", header->data_e_units_size); for (i = 0; i < MAXDIMS; i++) { header->dim_e_units_size[i] = igorfile->get_guint32(&p); gwy_debug("dim_e_units_size[%u]: %u", i, header->dim_e_units_size[i]); } for (i = 0; i < MAXDIMS; i++) { header->dim_labels_size[i] = igorfile->get_guint32(&p); gwy_debug("dim_labels_size[%u]: %u", i, header->dim_labels_size[i]); } header->indices_size = igorfile->get_guint32(&p); header->options_size1 = igorfile->get_guint32(&p); header->options_size2 = igorfile->get_guint32(&p); } else { g_assert_not_reached(); } gwy_debug("wfm_size: %u", header->wfm_size); /* Read the wave header */ if (version == 5) { IgorWaveHeader5 *wave5 = &igorfile->wave5; wave5->next = igorfile->get_guint32(&p); wave5->creation_date = igorfile->get_guint32(&p); wave5->mod_date = igorfile->get_guint32(&p); wave5->npts = igorfile->get_guint32(&p); wave5->type = igorfile->get_guint16(&p); gwy_debug("type: %u, npts: %u", wave5->type, wave5->npts); wave5->lock = igorfile->get_guint16(&p); get_CHARARRAY(wave5->whpad1, &p); wave5->wh_version = igorfile->get_guint16(&p); get_CHARARRAY0(wave5->bname, &p); wave5->whpad2 = igorfile->get_guint32(&p); wave5->dfolder = igorfile->get_guint32(&p); for (i = 0; i < MAXDIMS; i++) { wave5->n_dim[i] = igorfile->get_guint32(&p); gwy_debug("n_dim[%u]: %u", i, wave5->n_dim[i]); } for (i = 0; i < MAXDIMS; i++) wave5->sfA[i] = igorfile->get_gdouble(&p); for (i = 0; i < MAXDIMS; i++) wave5->sfB[i] = igorfile->get_gdouble(&p); get_CHARARRAY0(wave5->data_units, &p); gwy_debug("data_units: <%s>", wave5->data_units); for (i = 0; i < MAXDIMS; i++) { get_CHARARRAY0(wave5->dim_units[i], &p); gwy_debug("dim_units[%u]: <%s>", i, wave5->dim_units[i]); } wave5->fs_valid = !!igorfile->get_guint16(&p); wave5->whpad3 = igorfile->get_guint16(&p); wave5->top_full_scale = igorfile->get_gdouble(&p); wave5->bot_full_scale = igorfile->get_gdouble(&p); } return headers_size; }