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 void oldmda_read_data(OldMDAFile *mdafile, const gchar *buffer) { GwyBrick *brick; GwyDataField *dfield; GwyDataLine *cal; gdouble *data; gint i, j, k; const guchar *p; p = buffer; brick = gwy_brick_new(mdafile->xres, mdafile->yres, mdafile->zres, mdafile->xreal, mdafile->yreal, mdafile->zres, TRUE); data = gwy_brick_get_data(brick); for (k = 0; k < mdafile->zres; k++) { p = buffer + k * 4; for (i = 0; i < mdafile->yres; i++) for (j = 0; j < mdafile->xres; j++) { *(data + k * mdafile->xres * mdafile->yres + j + (mdafile->yres - i - 1) * mdafile->xres) = (gdouble)gwy_get_gint32_le(&p); p += (mdafile->zres - 1) * 4; } } gwy_brick_set_si_unit_x(brick, mdafile->siunitx); gwy_brick_set_si_unit_y(brick, mdafile->siunity); gwy_brick_set_si_unit_z(brick, mdafile->siunitz); cal = gwy_data_line_new(mdafile->zres, mdafile->zres, FALSE); data = gwy_data_line_get_data(cal); for (k = 0; k < mdafile->zres; k++) { *(data++) = g_array_index(mdafile->xdata, gdouble, k); } gwy_data_line_set_si_unit_y(cal, mdafile->siunitz); gwy_brick_set_zcalibration(brick, cal); g_object_unref(cal); g_object_unref(mdafile->siunitx); g_object_unref(mdafile->siunity); g_object_unref(mdafile->siunitz); dfield = gwy_data_field_new(mdafile->xres, mdafile->yres, mdafile->xreal, mdafile->yreal, TRUE); gwy_container_set_object_by_name(mdafile->data, "/brick/0", brick); gwy_container_set_string_by_name(mdafile->data, "/brick/0/title", g_strdup("MDA data")); gwy_brick_mean_plane(brick, dfield, 0, 0, 0, mdafile->xres, mdafile->yres, -1, FALSE); gwy_container_set_object_by_name(mdafile->data, "/brick/0/preview", dfield); g_object_unref(dfield); g_object_unref(brick); gwy_file_volume_import_log_add(mdafile->data, 0, NULL, mdafile->filename); }
static LIFMemBlock* lif_read_memblock(const guchar *buffer, gsize *size, gint version) { LIFMemBlock *memblock; const guchar *p; int i; p = buffer; memblock = g_new0(LIFMemBlock, 1); memblock->magic = gwy_get_gint32_le(&p); gwy_debug("Magic = %d", memblock->magic); if (memcmp(&memblock->magic, MAGIC, MAGIC_SIZE) != 0) { gwy_debug("Wrong magic for memblock"); size = 0; g_free(memblock); return NULL; } memblock->size = gwy_get_guint32_le(&p); gwy_debug("Size = %d", memblock->size); memblock->testcode = *(p++); gwy_debug("Testcode = 0x%x", memblock->testcode); if (memblock->testcode != TESTCODE) { gwy_debug("Wrong testcode for memblock"); g_free(memblock); size = 0; return NULL; } if (version == 1) { memblock->memsize = gwy_get_guint32_le(&p); } else if (version >= 2) { memblock->memsize = gwy_get_guint64_le(&p); } gwy_debug("data length = %" G_GUINT64_FORMAT "", memblock->memsize); i = 0; while (*(p++) != TESTCODE) { i++; } gwy_debug("skipped %d bytes", i); memblock->desclen = gwy_get_guint32_le(&p); gwy_debug("description length = %d", memblock->desclen); memblock->memid = g_convert((const gchar*)p, 2 * memblock->desclen, "UTF-8", "UTF-16", NULL, NULL, NULL); gwy_debug("description = %s", memblock->memid); p += memblock->desclen * 2; memblock->data = (gpointer)p; *size = (gsize)(p - buffer) + memblock->memsize; return memblock; }
static GwyContainer* lif_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; LIFHeader *header = NULL; LIFMemBlock *memblock = NULL; LIFFile *file = NULL; LIFElement *element = NULL; LIFDimension *dimension = NULL; LIFChannel *channel = NULL; gsize size = 0, memblock_size = 0; gint64 remaining = 0; gchar *buffer; const guchar *p; GError *err = NULL; GwyDataField *dfield = NULL; GwyBrick *brick = NULL; gdouble *data = NULL; gint i, j, channelno = 0, volumeno = 0; gchar *strkey, *lutname; GMarkupParser parser = { header_start_element, header_end_element, header_parse_text, NULL, NULL }; GMarkupParseContext *context; XMLParserData *xmldata; gint x, xres, xstep, y, yres, ystep, z, zres, zstep, offset, res; gdouble xreal, yreal, zreal, xoffset, yoffset, zoffset; gdouble zscale = 1.0, wscale = 1.0; GwySIUnit *siunitxy = NULL, *siunitz = NULL; GwySIUnit *siunitx = NULL, *siunity = NULL, *siunitw = NULL; gint power10xy = 1; gint power10x = 1, power10y = 1, power10z = 1, power10w = 1; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); goto fail; } if (size < 13) { /* header too short */ err_TOO_SHORT(error); goto fail; } p = buffer; remaining = size; header = g_new0(LIFHeader, 1); header->magic = gwy_get_gint32_le(&p); gwy_debug("Magic = %d", header->magic); header->size = gwy_get_guint32_le(&p); gwy_debug("Size = %d", header->size); header->testcode = *(p++); gwy_debug("Testcode = 0x%x", header->testcode); if (header->testcode != TESTCODE) { err_FILE_TYPE(error, "Leica LIF"); goto fail; } header->xmllen = gwy_get_guint32_le(&p); gwy_debug("XML length = %d", header->xmllen); if (size < 13 + header->xmllen * 2) { err_TOO_SHORT(error); goto fail; } remaining -= 13; header->xmlheader = g_convert((const gchar*)p, 2 * header->xmllen, "UTF-8", "UTF-16", NULL, NULL, NULL); p += header->xmllen * 2; remaining -= header->xmllen * 2; // gwy_debug("%s", header->xmlheader); /* Parse XML header */ xmldata = g_new0(XMLParserData, 1); xmldata->file = g_new0(LIFFile, 1); xmldata->file->elements = g_array_new(FALSE, TRUE, sizeof(LIFElement)); xmldata->elements = g_ptr_array_new(); context = g_markup_parse_context_new(&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, (gpointer)xmldata, NULL); if (!g_markup_parse_context_parse(context, header->xmlheader, -1, &err) || !g_markup_parse_context_end_parse(context, &err)) { error = &err; g_clear_error(&err); } g_markup_parse_context_free(context); file = xmldata->file; file->header = header; g_ptr_array_free(xmldata->elements, TRUE); g_free(xmldata); /* Reading memblocks */ file->memblocks = g_hash_table_new(g_str_hash, g_str_equal); while (remaining > 0) { memblock = lif_read_memblock(p, &memblock_size, file->version); if (!memblock) { break; } remaining -= memblock_size; if (remaining >= 0) { gwy_debug("remaining = %" G_GUINT64_FORMAT "", remaining); p += memblock_size; g_hash_table_insert(file->memblocks, memblock->memid, memblock); } } container = gwy_container_new(); for (i = 0; i < file->elements->len; i++) { element = &g_array_index(file->elements, LIFElement, i); if ((element->dimensions == NULL) || (element->channels == NULL)) { gwy_debug("Empty element"); continue; } gwy_debug("Dimensions = %d channels=%d", element->dimensions->len, element->channels->len); gwy_debug("memid=%s", element->memid); /* check if we can load this type of data into * Gwyddion structures */ res = 0; if ((element->dimensions->len != 2) && (element->dimensions->len != 3)) { /* check for case ndim == 4 && res == 1 */ for (i = 0; i < element->dimensions->len; i++) { dimension = &g_array_index(element->dimensions, LIFDimension, i); xres = dimension->res; gwy_debug("dim[%d].res=%d", i, xres); if (i == 2) { res = xres; } } if ((element->dimensions->len == 4) && (res == 1)) { gwy_debug("4D volume"); } else { gwy_debug("not loading"); continue; } } memblock = (LIFMemBlock *)g_hash_table_lookup(file->memblocks, element->memid); if (!memblock) { gwy_debug("Failed to locate memblock with key %s", element->memid); continue; } p = memblock->data; if (element->dimensions->len == 2) { /* Image */ for (j = 0; j < element->channels->len; j++) { dimension = &g_array_index(element->dimensions, LIFDimension, 0); xres = dimension->res; xreal = dimension->length; xoffset = dimension->origin; xstep = dimension->bytesinc; siunitxy = gwy_si_unit_new_parse(dimension->unit, &power10xy); dimension = &g_array_index(element->dimensions, LIFDimension, 1); yres = dimension->res; yreal = dimension->length; yoffset = dimension->origin; ystep = dimension->bytesinc; if (xreal <= 0.0) xreal = 1.0; if (yreal <= 0.0) yreal = 1.0; channel = &g_array_index(element->channels, LIFChannel, j); offset = channel->bytesinc; siunitz = gwy_si_unit_new_parse(channel->unit, &power10z); zscale = pow10(power10z); if (offset + (xres - 1) * xstep + (yres - 1)* ystep > memblock->memsize) { gwy_debug("Memblock too small"); gwy_debug("%d %" G_GUINT64_FORMAT "", offset + (xres-1)*xstep + (yres-1)*ystep, memblock->memsize); err_SIZE_MISMATCH(error, memblock->memsize, offset+(xres-1)*xstep +(yres-1)*ystep, FALSE); goto fail; } dfield = gwy_data_field_new(xres, yres, xreal*pow10(power10xy), yreal*pow10(power10xy), TRUE); gwy_data_field_set_xoffset(dfield, xoffset*pow10(power10xy)); gwy_data_field_set_yoffset(dfield, yoffset*pow10(power10xy)); data = gwy_data_field_get_data(dfield); for (y = 0; y < yres; y++) for (x = 0; x < xres; x++) { *(data++) = zscale * (gdouble)*(p + offset + x*xstep + y*ystep); } if (siunitxy) { gwy_data_field_set_si_unit_xy(dfield, siunitxy); g_object_unref(siunitxy); } if (siunitz) { gwy_data_field_set_si_unit_z(dfield, siunitz); g_object_unref(siunitz); } strkey = g_strdup_printf("/%d/data", channelno); gwy_container_set_object_by_name(container, strkey, dfield); g_object_unref(dfield); g_free(strkey); if (element->name) { strkey = g_strdup_printf("/%d/data/title", channelno); gwy_container_set_string_by_name(container, strkey, g_strdup(element->name)); g_free(strkey); } if (element->metadata) { strkey = g_strdup_printf("/%d/meta", channelno); gwy_container_set_object_by_name(container, strkey, element->metadata); g_free(strkey); } if (channel->lut) { lutname = NULL; if (gwy_strequal(channel->lut, "Red")) lutname = g_strdup_printf("RGB-Red"); else if (gwy_strequal(channel->lut, "Green")) lutname = g_strdup_printf("RGB-Green"); else if (gwy_strequal(channel->lut, "Blue")) lutname = g_strdup_printf("RGB-Blue"); else if (gwy_strequal(channel->lut, "Gray")) lutname = g_strdup_printf("Gray"); if (lutname) { strkey = g_strdup_printf("/%u/base/palette", channelno); gwy_container_set_string_by_name(container, strkey, lutname); g_free(strkey); } } gwy_file_channel_import_log_add(container, channelno, NULL, filename); channelno++; } } else if ((element->dimensions->len == 3) || ((element->dimensions->len == 4) && (res == 1))) { /* Volume */ for (j = 0; j < element->channels->len; j++) { dimension = &g_array_index(element->dimensions, LIFDimension, 0); xres = dimension->res; xreal = dimension->length; xoffset = dimension->origin; xstep = dimension->bytesinc; siunitx = gwy_si_unit_new_parse(dimension->unit, &power10x); dimension = &g_array_index(element->dimensions, LIFDimension, 1); yres = dimension->res; yreal = dimension->length; yoffset = dimension->origin; ystep = dimension->bytesinc; siunity = gwy_si_unit_new_parse(dimension->unit, &power10y); if (element->dimensions->len == 3) { dimension = &g_array_index(element->dimensions, LIFDimension, 2); } else { dimension = &g_array_index(element->dimensions, LIFDimension, 3); } zres = dimension->res; zreal = dimension->length; zoffset = dimension->origin; zstep = dimension->bytesinc; siunitz = gwy_si_unit_new_parse(dimension->unit, &power10z); channel = &g_array_index(element->channels, LIFChannel, j); offset = channel->bytesinc; siunitw = gwy_si_unit_new_parse(channel->unit, &power10w); wscale = pow10(power10w); if (offset + (xres-1)*xstep + (yres-1)*ystep + (zres-1)*zstep > memblock->memsize) { gwy_debug("Memblock too small"); gwy_debug("%d %" G_GUINT64_FORMAT "", offset + (xres-1)*xstep + (yres-1)*ystep + (zres-1)*zstep, memblock->memsize); err_SIZE_MISMATCH(error, memblock->memsize, offset + (xres-1)*xstep + (yres-1)*ystep + (zres-1)*zstep, FALSE); goto fail; } brick = gwy_brick_new(xres, yres, zres, xreal*pow10(power10x), yreal*pow10(power10y), zreal*pow10(power10z), TRUE); gwy_brick_set_xoffset(brick, xoffset*pow10(power10x)); gwy_brick_set_yoffset(brick, yoffset*pow10(power10y)); gwy_brick_set_zoffset(brick, zoffset*pow10(power10z)); data = gwy_brick_get_data(brick); for (z = 0; z < zres; z++) for (y = 0; y < yres; y++) for (x = 0; x < xres; x++) { *(data++) = wscale * (gdouble)*(p + offset + x*xstep + y*ystep + z*zstep); } if (siunitx) { gwy_brick_set_si_unit_x(brick, siunitx); g_object_unref(siunitx); } if (siunity) { gwy_brick_set_si_unit_y(brick, siunity); g_object_unref(siunity); } if (siunitz) { gwy_brick_set_si_unit_z(brick, siunitz); g_object_unref(siunitz); } if (siunitw) { gwy_brick_set_si_unit_w(brick, siunitw); g_object_unref(siunitw); } strkey = g_strdup_printf("/brick/%d", volumeno); gwy_container_set_object_by_name(container, strkey, brick); g_free(strkey); if (element->name) { strkey = g_strdup_printf("/brick/%d/title", volumeno); gwy_container_set_string_by_name(container, strkey, g_strdup(element->name)); g_free(strkey); } if (element->metadata) { strkey = g_strdup_printf("/brick/%d/meta", volumeno); gwy_container_set_object_by_name(container, strkey, element->metadata); g_free(strkey); } if (channel->lut) { lutname = NULL; if (gwy_strequal(channel->lut, "Red")) lutname = g_strdup_printf("RGB-Red"); else if (gwy_strequal(channel->lut, "Green")) lutname = g_strdup_printf("RGB-Green"); else if (gwy_strequal(channel->lut, "Blue")) lutname = g_strdup_printf("RGB-Blue"); else if (gwy_strequal(channel->lut, "Gray")) lutname = g_strdup_printf("Gray"); if (lutname) { strkey = g_strdup_printf("/brick/%d/preview/palette", volumeno); gwy_container_set_string_by_name(container, strkey, lutname); g_free(strkey); } } dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_brick_mean_plane(brick, dfield, 0, 0, 0, xres, yres, -1, FALSE); strkey = g_strdup_printf("/brick/%d/preview", volumeno); gwy_container_set_object_by_name(container, strkey, dfield); g_free(strkey); g_object_unref(brick); g_object_unref(dfield); gwy_file_volume_import_log_add(container, volumeno, NULL, filename); volumeno++; } /* for (channels) */ } /* if (volume) */ } fail: /* freeing all stuff */ if (file) { if (file->memblocks) { g_hash_table_foreach_remove(file->memblocks, lif_remove_memblock, NULL); g_hash_table_unref(file->memblocks); } if (file->elements) { for (i = 0; i < file->elements->len; i++) { element = &g_array_index(file->elements, LIFElement, i); if (element->dimensions) { for (j = 0; j < element->dimensions->len; j++) { dimension = &g_array_index(element->dimensions, LIFDimension, j); if (dimension->unit) g_free(dimension->unit); } g_array_free(element->dimensions, TRUE); } if (element->channels) { for (j = 0; j < element->channels->len; j++) { channel = &g_array_index(element->channels, LIFChannel, j); if (channel->unit) g_free(channel->unit); if (channel->lut) g_free(channel->lut); } g_array_free(element->channels, TRUE); } if (element->name) g_free(element->name); if (element->memid) g_free(element->memid); if (element->metadata) g_object_unref(element->metadata); } g_array_free(file->elements, TRUE); } g_free(file); } if (header->xmlheader) g_free(header->xmlheader); if (header) { g_free(header); } return container; }
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 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 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 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; }