summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2019-07-16 14:29:29 +0200
committerPaweł Redman <pawel.redman@gmail.com>2019-07-16 14:29:29 +0200
commit84887c191149b8b4d5a9ea4f78286477fe0a82b2 (patch)
tree2fe6b0c4876dfc53761047f3a3571a048b3c02ad
parent7a61c9bf86178de625a8431160ee6b4a3f745f2c (diff)
Fundus image exporting
-rw-r--r--src/e2e.c32
-rw-r--r--src/e2e.h4
-rw-r--r--src/export.c48
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: