diff options
Diffstat (limited to 'libcrystfel/src/image.c')
-rw-r--r-- | libcrystfel/src/image.c | 153 |
1 files changed, 103 insertions, 50 deletions
diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 1e2b7a3c..97112fa3 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -307,7 +307,7 @@ void image_cache_header_int(struct image *image, if ( ce != NULL ) { ce->header_name = strdup(header_name); ce->val_int = header_val; - ce->type = 'i'; + ce->type = HEADER_INT; image->header_cache[image->n_cached_headers++] = ce; } else { ERROR("Failed to add header cache entry.\n"); @@ -318,7 +318,7 @@ void image_cache_header_int(struct image *image, void image_cache_header_float(struct image *image, const char *header_name, - float header_val) + double header_val) { if ( image->n_cached_headers >= HEADER_CACHE_SIZE ) { ERROR("Too many headers to copy.\n"); @@ -330,7 +330,7 @@ void image_cache_header_float(struct image *image, if ( ce != NULL ) { ce->header_name = strdup(header_name); ce->val_float = header_val; - ce->type = 'f'; + ce->type = HEADER_FLOAT; image->header_cache[image->n_cached_headers++] = ce; } else { ERROR("Failed to add header cache entry.\n"); @@ -339,77 +339,130 @@ void image_cache_header_float(struct image *image, } -static double get_value(struct image *image, const char *from, - int *is_literal_number) +void image_cache_header_str(struct image *image, + const char *header_name, + const char *header_val) { - double val; - char *rval; - struct header_cache_entry *ce; - char type; + if ( image->n_cached_headers >= HEADER_CACHE_SIZE ) { + ERROR("Too many headers to copy.\n"); + } else { - if ( from == NULL ) return NAN; + struct header_cache_entry *ce; + ce = malloc(sizeof(struct header_cache_entry)); - val = strtod(from, &rval); - if ( (*rval == '\0') && (rval != from) ) { - if ( is_literal_number != NULL ) { - *is_literal_number = 1; + if ( ce != NULL ) { + ce->header_name = strdup(header_name); + ce->val_str = strdup(header_val); + ce->type = HEADER_STR; + image->header_cache[image->n_cached_headers++] = ce; + } else { + ERROR("Failed to add header cache entry.\n"); } - return val; } +} + + +static int read_header_to_cache(struct image *image, const char *from) +{ + switch ( image->data_source_type ) { + + case DST_HDF5: + return image_hdf5_read_header_to_cache(image, from); + + case DST_CBF: + case DST_CBFGZ: + return image_cbf_read_header_to_cache(image, from); + + case DST_MSGPACK: + return image_msgpack_read_header_to_cache(image, from); + + default: + ERROR("Unrecognised file type %i (read_header_to_cache)\n", + image->data_source_type); + return 1; + + } +} + + +static struct header_cache_entry *cached_header(struct image *image, const char *from) +{ + struct header_cache_entry *ce; if ( image == NULL ) { ERROR("Attempt to retrieve a header value without an image\n"); - return NAN; + return NULL; } ce = find_cache_entry(image, from); - if ( ce != NULL ) { - if ( ce->type == 'f' ) { - return ce->val_float; - } else if ( ce->type == 'i' ) { - return ce->val_int; - } else { - ERROR("Unrecognised header cache type '%c'\n", - ce->type); - return NAN; - } + if ( ce != NULL ) return ce; + /* Try to get the value from the file */ + if ( read_header_to_cache(image, from) == 0 ) { + return find_cache_entry(image, from); } else { + ERROR("Couldn't find header value '%s'\n", from); + return NULL; + } +} - switch ( image->data_source_type ) { - case DST_HDF5: - val = image_hdf5_get_value(from, image->filename, - image->ev, &type); - break; +int image_read_header_float(struct image *image, const char *from, double *val) +{ + struct header_cache_entry *ce; - case DST_CBF: - case DST_CBFGZ: - /* FIXME: Implementation */ - val = NAN; - break; + ce = cached_header(image, from); + if ( ce == NULL ) return 1; - case DST_MSGPACK: - val = image_msgpack_get_value(from, image->data_block, - image->data_block_size, - &type); - break; + switch ( ce->type ) { - default: - ERROR("Unrecognised file type %i (get_value)\n", - image->data_source_type); - return 1; + case HEADER_FLOAT: + *val = ce->val_float; + return 0; + + case HEADER_INT: + *val = ce->val_int; + return 0; + case HEADER_STR: + if ( convert_float(ce->val_str, val) == 0 ) { + return 0; + } else { + ERROR("Value '%s' (%s) can't be converted to float\n", + ce->val_str, from); + return 1; } + default: + ERROR("Unrecognised header cache type %i\n", ce->type); + return 1; + } +} + +static double get_value(struct image *image, const char *from, + int *is_literal_number) +{ + double val; + char *rval; + + if ( from == NULL ) return NAN; + + val = strtod(from, &rval); + if ( (*rval == '\0') && (rval != from) ) { + if ( is_literal_number != NULL ) { + *is_literal_number = 1; + } + return val; } - if ( type == 'f' ) { - image_cache_header_float(image, from, val); - } else if ( type == 'i' ) { - image_cache_header_int(image, from, val); + if ( is_literal_number != NULL ) { + *is_literal_number = 0; + } + if ( image_read_header_float(image, from, &val) == 0 ) { + return val; + } else { + return NAN; /* FIXME: Use out-of-band flag */ } - return val; } |