diff options
-rw-r--r-- | libcrystfel/src/image.c | 152 | ||||
-rw-r--r-- | libcrystfel/src/image.h | 15 | ||||
-rw-r--r-- | src/crystfel_gui.c | 2 | ||||
-rw-r--r-- | src/gui_index.c | 2 | ||||
-rw-r--r-- | src/im-sandbox.c | 6 | ||||
-rw-r--r-- | src/process_image.c | 16 | ||||
-rw-r--r-- | src/process_image.h | 2 | ||||
-rw-r--r-- | tests/wavelength_geom.c | 2 |
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); |