static gboolean rhk_sm4_read_page_index_header(RHKPageIndexHeader *header, const RHKObject *obj, const guchar *buffer, gsize size, GError **error) { const guchar *p; if (obj->size < PAGE_INDEX_HEADER_SIZE) { err_OBJECT_TRUNCATED(error, RHK_OBJECT_PAGE_INDEX_HEADER); return FALSE; } p = buffer + obj->offset; header->page_count = gwy_get_guint32_le(&p); header->object_count = gwy_get_guint32_le(&p); gwy_debug("page_count: %u, object_count: %u", header->page_count, header->object_count); header->reserved1 = gwy_get_guint32_le(&p); header->reserved2 = gwy_get_guint32_le(&p); if (!(header->objects = rhk_sm4_read_objects(buffer, p, size, header->object_count, RHK_OBJECT_PAGE_INDEX_HEADER, error))) return FALSE; return TRUE; }
static gboolean rhk_sm4_read_page_index(RHKPageIndex *header, const RHKObject *obj, const guchar *buffer, gsize size, GError **error) { const guchar *p; if (obj->size < PAGE_INDEX_ARRAY_SIZE) { err_OBJECT_TRUNCATED(error, RHK_OBJECT_PAGE_INDEX_ARRAY); return FALSE; } p = buffer + obj->offset; memcpy(header->id, p, sizeof(header->id)); p += sizeof(header->id); header->data_type = gwy_get_guint32_le(&p); header->source = gwy_get_guint32_le(&p); header->object_count = gwy_get_guint32_le(&p); header->minor_version = gwy_get_guint32_le(&p); gwy_debug("data_type: %u, source: %u, object_count: %u, minorv: %u", header->data_type, header->source, header->object_count, header->minor_version); if (!(header->objects = rhk_sm4_read_objects(buffer, p, size, header->object_count, RHK_OBJECT_PAGE_INDEX_ARRAY, error))) return FALSE; return TRUE; }
static void mif_read_block(MIFBlock *block, G_GNUC_UNUSED const gchar *name, const guchar **p) { block->offset = gwy_get_guint32_le(p); block->size = gwy_get_guint32_le(p); if (block->size) { gwy_debug("%s offset: %zu (0x%zx), size: %zu (0x%zx)", name, block->offset, block->offset, block->size, block->size); } }
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 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 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 inline const guchar* read_t2_record(PicoHarpT2Record *rec, const guchar *p) { guint32 r = gwy_get_guint32_le(&p); rec->time = r & 0x0fffffffU; rec->channel = r >> 28; return p; }
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 inline const guchar* read_t3_record(PicoHarpT3Record *rec, const guchar *p) { guint32 r = gwy_get_guint32_le(&p); rec->nsync = r & 0x0000ffffU; r = r >> 16; rec->time = r & 0x000000fffU; rec->channel = r >> 12; return p; }
/* FIXME: Some of the objects read are of type 0 and size 0, but maybe * that's right and they allow empty object slots */ static RHKObject* rhk_sm4_read_objects(const guchar *buffer, const guchar *p, gsize size, guint count, RHKObjectType intype, GError **error) { RHKObject *objects, *obj; guint i; if ((p - buffer) + count*OBJECT_SIZE >= size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Object list in %s is truncated."), rhk_sm4_describe_object(intype)); return NULL; } objects = g_new(RHKObject, count); for (i = 0; i < count; i++) { obj = objects + i; obj->type = gwy_get_guint32_le(&p); obj->offset = gwy_get_guint32_le(&p); obj->size = gwy_get_guint32_le(&p); gwy_debug("object of type %u (%s) at %u, size %u", obj->type, rhk_sm4_describe_object(obj->type), obj->offset, obj->size); if ((gsize)obj->size + obj->offset > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Object of type %s is truncated."), rhk_sm4_describe_object(obj->type)); g_free(objects); return NULL; } } return objects; }
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 gint pni_detect(const GwyFileDetectInfo *fileinfo, gboolean only_name) { gint score = 0; guint32 xres, yres; if (only_name) return g_str_has_suffix(fileinfo->name_lowercase, EXTENSION) ? 20 : 0; if (fileinfo->buffer_len >= 0xa0 && (memcmp(fileinfo->head, MAGIC1, MAGIC_SIZE) == 0 || memcmp(fileinfo->head, MAGIC2, MAGIC_SIZE) == 0)) { const guchar *p = fileinfo->head + 0x90; xres = gwy_get_guint32_le(&p); yres = gwy_get_guint32_le(&p); gwy_debug("%u %u", xres, yres); if (fileinfo->file_size == DATA_START + 2*xres*yres) score = 95; } return score; }
static const guchar* read_lsm_imaging_header(PicoHarpImagingHeader *header, const guchar *p) { header->lsm.frame_trigger_index = gwy_get_guint32_le(&p); header->lsm.line_start_trigger_index = gwy_get_guint32_le(&p); header->lsm.line_stop_trigger_index = gwy_get_guint32_le(&p); header->lsm.bidirectional = !!gwy_get_guint32_le(&p); header->lsm.xres = gwy_get_guint32_le(&p); header->lsm.yres = gwy_get_guint32_le(&p); return p; }
/* XXX: Code identical to nxiifile.c */ static gboolean read_bmp_header(const guchar *p, guint *xres, guint *yres, guint *size) { guint x; if (p[0] != 'B' || p[1] != 'M') return FALSE; p += 2; if ((*size = gwy_get_guint32_le(&p)) < BMP_HEADER_SIZE) /* Size */ return FALSE; if ((x = gwy_get_guint32_le(&p)) != 0) /* Reserved */ return FALSE; if ((x = gwy_get_guint32_le(&p)) != 54) /* Offset */ return FALSE; if ((x = gwy_get_guint32_le(&p)) != 40) /* Header size */ return FALSE; if ((*xres = gwy_get_guint32_le(&p)) == 0) /* Width */ return FALSE; if ((*yres = gwy_get_guint32_le(&p)) == 0) /* Height */ return FALSE; if ((x = gwy_get_guint16_le(&p)) != 1) /* Bit planes */ return FALSE; if ((x = gwy_get_guint16_le(&p)) != 24) /* BPP */ return FALSE; if ((x = gwy_get_guint32_le(&p)) != 0) /* Compression */ return FALSE; if ((x = gwy_get_guint32_le(&p)) && x + BMP_HEADER_SIZE != *size) /* Compresed size, may be 0 */ return FALSE; if (3*(*xres)*(*yres) + BMP_HEADER_SIZE != *size) return FALSE; return TRUE; }
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 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 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 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 GwyDataField* read_data_field(const guchar *buffer, guint size, guchar version, gchar **title, gint *direction, GError **error) { enum { MIN_REMAINDER = 2620 }; /* information offsets in different versions, in r5+ relative to data * start, in order: * data offset, * pixel dimensions, * physical dimensions, * value multiplier, * unit string, * data type, (if zero, use channel title) * channel title (if zero, use data type) */ const guint offsets34[] = { 0x0104, 0x0196, 0x01a2, 0x01b2, 0x01c2, 0x0400, 0x0000 }; const guint offsets56[] = { 0x0104, 0x025c, 0x0268, 0x0288, 0x02a0, 0x0708, 0x0000 }; const guint offsets7[] = { 0x0104, 0x029c, 0x02a8, 0x02c8, 0x02e0, 0x0000, 0x0b90 }; gint xres, yres, doffset, i, power10, type; gdouble xreal, yreal, q, z0; GwyDataField *dfield; GwySIUnit *unitxy, *unitz; gdouble *data; const guint *offset; const guchar *p, *r, *last; /* get floats in single precision from r4 but double from r5+ */ gdouble (*getflt)(const guchar**); *title = NULL; *direction = -1; if (version == '5' || version == '6' || version == '7') { /* There are more headers in r5, * try to find something that looks like #R5. */ last = r = buffer; while ((p = memchr(r, '#', size - (r - buffer) - MIN_REMAINDER))) { if (p[1] == 'R' && p[2] == version && p[3] == '.') { gwy_debug("pos: %ld", (long)(p - buffer)); last = p; r = p + MIN_REMAINDER-1; } else r = p + 1; } offset = (version == '7') ? &offsets7[0] : &offsets56[0]; buffer = last; getflt = &gwy_get_gdouble_le; } else { offset = &offsets34[0]; getflt = &get_gfloat_le_as_double; } p = buffer + *(offset++); doffset = gwy_get_guint32_le(&p); /* this appears to be the same number as in the ASCII miniheader -- so get it here since it's easier */ gwy_debug("data offset = %u", doffset); p = buffer + *(offset++); xres = gwy_get_guint32_le(&p); yres = gwy_get_guint32_le(&p); if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres)) return NULL; p = buffer + *(offset++); xreal = -getflt(&p); xreal += getflt(&p); yreal = -getflt(&p); yreal += getflt(&p); 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; } p = buffer + *(offset++); q = getflt(&p); z0 = getflt(&p); gwy_debug("xreal.raw = %g, yreal.raw = %g, q.raw = %g, z0.raw = %g", xreal, yreal, q, z0); p = buffer + *(offset++); unitz = gwy_si_unit_new_parse(p, &power10); q *= pow10(power10); z0 *= pow10(power10); unitxy = gwy_si_unit_new_parse(p + 10, &power10); xreal *= pow10(power10); yreal *= pow10(power10); gwy_debug("xres = %d, yres = %d, xreal = %g, yreal = %g, q = %g, z0 = %g", xres, yres, xreal, yreal, q, z0); gwy_debug("unitxy = %s, unitz = %s", p, p + 10); if (offset[1]) { /* We know channel title */ offset++; p = buffer + *(offset++); *title = g_strndup(p, size - (p - buffer)); gwy_debug("title = <%s>", *title); } else { /* We know data type */ p = buffer + *(offset++); type = gwy_get_guint16_le(&p); *direction = gwy_get_guint16_le(&p); gwy_debug("type = %d, dir = %d", type, *direction); offset++; *title = type_to_title(type); } p = buffer + doffset; if (err_SIZE_MISMATCH(error, 2*xres*yres, size - (p - buffer), FALSE)) return NULL; dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); gwy_data_field_set_si_unit_xy(dfield, unitxy); g_object_unref(unitxy); gwy_data_field_set_si_unit_z(dfield, unitz); g_object_unref(unitz); data = gwy_data_field_get_data(dfield); for (i = 0; i < xres*yres; i++) data[i] = (p[2*i] + 256.0*p[2*i + 1])*q + z0; return dfield; }
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 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 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* mif_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; MIFFile mfile; GwyDataField *dfield; guint i; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (!mif_read_header(buffer, size, &mfile.header, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* TODO: Check file version */ if (!mif_read_image_items(mfile.images, buffer, size, &mfile.header.info, error)) { gwy_file_abandon_contents(buffer, size, NULL); return NULL; } /* FIXME: Only v1.7! */ for (i = 0; i < mfile.header.nimages; i++) { MIFInfoItem *item = mfile.images + i; MIFImageHeader image_header; MIFBlock raster, macro_geometry, preview, image, curve, calc; guint ncalculations; const guchar *p = buffer + item->image.offset; GQuark quark; if (!item->image.size) continue; if (item->image.offset > size || item->image.size > size || item->image.offset + item->image.size > size) { continue; } /* XXX: We cannot use item->image.size because it's bogus, i.e. * too short. Apparently there is some unaccounted-for space until * the next block starts, 120 bytes for v1.7 files, after the image * header which is in fact still occupied by the image header. * MIFBlock says 714 bytes but the true size is 834 = 714 + 120. */ if (!mif_read_image_header(&image_header, &p, size - (p - buffer), mfile.header.file_version, error)) continue; if (p - buffer + 52 > size) continue; mif_read_block(&raster, "raster", &p); mif_read_block(¯o_geometry, "macro_geometry", &p); mif_read_block(&preview, "preview", &p); mif_read_block(&image, "image", &p); mif_read_block(&curve, "curve", &p); ncalculations = gwy_get_guint32_le(&p); mif_read_block(&calc, "calc", &p); gwy_debug("image header true size: %zu", (gsize)(p - (buffer + item->image.offset))); dfield = mif_read_data_field(&image_header, &image, buffer, size, NULL); if (!dfield) continue; if (!container) container = gwy_container_new(); quark = gwy_app_get_data_key_for_id(i); gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); gwy_app_channel_title_fall_back(container, i); } if (!container) err_NO_DATA(error); gwy_file_abandon_contents(buffer, size, NULL); return container; }
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 GwyContainer* rhk_sm4_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { RHKFile rhkfile; RHKObject *obj, o; GwyContainer *meta, *container = NULL; guchar *buffer = NULL; gsize size = 0; GError *err = NULL; const guchar *p; GString *key = NULL; guint i, imageid = 0, graphid = 0; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } gwy_clear(&rhkfile, 1); if (size < HEADER_SIZE) { err_TOO_SHORT(error); goto fail; } /* File header */ p = buffer + MAGIC_OFFSET + MAGIC_TOTAL_SIZE; rhkfile.page_count = gwy_get_guint32_le(&p); rhkfile.object_count = gwy_get_guint32_le(&p); rhkfile.object_field_size = gwy_get_guint32_le(&p); gwy_debug("page_count: %u, object_count: %u, object_field_size: %u", rhkfile.page_count, rhkfile.object_count, rhkfile.object_field_size); if (rhkfile.object_field_size != OBJECT_SIZE) g_warning("Object field size %u differs from %u", rhkfile.object_field_size, OBJECT_SIZE); rhkfile.reserved1 = gwy_get_guint32_le(&p); rhkfile.reserved2 = gwy_get_guint32_le(&p); /* Header objects */ if (!(rhkfile.objects = rhk_sm4_read_objects(buffer, p, size, rhkfile.object_count, RHK_OBJECT_FILE_HEADER, error))) goto fail; /* Find page index header */ if (!(obj = rhk_sm4_find_object(rhkfile.objects, rhkfile.object_count, RHK_OBJECT_PAGE_INDEX_HEADER, RHK_OBJECT_FILE_HEADER, error)) || !rhk_sm4_read_page_index_header(&rhkfile.page_index_header, obj, buffer, size, error)) goto fail; /* There, find the page index array. That's a single object in the object * list but it contains a page_count-long sequence of page indices. */ rhkfile.page_indices = g_new0(RHKPageIndex, rhkfile.page_index_header.page_count); if (!(obj = rhk_sm4_find_object(rhkfile.page_index_header.objects, rhkfile.page_index_header.object_count, RHK_OBJECT_PAGE_INDEX_ARRAY, RHK_OBJECT_PAGE_INDEX_HEADER, error))) goto fail; o = *obj; for (i = 0; i < rhkfile.page_index_header.page_count; i++) { if (!rhk_sm4_read_page_index(rhkfile.page_indices + i, &o, buffer, size, error)) goto fail; /* Carefully move to the next page index */ o.offset += o.size + OBJECT_SIZE*rhkfile.page_indices[i].object_count; } container = gwy_container_new(); key = g_string_new(NULL); /* Read pages */ for (i = 0; i < rhkfile.page_index_header.page_count; i++) { RHKPageIndex *pi = rhkfile.page_indices + i; RHKPage *page = &pi->page; /* Page must contain header */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_HEADER, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_header(page, obj, buffer, size, error)) goto fail; /* Page must contain data */ if (!(obj = rhk_sm4_find_object(pi->objects, pi->object_count, RHK_OBJECT_PAGE_DATA, RHK_OBJECT_PAGE_INDEX, error)) || !rhk_sm4_read_page_data(page, obj, buffer, error)) goto fail; /* Page may contain strings */ if (!(obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_STRING_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) || !rhk_sm4_read_string_data(page, obj, pi->page.string_count, buffer)) { g_warning("Failed to read string data in page %u", i); } /* Read the data */ if (pi->data_type == RHK_DATA_IMAGE) { GwyDataField *dfield = rhk_sm4_page_to_data_field(page); GQuark quark = gwy_app_get_data_key_for_id(imageid); const gchar *scandir, *name; gchar *title; gwy_container_set_object(container, quark, dfield); g_object_unref(dfield); if ((name = page->strings[RHK_STRING_LABEL])) { scandir = gwy_enum_to_string(page->scan_dir, scan_directions, G_N_ELEMENTS(scan_directions)); g_string_assign(key, g_quark_to_string(quark)); g_string_append(key, "/title"); if (scandir && *scandir) title = g_strdup_printf("%s [%s]", name, scandir); else title = g_strdup(name); gwy_container_set_string_by_name(container, key->str, title); } meta = rhk_sm4_get_metadata(pi, page); g_string_printf(key, "/%u/meta", imageid); gwy_container_set_object_by_name(container, key->str, meta); g_object_unref(meta); imageid++; } else if (pi->data_type == RHK_DATA_LINE) { GwyGraphModel *gmodel; RHKSpecDriftHeader drift_header; RHKSpecInfo spec_info; G_GNUC_UNUSED gboolean have_header = FALSE, have_info = FALSE; gwy_debug("page_type %u", page->page_type); gwy_debug("line_type %u", page->line_type); gwy_debug("page_sizes %u %u", page->x_size, page->y_size); /* Page may contain drift header */ if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_HEADER, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_drift_header(&drift_header, obj, buffer)) { gwy_debug("drift_header OK"); have_header = TRUE; } if ((obj = rhk_sm4_find_object(page->objects, page->object_count, RHK_OBJECT_SPEC_DRIFT_DATA, RHK_OBJECT_PAGE_HEADER, NULL)) && rhk_sm4_read_spec_info(&spec_info, obj, buffer)) { gwy_debug("spec_info OK"); have_info = TRUE; } /* FIXME: RHK_STRING_PLL_PRO_STATUS may contain interesting * metadata. But we have not place where to put it. */ if ((gmodel = rhk_sm4_page_to_graph_model(page))) { graphid++; gwy_container_set_object(container, gwy_app_get_graph_key_for_id(graphid), gmodel); g_object_unref(gmodel); } } } if (!imageid && !graphid) err_NO_DATA(error); fail: gwy_file_abandon_contents(buffer, size, NULL); rhk_sm4_free(&rhkfile); if (!imageid && !graphid) { gwy_object_unref(container); } if (key) g_string_free(key, TRUE); return container; }
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 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; }