From 84887c191149b8b4d5a9ea4f78286477fe0a82b2 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Tue, 16 Jul 2019 14:29:29 +0200 Subject: Fundus image exporting --- src/e2e.c | 32 ++++++++++++++++++++++++++++---- src/e2e.h | 4 ++++ src/export.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/e2e.c b/src/e2e.c index 5ac9f6c..d842fd8 100644 --- a/src/e2e.c +++ b/src/e2e.c @@ -86,6 +86,12 @@ static int make_pointer(const struct e2e_data *data, const char *pos, static int read_fundus(struct e2e_data *data, const char *cursor, struct e2e_image *image) { + if (cursor + image->width * image->height > data->end) { + errorf("Fundus image at %td ends past the end of file.\n", + cursor - data->start); + return 1; + } + // This cast is _technically_ illegal, but I can't think of a way in // which this would cause problems in practice. image->fundus = (const uint8_t*)cursor; @@ -96,6 +102,12 @@ static int read_fundus(struct e2e_data *data, const char *cursor, static int read_tomogram(struct e2e_data *data, const char *cursor, struct e2e_image *image) { + if (cursor + image->width * image->height * 2 > data->end) { + errorf("Tomogram image at %td ends past the end of file.\n", + cursor - data->start); + return 1; + } + image->tomogram = calloc(image->width * image->height, sizeof(float)); if (!image->tomogram) return ENOMEM; @@ -407,17 +419,29 @@ static int post_process(struct e2e_data *data) eli_for(dir, data->dirs, data_list) for (size_t i = 0; i < dir->num_entries; i++) { struct e2e_entry *entry = dir->entries + i; + struct e2e_series *series; struct e2e_slice *slice; rv = ensure_slice(data, entry->patient_id, entry->study_id, entry->series_id, entry->slice_id, - NULL, NULL, NULL, &slice); + NULL, NULL, &series, &slice); if (rv) return rv; - if (slice && entry->has_chunk - && entry->chunk.type == E2E_CHUNK_IMAGE) - slice->image = &entry->chunk.image; + if (entry->has_chunk && entry->chunk.type == E2E_CHUNK_IMAGE) { + struct e2e_image *image = &entry->chunk.image; + + if (slice && + entry->chunk.image.type == E2E_IMAGE_TOMOGRAM) + slice->image = image; + + if (series && + entry->chunk.image.type == E2E_IMAGE_FUNDUS) { + eli_append(&series->fundi, image, + series_fundi_list); + series->num_fundi++; + } + } } return 0; diff --git a/src/e2e.h b/src/e2e.h index 65428ea..7d3559e 100644 --- a/src/e2e.h +++ b/src/e2e.h @@ -15,6 +15,8 @@ struct e2e_image { const uint8_t *fundus; float *tomogram; }; + + eli_header series_fundi_list; }; #define E2E_CHUNK_IMAGE 0x40000000 @@ -69,6 +71,8 @@ struct e2e_series { int id; struct e2e_slice *slices; + size_t num_fundi; + struct e2e_image *fundi; UT_hash_handle hh; }; diff --git a/src/export.c b/src/export.c index 5a98f2d..9abd1ae 100644 --- a/src/export.c +++ b/src/export.c @@ -70,6 +70,34 @@ error_image3d: return ENOMEM; } +static int export_fundi(const struct e2e_series *series, matvar_t **fundi) +{ + size_t i, dims; + struct e2e_image *image; + + dims = series->num_fundi; + *fundi = Mat_VarCreate(NULL, MAT_C_CELL, MAT_T_CELL, 1, &dims, NULL, 0); + if (!*fundi) + return ENOMEM; + + i = 0; + eli_for(image, series->fundi, series_fundi_list) { + matvar_t *var; + size_t dims[2] = {image->width, image->height}; + + var = Mat_VarCreate(NULL, MAT_C_UINT8, MAT_T_UINT8, 2, dims, + (void*)image->fundus, 0); + if (!var) { + Mat_VarFree(*fundi); + return ENOMEM; + } + + Mat_VarSetCell(*fundi, i++, var); + } + + return 0; +} + static int export_series(const struct e2e_series *series, matvar_t **out) { int rv; @@ -89,7 +117,7 @@ static int export_series(const struct e2e_series *series, matvar_t **out) "tomogram_slice_ids", "fundi", }; - matvar_t *st, *id, *tomogram, *slice_ids; + matvar_t *st, *id, *tomogram = NULL, *slice_ids = NULL, *fundi; st = create_struct(fields, COUNT(fields)); if (!st) { @@ -103,22 +131,26 @@ static int export_series(const struct e2e_series *series, matvar_t **out) goto error_id; } - Mat_VarSetStructFieldByName(st, "series_id", 0, id); if (HASH_COUNT(series1->slices)) { rv = export_tomogram(series1->slices, &tomogram, &slice_ids); if (rv) goto error_tomogram; - - Mat_VarSetStructFieldByName(st, "tomogram", 0, tomogram); - Mat_VarSetStructFieldByName(st, "tomogram_slice_ids", 0, - slice_ids); } - // TODO: export fundus images - + + rv = export_fundi(series1, &fundi); + if (rv) + goto error_fundi; + + Mat_VarSetStructFieldByName(st, "tomogram", 0, tomogram); + Mat_VarSetStructFieldByName(st, "tomogram_slice_ids", 0, + slice_ids); + Mat_VarSetStructFieldByName(st, "fundi", 0, fundi); Mat_VarSetCell(*out, i++, st); continue; + error_fundi: + Mat_VarFree(tomogram); error_tomogram: Mat_VarFree(id); error_id: -- cgit