diff --git a/src/file.h b/src/file.h index 0bcc36e..6208d4c 100644 --- a/src/file.h +++ b/src/file.h @@ -20,6 +20,7 @@ struct ds_desc_t { int (*get_pixel_mask)(const struct ds_desc_t *, int *); int (*get_data_frame)(const struct ds_desc_t *, const int, void *); void (*free_desc)(struct ds_desc_t *); + int i2i[]; // array to hold a translation from the image number requested by XDS and the actual position in the HDF5 file }; struct nxs_ds_desc_t { diff --git a/src/plugin.c b/src/plugin.c index 8afa637..0f5c3e9 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -5,6 +5,7 @@ #include #include +#include #include "file.h" #include "filters.h" @@ -69,6 +70,17 @@ static hid_t file_id = 0; static struct ds_desc_t *data_desc = NULL; static int *mask_buffer = NULL; +// CV-20240605: potentially provide a mapping from frame number (as +// requested by caller) to actual 2D slice within 3D data +// array. +// +// This is defined by the environment variable +// DURIN_IMAGE2ORDINAL (see below). +int *image2ordinal = NULL; +int image2ordinal_debug = 0; +int image2ordinal_imin = 0; +int image2ordinal_imax = 0; + void fill_info_array(int info[1024]) { info[0] = DLS_CUSTOMER_ID; info[1] = VERSION_MAJOR; @@ -88,6 +100,92 @@ void fill_info_array(int info[1024]) { info[6] = atoi(cenv); } + cenv = getenv("DURIN_IMAGE2ORDINAL"); + if (cenv!=NULL&&(!image2ordinal)) { + + char *denv = getenv("DURIN_IMAGE2ORDINAL_DEBUG"); + if (denv!=NULL) { + image2ordinal_debug=1; + } + + // ,-,-,..,- + if (image2ordinal_debug) printf("DURIN_IMAGE2ORDINAL = \"%s\"\n",cenv); + + const char outer_delimiters[] = ","; + const char inner_delimiters[] = "-"; + + char *found; + + char *outer_saveptr; + char *inner_saveptr; + + int ordinal_start = 0; + int ordinal = 0; + int ntt = -1; + found = strtok_r(cenv,outer_delimiters, &outer_saveptr); + if (found!=NULL) { + int tt[1000][2]; + while(found) { + if (ordinal_start==0) { + ordinal_start = atoi(found); + ordinal = ordinal_start - 1; + } + else { + char* s = strtok_r(found, inner_delimiters, &inner_saveptr); + if (s!=NULL) { + int i1 = atoi(s); + s = strtok_r(NULL,inner_delimiters, &inner_saveptr); + if (s!=NULL) { + int i2 = atoi(s); + ntt++; + if (ntt<=1000) { + tt[ntt][0] = i1; + tt[ntt][1] = i2; + for(int i=i1; i<=i2; ++i) { + ordinal++; + if (ordinal==1) { + image2ordinal_imin=i; + image2ordinal_imax=i; + } + else { + if (iimage2ordinal_imax) image2ordinal_imax=i; + } + } + } + } + } + } + found = strtok_r(NULL,outer_delimiters,&outer_saveptr); + } + + if (ordinal_start>0) { + if (image2ordinal_debug) { + printf("ordinal_start, end = %d %d\n",ordinal_start, ordinal); + printf("imin, imax = %d %d\n",image2ordinal_imin,image2ordinal_imax); + } + + // allocate array to go from image number/id to ordinal: + image2ordinal = malloc((image2ordinal_imax-image2ordinal_imin+1) * sizeof(image2ordinal_imin)); + int ordinal = ordinal_start - 1; + for(int i=0; i<=ntt; i++) { + for(int j=tt[i][0];j<=tt[i][1];j++) { + ordinal++; + //printf(" %d -> %d\n",ordinal,j); + image2ordinal[j] = ordinal; + } + } + if (image2ordinal&&image2ordinal_debug) { + for(int i=image2ordinal_imin; i<=image2ordinal_imax; i++) { + if (image2ordinal[i]>0) { + printf(" %d -> %d\n",i,image2ordinal[i]); + } + } + } + } + } + } + } int convert_to_int_and_mask(void *in_buffer, int width, int setValue, int *out_buffer, @@ -279,9 +377,26 @@ void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array, } } - if (data_desc->get_data_frame(data_desc, (*frame_number) - 1, buffer) < 0) { + int ordinal = *frame_number; + if (image2ordinal) { + if (ordinal < image2ordinal_imin || ordinal>image2ordinal_imax) { + char message[64] = {0}; + sprintf(message, "Failed to map frame %d to ordinals since outside of range %d - %d", ordinal,image2ordinal_imin,image2ordinal_imax); + ERROR_JUMP(-2, done, message); + } + ordinal = image2ordinal[ordinal]; + if (ordinal!=*frame_number) { + if (image2ordinal_debug) printf("fetching data from ordinal %d for frame %d\n",ordinal,*frame_number); + } + } + + if (data_desc->get_data_frame(data_desc, ordinal - 1, buffer) < 0) { char message[64] = {0}; - sprintf(message, "Failed to retrieve data for frame %d", *frame_number); + if (image2ordinal) { + sprintf(message, "Failed to retrieve data for frame %d (ordinal %d)", *frame_number, ordinal); + } else { + sprintf(message, "Failed to retrieve data for frame %d", *frame_number); + } ERROR_JUMP(-2, done, message); } @@ -289,7 +404,11 @@ void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array, if (convert_to_int_and_mask(buffer, data_desc->data_width, info[6], data_array, frame_size_px, mask_buffer) < 0) { char message[64]; - sprintf(message, "Error converting data for frame %d", *frame_number); + if (image2ordinal) { + sprintf(message, "Error converting data for frame %d (ordinal %d)", *frame_number, ordinal); + } else { + sprintf(message, "Error converting data for frame %d", *frame_number); + } ERROR_JUMP(-2, done, message); } } else { @@ -314,6 +433,11 @@ void plugin_close(int *error_flag) { } file_id = 0; + if (image2ordinal) { + free(image2ordinal); + image2ordinal = NULL; + } + if (mask_buffer) { free(mask_buffer); mask_buffer = NULL;