aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcrystfel/src/image.c152
-rw-r--r--libcrystfel/src/image.h15
-rw-r--r--src/crystfel_gui.c2
-rw-r--r--src/gui_index.c2
-rw-r--r--src/im-sandbox.c6
-rw-r--r--src/process_image.c16
-rw-r--r--src/process_image.h2
-rw-r--r--tests/wavelength_geom.c2
8 files changed, 146 insertions, 51 deletions
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c
index 234b63c7..95bc56e5 100644
--- a/libcrystfel/src/image.c
+++ b/libcrystfel/src/image.c
@@ -603,48 +603,115 @@ int image_set_zero_data(struct image *image,
}
+struct _image_data_arrays
+{
+ float **dp;
+ int **bad;
+ int np;
+};
+
+
+ImageDataArrays *image_data_arrays_new()
+{
+ ImageDataArrays *ida = malloc(sizeof(struct _image_data_arrays));
+ if ( ida == NULL ) return NULL;
+
+ ida->dp = NULL;
+ ida->bad = NULL;
+ ida->np = 0;
+
+ return ida;
+}
+
+
+void image_data_arrays_free(ImageDataArrays *ida)
+{
+ int i;
+
+ for ( i=0; i<ida->np; i++ ) {
+ if ( ida->dp != NULL ) free(ida->dp[i]);
+ if ( ida->bad != NULL ) free(ida->bad[i]);
+ }
+
+ free(ida->dp);
+ free(ida->bad);
+
+ free(ida);
+}
+
+
int image_create_dp_bad(struct image *image,
const DataTemplate *dtempl)
{
int i;
- image->dp = malloc(dtempl->n_panels*sizeof(float *));
- if ( image->dp == NULL ) {
- ERROR("Failed to allocate data array.\n");
- return 1;
- }
+ if ( (image->ida != NULL) && (image->ida->np > 0) ) {
- image->bad = malloc(dtempl->n_panels*sizeof(int *));
- if ( image->bad == NULL ) {
- ERROR("Failed to allocate bad pixel mask\n");
- free(image->dp);
- return 1;
- }
+ assert(dtempl->n_panels == image->ida->np);
- /* Set all pointers to NULL for easier clean-up */
- for ( i=0; i<dtempl->n_panels; i++ ) {
- image->dp[i] = NULL;
- image->bad[i] = NULL;
- }
+ /* (Re-)use the provided arrays */
+ image->dp = image->ida->dp;
+ image->bad = image->ida->bad;
- for ( i=0; i<dtempl->n_panels; i++ ) {
+ } else {
- size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]);
+ /* Allocate new arrays */
- image->dp[i] = malloc(nel*sizeof(float));
- image->bad[i] = calloc(nel, sizeof(int));
+ image->dp = malloc(dtempl->n_panels*sizeof(float *));
+ if ( image->dp == NULL ) {
+ ERROR("Failed to allocate data array.\n");
+ return 1;
+ }
- if ( (image->dp[i] == NULL) || (image->bad[i] == NULL) ) {
- ERROR("Failed to allocate panel data arrays\n");
- for ( i=0; i<dtempl->n_panels; i++ ) {
- free(image->dp[i]);
- free(image->bad[i]);
- }
+ image->bad = malloc(dtempl->n_panels*sizeof(int *));
+ if ( image->bad == NULL ) {
+ ERROR("Failed to allocate bad pixel mask\n");
free(image->dp);
- free(image->bad);
return 1;
}
+ /* Set all pointers to NULL for easier clean-up */
+ for ( i=0; i<dtempl->n_panels; i++ ) {
+ image->dp[i] = NULL;
+ image->bad[i] = NULL;
+ }
+
+ for ( i=0; i<dtempl->n_panels; i++ ) {
+
+ size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]);
+
+ image->dp[i] = malloc(nel*sizeof(float));
+ image->bad[i] = malloc(nel*sizeof(int));
+
+ if ( (image->dp[i] == NULL)|| (image->bad[i] == NULL) ) {
+ ERROR("Failed to allocate panel data arrays\n");
+ for ( i=0; i<dtempl->n_panels; i++ ) {
+ free(image->dp[i]);
+ free(image->bad[i]);
+ }
+ free(image->dp);
+ free(image->bad);
+ return 1;
+ }
+
+ }
+
+ if ( image->ida != NULL ) {
+ image->ida->dp = image->dp;
+ image->ida->bad = image->bad;
+ image->ida->np = dtempl->n_panels;
+ }
+
+ }
+
+ for ( i=0; i<dtempl->n_panels; i++ ) {
+
+ size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]);
+
+ profile_start("zero-mask");
+ memset(image->bad[i], 0, nel*sizeof(int));
+ profile_end("zero-mask");
+
}
return 0;
@@ -1237,7 +1304,8 @@ struct image *image_read(const DataTemplate *dtempl,
const char *filename,
const char *event,
int no_image_data,
- int no_mask_data)
+ int no_mask_data,
+ ImageDataArrays *ida)
{
struct image *image;
@@ -1262,6 +1330,7 @@ struct image *image_read(const DataTemplate *dtempl,
image->data_block_size = 0;
image->data_source_type = file_type(image->filename);
+ image->ida = ida;
if ( do_image_read(image, dtempl, no_image_data, no_mask_data) ) {
image_free(image);
@@ -1279,7 +1348,8 @@ struct image *image_read_data_block(const DataTemplate *dtempl,
DataSourceType type,
int serial,
int no_image_data,
- int no_mask_data)
+ int no_mask_data,
+ ImageDataArrays *ida)
{
struct image *image;
@@ -1294,6 +1364,7 @@ struct image *image_read_data_block(const DataTemplate *dtempl,
return NULL;
}
+ image->ida = ida;
image->filename = NULL;
image->ev = NULL;
image->data_block = data_block;
@@ -1332,21 +1403,25 @@ void image_free(struct image *image)
np = 0;
}
- for ( i=0; i<np; i++ ) {
- if ( image->dp != NULL ) free(image->dp[i]);
- if ( image->sat != NULL ) free(image->sat[i]);
- if ( image->bad != NULL ) free(image->bad[i]);
- }
+ if ( image->ida == NULL ) {
+
+ for ( i=0; i<np; i++ ) {
+ if ( image->dp != NULL ) free(image->dp[i]);
+ if ( image->sat != NULL ) free(image->sat[i]);
+ if ( image->bad != NULL ) free(image->bad[i]);
+ }
+
+ free(image->dp);
+ free(image->sat);
+ free(image->bad);
+
+ } /* else the arrays belong to the IDA structure */
for ( i=0; i<image->n_cached_headers; i++ ) {
free(image->header_cache[i]->header_name);
free(image->header_cache[i]);
}
- free(image->dp);
- free(image->sat);
- free(image->bad);
-
free(image);
}
@@ -1372,6 +1447,7 @@ struct image *image_new()
image->data_block_size = 0;
image->meta_data = NULL;
image->data_source_type = DATA_SOURCE_TYPE_UNKNOWN;
+ image->ida = NULL;
image->n_cached_headers = 0;
image->id = 0;
diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h
index 8930ffe7..eafc5f83 100644
--- a/libcrystfel/src/image.h
+++ b/libcrystfel/src/image.h
@@ -75,6 +75,8 @@ struct imagefeature {
/** An opaque type representing a list of image features */
typedef struct _imagefeaturelist ImageFeatureList;
+typedef struct _image_data_arrays ImageDataArrays;
+
#define HEADER_CACHE_SIZE (128)
@@ -179,6 +181,9 @@ struct image
/** List of peaks found in the image */
ImageFeatureList *features;
+ /** Re-usable data array structure, or NULL if not used */
+ ImageDataArrays *ida;
+
};
#ifdef __cplusplus
@@ -226,7 +231,8 @@ extern struct image *image_read(const DataTemplate *dtempl,
const char *filename,
const char *event,
int no_image_data,
- int no_mask_data);
+ int no_mask_data,
+ ImageDataArrays *ida);
extern struct image *image_create_for_simulation(const DataTemplate *dtempl);
extern struct image *image_read_data_block(const DataTemplate *dtempl,
@@ -236,7 +242,8 @@ extern struct image *image_read_data_block(const DataTemplate *dtempl,
DataSourceType type,
int serial,
int no_image_data,
- int no_mask_data);
+ int no_mask_data,
+ ImageDataArrays *ida);
extern void image_free(struct image *image);
extern int image_read_header_float(struct image *image, const char *from,
@@ -265,6 +272,10 @@ extern ImageFeatureList *image_read_peaks(const DataTemplate *dtempl,
extern char **image_expand_frames(const DataTemplate *dtempl,
const char *filename, int *nframes);
+extern ImageDataArrays *image_data_arrays_new(void);
+
+extern void image_data_arrays_free(ImageDataArrays *ida);
+
extern int image_create_dp_bad(struct image *image,
const DataTemplate *dtempl);
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c
index 41546bcd..d0fab3b1 100644
--- a/src/crystfel_gui.c
+++ b/src/crystfel_gui.c
@@ -215,7 +215,7 @@ void update_imageview(struct crystfelproject *proj)
image = image_read(proj->dtempl,
proj->filenames[proj->cur_frame],
proj->events[proj->cur_frame],
- 0, 0);
+ 0, 0, NULL);
} else {
STATUS("Image data file not present.\n");
image = NULL;
diff --git a/src/gui_index.c b/src/gui_index.c
index 660dac1c..d690737d 100644
--- a/src/gui_index.c
+++ b/src/gui_index.c
@@ -160,7 +160,7 @@ static int get_first_frame_parameters(struct crystfelproject *proj,
image = image_read(proj->dtempl,
proj->filenames[0],
proj->events[0],
- 0, 0);
+ 0, 0, NULL);
if ( image == NULL ) {
ERROR("Failed to load first frame\n");
diff --git a/src/im-sandbox.c b/src/im-sandbox.c
index 62b46187..1a6c9e88 100644
--- a/src/im-sandbox.c
+++ b/src/im-sandbox.c
@@ -342,6 +342,7 @@ static int run_work(const struct index_args *iargs, Stream *st,
struct im_zmq *zmqstuff = NULL;
struct im_asapo *asapostuff = NULL;
Mille *mille;
+ ImageDataArrays *ida;
if ( sb->profile ) {
profile_init();
@@ -372,6 +373,8 @@ static int run_work(const struct index_args *iargs, Stream *st,
mille = crystfel_mille_new(tmp);
}
+ ida = image_data_arrays_new();
+
while ( !allDone ) {
struct pattern_args pargs;
@@ -528,7 +531,7 @@ static int run_work(const struct index_args *iargs, Stream *st,
profile_start("process-image");
process_image(iargs, &pargs, st, cookie, tmpdir, ser,
sb->shared, sb->shared->last_task[cookie],
- asapostuff, mille);
+ asapostuff, mille, ida);
profile_end("process-image");
}
@@ -545,6 +548,7 @@ static int run_work(const struct index_args *iargs, Stream *st,
free(pargs.event);
}
+ image_data_arrays_free(ida);
crystfel_mille_free(mille);
/* These are both no-ops if argument is NULL */
diff --git a/src/process_image.c b/src/process_image.c
index 6212e361..57a994ac 100644
--- a/src/process_image.c
+++ b/src/process_image.c
@@ -108,7 +108,8 @@ static struct image *file_wait_open_read(const char *filename,
signed int wait_for_file,
int cookie,
int no_image_data,
- int no_mask_data)
+ int no_mask_data,
+ ImageDataArrays *ida)
{
signed int file_wait_time = wait_for_file;
int wait_message_done = 0;
@@ -154,7 +155,7 @@ static struct image *file_wait_open_read(const char *filename,
profile_start("image-read");
image = image_read(dtempl, filename, event,
- no_image_data, no_mask_data);
+ no_image_data, no_mask_data, ida);
profile_end("image-read");
if ( image == NULL ) {
if ( wait_for_file && !read_retry_done ) {
@@ -179,7 +180,7 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
Stream *st, int cookie, const char *tmpdir,
int serial, struct sb_shm *sb_shared,
char *last_task, struct im_asapo *asapostuff,
- Mille *mille)
+ Mille *mille, ImageDataArrays *ida)
{
struct image *image;
int i;
@@ -200,7 +201,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
iargs->data_format,
serial,
iargs->no_image_data,
- iargs->no_mask_data);
+ iargs->no_mask_data,
+ ida);
profile_end("read-zmq-data");
if ( image == NULL ) return;
@@ -222,7 +224,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
iargs->data_format,
serial,
iargs->no_image_data,
- iargs->no_mask_data);
+ iargs->no_mask_data,
+ ida);
profile_end("read-asapo-data");
if ( image == NULL ) return;
@@ -240,7 +243,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
iargs->wait_for_file,
cookie,
iargs->no_image_data,
- iargs->no_mask_data);
+ iargs->no_mask_data,
+ ida);
profile_end("file-wait-open-read");
if ( image == NULL ) {
if ( iargs->wait_for_file != 0 ) {
diff --git a/src/process_image.h b/src/process_image.h
index 50abbaa8..f5e27631 100644
--- a/src/process_image.h
+++ b/src/process_image.h
@@ -119,7 +119,7 @@ extern void process_image(const struct index_args *iargs,
int cookie, const char *tmpdir, int serial,
struct sb_shm *sb_shared, char *last_task,
struct im_asapo *asapostuff,
- Mille *mille);
+ Mille *mille, ImageDataArrays *ida);
#endif /* PROCESS_IMAGE_H */
diff --git a/tests/wavelength_geom.c b/tests/wavelength_geom.c
index 8bf86a74..6c45c491 100644
--- a/tests/wavelength_geom.c
+++ b/tests/wavelength_geom.c
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
return 1;
}
- image = image_read(dtempl, image_filename, NULL, 0, 0);
+ image = image_read(dtempl, image_filename, NULL, 0, 0, NULL);
if ( image == NULL ) return 1;
printf("wavelength = %e\n", image->lambda);