From eaf9e6250654e65daabbe98b6b4d5b5f8cd6924f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Aug 2022 14:20:16 +0200 Subject: Restructure image data array creation This adds a central procedure (image_create_dp_bad_sat) to create all the arrays. Then it's up to the loading procedure to put the values into the arrays. This also makes the loading procedures responsible for marking NaN/inf pixels in the bad pixel map. This avoids an additional sweep through the image data, and makes it possible to skip the NaN/inf check altogether if the image data comes, as it often does, in format which can't represent NaN/inf anyway. Finally, it removes quite a lot of duplicated code. --- libcrystfel/src/image.c | 144 ++++++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 67 deletions(-) (limited to 'libcrystfel/src/image.c') diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 5d67ae2d..3593f52b 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -716,54 +716,75 @@ int image_set_zero_data(struct image *image, { int pi; - image->dp = malloc(dtempl->n_panels*sizeof(float *)); - if ( image->dp == NULL ) return 1; - for ( pi=0; pin_panels; pi++ ) { - struct panel_template *p; - int p_w, p_h; - + long int i; p = &dtempl->panels[pi]; - p_w = p->orig_max_fs - p->orig_min_fs + 1; - p_h = p->orig_max_ss - p->orig_min_ss + 1; - - image->dp[pi] = calloc(p_w*p_h, sizeof(float)); - if ( image->dp[pi] == NULL ) return 1; - + for ( i=0; idp[pi][i] = 0.0; + } } return 0; } -int image_set_zero_mask(struct image *image, - const DataTemplate *dtempl) +int image_create_dp_bad_sat(struct image *image, + const DataTemplate *dtempl) { - int pi; + int i; + + image->dp = malloc(dtempl->n_panels*sizeof(float *)); + if ( image->dp == NULL ) { + ERROR("Failed to allocate data array.\n"); + return 1; + } 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; + } + image->sat = malloc(dtempl->n_panels*sizeof(float *)); - if ( (image->bad == NULL) || (image->sat == NULL) ) return 1; + if ( image->sat == NULL ) { + ERROR("Failed to allocate saturation map\n"); + free(image->dp); + free(image->bad); + return 1; + } - for ( pi=0; pin_panels; pi++ ) { + /* Set all pointers to NULL for easier clean-up */ + for ( i=0; in_panels; i++ ) { + image->dp[i] = NULL; + image->bad[i] = NULL; + image->sat[i] = NULL; + } - struct panel_template *p; - int p_w, p_h; - long int i; + for ( i=0; in_panels; i++ ) { - p = &dtempl->panels[pi]; - p_w = p->orig_max_fs - p->orig_min_fs + 1; - p_h = p->orig_max_ss - p->orig_min_ss + 1; + size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]); - image->bad[pi] = calloc(p_w*p_h, sizeof(int)); - image->sat[pi] = calloc(p_w*p_h, sizeof(float)); - if ( image->bad[pi] == NULL ) return 1; - if ( image->sat[pi] == NULL ) return 1; + image->dp[i] = malloc(nel*sizeof(float)); + image->bad[i] = calloc(nel, sizeof(int)); + image->sat[i] = malloc(nel*sizeof(float)); - for ( i=0; isat[pi][i] = INFINITY; + if ( (image->dp[i] == NULL) + || (image->bad[i] == NULL) + || (image->sat[i] == NULL) ) { + ERROR("Failed to allocate panel data arrays\n"); + for ( i=0; in_panels; i++ ) { + free(image->dp[i]); + free(image->bad[i]); + free(image->sat[i]); + } + free(image->dp); + free(image->bad); + free(image->sat); + return 1; } + } return 0; @@ -882,16 +903,6 @@ static void mark_flagged_pixels_equal(float *dp, int *bad, } -static void mark_flagged_pixels_naninf(float *dp, int *bad, - long int n) -{ - long int i; - for ( i=0; iorig_max_ss - p->orig_min_ss + 1; n = p_w * p_h; - profile_start("nan-inf"); - mark_flagged_pixels_naninf(dp, bad, n); - profile_end("nan-inf"); - profile_start("flag-values"); for ( i=0; ibad = malloc(dtempl->n_panels * sizeof(int *)); - if ( image->bad == NULL ) { - ERROR("Failed to allocate bad pixel mask\n"); - return 1; - } + /* The bad pixel map array is already created (see image_create_dp_bad_sat), + * and a preliminary mask (with NaN/inf pixels marked) has already been + * created when the image data was loaded. */ for ( i=0; in_panels; i++ ) { @@ -1097,12 +1102,6 @@ static int create_badmap(struct image *image, p_w = p->orig_max_fs - p->orig_min_fs + 1; p_h = p->orig_max_ss - p->orig_min_ss + 1; - image->bad[i] = calloc(p_w*p_h, sizeof(int)); - if ( image->bad[i] == NULL ) { - ERROR("Failed to allocate bad pixel mask\n"); - return 1; - } - /* Panel marked as bad? */ if ( p->bad ) { profile_start("whole-panel"); @@ -1148,10 +1147,16 @@ static int create_badmap(struct image *image, mask_fn = p->masks[j].filename; } - load_mask(p, mask_fn, image->ev, image->bad[i], - p->masks[j].data_location, - p->masks[j].good_bits, - p->masks[j].bad_bits); + if ( load_mask(p, mask_fn, image->ev, image->bad[i], + p->masks[j].data_location, + p->masks[j].good_bits, + p->masks[j].bad_bits) ) + { + ERROR("Failed to load mask for %s\n", + p->name); + profile_end("load-masks"); + return 1; + } } profile_end("load-masks"); @@ -1226,9 +1231,7 @@ static int create_satmap(struct image *image, if ( is_hdf5_file(map_fn) ) { #ifdef HAVE_HDF5 - image->sat[i] = image_hdf5_read_satmap(p, map_fn, - image->ev, - p->satmap); + image_hdf5_read_satmap(p, map_fn, image->ev, p->satmap); #endif } else { @@ -1276,6 +1279,11 @@ struct image *image_create_for_simulation(const DataTemplate *dtempl) return NULL; } + if ( image_create_dp_bad_sat(image, dtempl) ) { + image_free(image); + return NULL; + } + if ( image_set_zero_data(image, dtempl) ) { image_free(image); return NULL; @@ -1311,6 +1319,8 @@ static int do_image_read(struct image *image, const DataTemplate *dtempl, int i; int r; + if ( image_create_dp_bad_sat(image, dtempl) ) return 1; + /* Load the image data */ if ( !no_image_data ) { int r; -- cgit v1.2.3