diff options
| -rw-r--r-- | src/e2e.c | 32 | ||||
| -rw-r--r-- | src/e2e.h | 4 | ||||
| -rw-r--r-- | src/export.c | 48 | 
3 files changed, 72 insertions, 12 deletions
@@ -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; @@ -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:  | 
