Example #1
0
void
test_brick_compatibility_units(void)
{
    enum { N = 5 };
    static const GwyBrickCompatFlags incompat[N] = {
        0,
        GWY_BRICK_COMPAT_X,
        GWY_BRICK_COMPAT_Y,
        GWY_BRICK_COMPAT_Z,
        GWY_BRICK_COMPAT_VALUE,
    };
    GwyBrick *bricks[N];
    for (guint i = 0; i < N; i++)
        bricks[i] = gwy_brick_new();

    gwy_unit_set_from_string(gwy_brick_get_xunit(bricks[1]), "m", NULL);
    gwy_unit_set_from_string(gwy_brick_get_yunit(bricks[2]), "m", NULL);
    gwy_unit_set_from_string(gwy_brick_get_zunit(bricks[3]), "m", NULL);
    gwy_unit_set_from_string(gwy_brick_get_wunit(bricks[4]), "m", NULL);

    for (guint tocheck = 0; tocheck <= GWY_BRICK_COMPAT_ALL; tocheck++) {
        for (guint i = 0; i < N; i++) {
            for (guint j = 0; j < N; j++) {
                GwyBrickCompatFlags expected = ((i == j) ? 0
                                                : incompat[i] | incompat[j]);
                g_assert_cmpuint(gwy_brick_is_incompatible(bricks[i], bricks[j],
                                                           tocheck),
                                 ==, expected & tocheck);
            }
        }
    }

    for (guint i = 0; i < N; i++)
        g_object_unref(bricks[i]);
}
Example #2
0
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);
}
Example #3
0
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;
}