aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src/image.c')
-rw-r--r--libcrystfel/src/image.c153
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;
}