16 Commits

Author SHA1 Message Date
CV-GPhL 0e258cc8c9 Null terminate buffer in file.c
Ensure the buffer is null terminated after allocation - otherwise correct results from strcmp below is undefined.
2026-02-04 14:52:02 +01:00
Graeme Winter bec44c8691 Do not depend on the strings being NULL terminated
Fixes #28

Instead make them NULL terminated by reading one longer into buffer
2023-08-09 12:47:45 +01:00
Graeme Winter 5d0b7bd104 New flag needed 2022-03-11 14:47:22 +00:00
Graeme Winter 300a980551 Use blocks for imports to prevent reorder; finish clang-format 2020-10-27 09:55:39 +00:00
Graeme Winter 4a6a75af70 clang-format err.* 2020-10-27 09:55:39 +00:00
Graeme Winter b36870935a clang-format file.* 2020-10-27 09:55:39 +00:00
Graeme Winter d73d6d70cb clang-format test.c 2020-10-27 09:55:39 +00:00
Graeme Winter 513bb10bf4 clang-format plugin 2020-10-27 09:55:39 +00:00
Graeme Winter 6ffef7d7c2 Typo; some comment formats 2020-10-27 09:55:39 +00:00
Graeme Winter e3cad6a7c3 Switch to c99 from c89 default - fixes #20
auggested by @jcbollinger
2020-10-26 15:58:25 +00:00
Graeme Winter 9b3236b084 First cut: use H5_USE_110_API (#19)
For #18 - compile against 1.10 API (may need to do more work to make sure this
does what we actually want)
2020-06-08 10:55:24 +01:00
Graeme Winter f25a73c667 Set to NULL after free; though fixes nothing 2020-04-02 14:21:52 +01:00
Tom Schoonjans 6165d14c31 Force linking against HDF5 shared library (#16) 2020-01-22 06:40:22 +00:00
Tom Schoonjans 19b16ad2a1 Fix sprintf usage (#15) 2020-01-21 10:52:49 +00:00
Graeme Winter 4e2b0c7506 Point at release 2019-05-08 09:28:59 +01:00
Charles Mita 34a38e15fd Update README.md 2019-01-29 19:58:27 +00:00
11 changed files with 1265 additions and 1255 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ BSLZ4_BUILD_DIR = ./bslz4/build
BSLZ4_INC_DIR = $(BSLZ4_SRC_DIR)
CC=h5cc
CFLAGS=-Wall -g -O2 -fpic -I$(INC_DIR) -I$(BSLZ4_INC_DIR) -std=c89
CFLAGS=-DH5_USE_110_API -Wall -g -O2 -fpic -I$(INC_DIR) -I$(BSLZ4_INC_DIR) -std=c99 -shlib
.PHONY: plugin
plugin: $(BUILD_DIR)/durin-plugin.so
@@ -42,7 +42,7 @@ $(BSLZ4_BUILD_DIR)/bitshuffle_core.o $(BSLZ4_BUILD_DIR)/iochain.o
$(BUILD_DIR)/durin-plugin.so: $(BUILD_DIR)/plugin.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \
$(BUILD_DIR)/bslz4.a
mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -shared $^ -o $(BUILD_DIR)/durin-plugin.so
$(CC) $(CFLAGS) -shared -noshlib $^ -o $(BUILD_DIR)/durin-plugin.so
$(BUILD_DIR)/example: $(BUILD_DIR)/test.o $(BUILD_DIR)/file.o $(BUILD_DIR)/err.o $(BUILD_DIR)/filters.o \
$(BUILD_DIR)/bslz4.a
+34 -11
View File
@@ -8,6 +8,9 @@ See:
* https://www.dectris.com/features/features-eiger-x/hdf5-and-nexus
* https://strucbio.biologie.uni-konstanz.de/xdswiki
## Get Durin
Latest release at https://github.com/DiamondLightSource/durin/releases/tag/2019v1
## Usage
In your XDS.INP add:
@@ -29,26 +32,47 @@ series of datasets named `data_000001`, `data_000002`, etc.
## Building
First ensure that the HDF5 libraries are compiled with:
### Building HDF5 library
The HDF5 library used when building durin must have been compiled with specific switches enabled
to allow the durin plugin to be built and used.
Download the HDF5 source code (https://www.hdfgroup.org/downloads/hdf5/source-code) and extract
to any directory (referred to as `/hdf5_dir`), and run the following commands.
```
cd /hdf5_dir
mkdir build
cd build
export CFLAGS=-fPIC
./configure --enable-threadsafe=yes --enable-unsupported
../configure --enable-threadsafe --enable-deprecated-symbols --enable-hl --enable-unsupported
make
make check
make install
```
The hdf5 tools and libraries should now be located in `/hdf5_dir/build/hdf5`
former is neeed to ensure that XDS in parallel mode will work, latter
to ensure that the chunk read (which for opaque reasons is defined to
be _high level_) works. Then make sure that wherever this was
installed, the h5cc is in PATH before:
For reference, the plugin requires the thread-safe switch and the optimised chunk read function.
The chunk read function may be defined in the high level library instead of the regular library,
depending on the exact HDF5 version downloaded (hence the --enable-deprecated-symbols _and_ --enable-hl).
The unsupported flag enables building with both threadsafe and high-level enabled.
### Building durin plugin
The plugin makefile will use the "h5cc" compiler wrapper, provided by the HDF5 library, which
must be on your PATH.
Download or clone the plugin source code (https://github.com/DiamondLightSource/durin)
into any directory (referred to as `/durin_dir`) and run the following commands.
```
cd durin
cd /durin_dir
PATH=/hdf5_dir/build/hdf5/bin:$PATH
make
```
The plugin is located at `/durin_dir/build/durin-plugin.so` and should be added to the
XDS.INP file as `LIB=/durin_dir/build/durin-plugin.so`
Plugin file is `build/durin-plugin.so` - this should be added to the
XDS.INP file i.e. as:
## Example XDS.INP
```
DETECTOR=PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD=4096
LIB=/opt/durin/build/durin-plugin.so
@@ -57,7 +81,6 @@ SENSOR_THICKNESS= 0.450
!SILICON= 3.953379
DIRECTION_OF_DETECTOR_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_DETECTOR_Y-AXIS= 0.00000 1.00000 0.00000
NX=2070 NY=2164 QX=0.0750 QY=0.0750
DETECTOR_DISTANCE= 194.633000
ORGX= 1041.30 ORGY= 1160.90
ROTATION_AXIS= 0.00000 -1.00000 -0.00000
@@ -74,4 +97,4 @@ JOB=XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
```
N.B. the master file is needed, not the .nxs one which follows the
standard.
standard.
+72 -73
View File
@@ -3,19 +3,18 @@
* Author: Charles Mita
*/
#include <stdio.h>
#include <hdf5.h>
#include <stdio.h>
#include "err.h"
struct error_stack_t {
char **files;
char **funcs;
int *lines;
int *errors;
char **messages;
int size;
char **files;
char **funcs;
int *lines;
int *errors;
char **messages;
int size;
};
static char files_buffer[ERR_MAX_FILENAME_LENGTH * ERR_MAX_STACK_SIZE] = {0};
@@ -30,89 +29,89 @@ static char *messages[ERR_MAX_STACK_SIZE] = {0};
static struct error_stack_t stack = {files, funcs, lines, errors, messages, 0};
void push_error_stack(const char *file, const char *func, int line, int err,
const char *message) {
if (stack.size >= ERR_MAX_STACK_SIZE)
return; /* unfortunate */
int idx = stack.size;
void push_error_stack(const char *file, const char *func, int line, int err, const char *message) {
if (stack.size >= ERR_MAX_STACK_SIZE) return; /* unfortunate */
int idx = stack.size;
/* subtract 1 to ensure room for null byte in buffer */
sprintf(stack.funcs[idx], "%.*s", ERR_MAX_FUNCNAME_LENGTH - 1, func);
sprintf(stack.files[idx], "%.*s", ERR_MAX_FILENAME_LENGTH - 1, file);
sprintf(stack.messages[idx], "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, message);
stack.lines[idx] = line;
stack.errors[idx] = err;
/* subtract 1 to ensure room for null byte in buffer */
sprintf(stack.funcs[idx], "%.*s", ERR_MAX_FUNCNAME_LENGTH - 1, func);
sprintf(stack.files[idx], "%.*s", ERR_MAX_FILENAME_LENGTH - 1, file);
sprintf(stack.messages[idx], "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, message);
stack.lines[idx] = line;
stack.errors[idx] = err;
stack.size++;
stack.size++;
}
herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err, void *client_data) {
herr_t retval = 0;
/* only read the message for the innermost stack frame - the rest are just noise */
if (n == 0) {
char message[ERR_MAX_MESSAGE_LENGTH] = {0};
sprintf(message, "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, err->desc);
push_error_stack(err->file_name, err->func_name, err->line, -1, message);
} else {
push_error_stack(err->file_name, err->func_name, err->line, -1, "");
}
return retval;
herr_t h5e_walk_callback(unsigned int n, const struct H5E_error2_t *err,
void *client_data) {
herr_t retval = 0;
/* only read the message for the innermost stack frame - the rest are just
* noise */
if (n == 0) {
char message[ERR_MAX_MESSAGE_LENGTH] = {0};
sprintf(message, "%.*s", ERR_MAX_MESSAGE_LENGTH - 1, err->desc);
push_error_stack(err->file_name, err->func_name, err->line, -1, message);
} else {
push_error_stack(err->file_name, err->func_name, err->line, -1, "");
}
return retval;
}
int h5e_error_callback(hid_t stack_id, void *client_data) {
int retval = 0;
herr_t err = 0;
err = H5Ewalk2(stack_id, H5E_WALK_UPWARD, &h5e_walk_callback, client_data);
if (err < 0) {
ERROR_JUMP(err, done, "Error walking HDF5 Error stack");
}
int retval = 0;
herr_t err = 0;
err = H5Ewalk2(stack_id, H5E_WALK_UPWARD, &h5e_walk_callback, client_data);
if (err < 0) {
ERROR_JUMP(err, done, "Error walking HDF5 Error stack");
}
done:
return retval;
return retval;
}
void reset_error_stack() {
stack.size = 0;
H5Eclear2(H5E_DEFAULT); /* almost certainly unnecessary */
stack.size = 0;
H5Eclear2(H5E_DEFAULT); /* almost certainly unnecessary */
}
void dump_error_stack(FILE *out) {
int idx = stack.size;
if (idx > 0) fprintf(out, "Durin plugin error:\n");
while (idx-- > 0) {
const char *file = stack.files[idx];
const char *func = stack.funcs[idx];
const char *message = stack.messages[idx];
const int line = stack.lines[idx];
if (message[0] != '\0') {
fprintf(out, "\t%s - line %d in %s:\n\t\t%s\n", file, line, func, message);
} else {
fprintf(out, "\t%s - line %d in %s\n", file, line, func);
}
}
int idx = stack.size;
if (idx > 0)
fprintf(out, "Durin plugin error:\n");
while (idx-- > 0) {
const char *file = stack.files[idx];
const char *func = stack.funcs[idx];
const char *message = stack.messages[idx];
const int line = stack.lines[idx];
if (message[0] != '\0') {
fprintf(out, "\t%s - line %d in %s:\n\t\t%s\n", file, line, func,
message);
} else {
fprintf(out, "\t%s - line %d in %s\n", file, line, func);
}
}
}
int init_h5_error_handling() {
int retval = 0;
hid_t err = 0;
if ((err = H5Eset_auto2(H5E_DEFAULT, &h5e_error_callback, NULL)) < 0) {
ERROR_JUMP(err, done, "Error configuring HDF5 error callback");
}
int retval = 0;
hid_t err = 0;
if ((err = H5Eset_auto2(H5E_DEFAULT, &h5e_error_callback, NULL)) < 0) {
ERROR_JUMP(err, done, "Error configuring HDF5 error callback");
}
done:
return retval;
return retval;
}
int init_error_handling() {
int retval = 0;
int idx = 0;
while (idx < ERR_MAX_STACK_SIZE) {
stack.files[idx] = files_buffer + (idx * ERR_MAX_FILENAME_LENGTH);
stack.funcs[idx] = funcs_buffer + (idx * ERR_MAX_FUNCNAME_LENGTH);
stack.messages[idx] = messages_buffer + (idx * ERR_MAX_MESSAGE_LENGTH);
idx++;
}
return retval;
int retval = 0;
int idx = 0;
while (idx < ERR_MAX_STACK_SIZE) {
stack.files[idx] = files_buffer + (idx * ERR_MAX_FILENAME_LENGTH);
stack.funcs[idx] = funcs_buffer + (idx * ERR_MAX_FUNCNAME_LENGTH);
stack.messages[idx] = messages_buffer + (idx * ERR_MAX_MESSAGE_LENGTH);
idx++;
}
return retval;
}
+17 -19
View File
@@ -3,46 +3,44 @@
* Author: Charles Mita
*/
#ifndef NXS_XDS_ERR_H
#define NXS_XDS_ERR_H
#define ERR_MAX_FILENAME_LENGTH 64
#define ERR_MAX_FUNCNAME_LENGTH 128
#define ERR_MAX_MESSAGE_LENGTH 1024
#define ERR_MAX_STACK_SIZE 128
/* obtain __func__ from GCC if no C99 */
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#if __GNUC__ >= 2
#define __func__ __FUNCTION__
#else
#define __func__ "<unknown>"
#endif
#endif
#if __GNUC__ >= 2
# define __line__ __LINE__
#define __line__ __LINE__
#else
# define __line__ 0
#define __line__ 0
#endif
#if __GNUC__ >= 2
# define __file__ __FILE__
#define __file__ __FILE__
#else
# define __file__ "unknown"
#define __file__ "unknown"
#endif
#define ERROR_JUMP(err, target, message) \
{ \
push_error_stack(__file__, __func__, __line__, err, message); \
retval = err; \
goto target; \
}
#define ERROR_JUMP(err, target, message) \
{ \
push_error_stack(__file__, __func__, __line__, err, message); \
retval = err; \
goto target; \
}
void push_error_stack(const char *file, const char *func, int line, int err, const char *message);
void push_error_stack(const char *file, const char *func, int line, int err,
const char *message);
void dump_error_stack(FILE *out);
+768 -757
View File
File diff suppressed because it is too large Load Diff
+20 -21
View File
@@ -3,48 +3,47 @@
* Author: Charles Mita
*/
#ifndef NXS_XDS_FILE_H
#define NXS_XDS_FILE_H
#include <hdf5.h>
#include "err.h"
#include "filters.h"
#include <hdf5.h>
struct ds_desc_t {
hid_t det_g_id;
hid_t data_g_id;
hsize_t dims[3];
int data_width;
int (*get_pixel_properties)(const struct ds_desc_t*, double*, double*);
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*);
hid_t det_g_id;
hid_t data_g_id;
hsize_t dims[3];
int data_width;
int (*get_pixel_properties)(const struct ds_desc_t *, double *, double *);
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 *);
};
struct nxs_ds_desc_t {
struct ds_desc_t base;
struct ds_desc_t base;
};
struct eiger_ds_desc_t {
struct ds_desc_t base;
int n_data_blocks;
int *block_sizes;
int (*frame_func)(const struct ds_desc_t*, const char*, const hsize_t*, const hsize_t*, void*);
struct ds_desc_t base;
int n_data_blocks;
int *block_sizes;
int (*frame_func)(const struct ds_desc_t *, const char *, const hsize_t *,
const hsize_t *, void *);
};
struct opt_eiger_ds_desc_t {
struct eiger_ds_desc_t base;
int bs_applied;
unsigned int bs_params[BS_H5_N_PARAMS];
struct eiger_ds_desc_t base;
int bs_applied;
unsigned int bs_params[BS_H5_N_PARAMS];
};
int get_detector_info(const hid_t fid, struct ds_desc_t **desc);
struct det_visit_objects_t {
hid_t nxdata;
hid_t nxdetector;
hid_t nxdata;
hid_t nxdetector;
};
#endif /* NXS_XDS_FILE_H */
+36 -36
View File
@@ -4,55 +4,55 @@
*/
#include <stdio.h>
#include "filters.h"
#include "err.h"
#include "bitshuffle.h"
#include "err.h"
#include "filters.h"
/* Required prototypes from bitshuffle.c but not included in header */
uint64_t bshuf_read_uint64_BE(const void *buffer);
uint32_t bshuf_read_uint32_BE(const void *buffer);
/*
* Derived from the h5 filter code from the bitshuffle project (not included here)
* Derived from the h5 filter code from the bitshuffle project (not included
* here)
*/
int bslz4_decompress(
const unsigned int* bs_params,
size_t in_size,
void *in_buffer,
size_t out_size,
void *out_buffer) {
int bslz4_decompress(const unsigned int *bs_params, size_t in_size,
void *in_buffer, size_t out_size, void *out_buffer) {
int retval = 0;
size_t size, elem_size, block_size, u_bytes;
int retval = 0;
size_t size, elem_size, block_size, u_bytes;
elem_size = bs_params[2];
u_bytes = bshuf_read_uint64_BE(in_buffer);
elem_size = bs_params[2];
u_bytes = bshuf_read_uint64_BE(in_buffer);
if (u_bytes != out_size) {
char message[64];
sprintf(message, "Decompressed chunk is %lu bytes, expected %lu", u_bytes, out_size);
ERROR_JUMP(-1, done, message);
}
if (u_bytes != out_size) {
char message[64];
sprintf(message, "Decompressed chunk is %lu bytes, expected %lu", u_bytes,
out_size);
ERROR_JUMP(-1, done, message);
}
block_size = bshuf_read_uint32_BE((const char *) in_buffer + 8) / elem_size;
if (!block_size) {
ERROR_JUMP(-1, done, "Read block bitshuffle lz4 block size as 0");
}
/* skip over header */
in_buffer += 12;
size = u_bytes / elem_size;
block_size = bshuf_read_uint32_BE((const char *)in_buffer + 8) / elem_size;
if (!block_size) {
ERROR_JUMP(-1, done, "Read block bitshuffle lz4 block size as 0");
}
/* skip over header */
in_buffer += 12;
size = u_bytes / elem_size;
if (bs_params[4] == BS_H5_PARAM_LZ4_COMPRESS) {
if (bshuf_decompress_lz4(in_buffer, out_buffer, size, elem_size, block_size) < 0) {
ERROR_JUMP(-1, done, "Error performing bitshuffle_lz4 decompression");
}
} else {
if (bshuf_bitunshuffle(in_buffer, out_buffer, size, elem_size, block_size) < 0) {
ERROR_JUMP(-1, done, "Error performing bit unshuffle");
}
}
if (bs_params[4] == BS_H5_PARAM_LZ4_COMPRESS) {
if (bshuf_decompress_lz4(in_buffer, out_buffer, size, elem_size,
block_size) < 0) {
ERROR_JUMP(-1, done, "Error performing bitshuffle_lz4 decompression");
}
} else {
if (bshuf_bitunshuffle(in_buffer, out_buffer, size, elem_size, block_size) <
0) {
ERROR_JUMP(-1, done, "Error performing bit unshuffle");
}
}
done:
return retval;
return retval;
}
+2 -8
View File
@@ -10,13 +10,7 @@
#define BS_H5_FILTER_ID 32008
#define BS_H5_PARAM_LZ4_COMPRESS 2
int bslz4_decompress(
const unsigned int* bs_params,
size_t in_size,
void *in_buffer,
size_t out_size,
void *out_buffer);
int bslz4_decompress(const unsigned int *bs_params, size_t in_size,
void *in_buffer, size_t out_size, void *out_buffer);
#endif /* NXS_XDS_FILTER_H */
+188 -193
View File
@@ -3,249 +3,244 @@
* Author: Charles Mita
*/
#include <hdf5.h>
#include <stdlib.h>
#include "file.h"
#include "filters.h"
#include "plugin.h"
/* XDS does not provide an error callback facility, so just write to stderr for now */
/* generally regarded as poor practice */
/* XDS does not provide an error callback facility, so just write to stderr
for now - generally regarded as poor practice */
#define ERROR_OUTPUT stderr
/* mask bits loosely based on what Neggia does and what NeXus says should be
done basically - anything in the low byte (& 0xFF) means "ignore this"
Neggia uses the value -2 if bit 1, 2 or 3 are set */
#define COPY_AND_MASK(in, out, size, mask) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
out[i] = in[i]; \
if (mask[i] & 0xFF) \
out[i] = -1; \
if (mask[i] & 30) \
out[i] = -2; \
} \
} else { \
for (i = 0; i < size; i++) { \
out[i] = in[i]; \
} \
} \
}
/* mask bits loosely based on what Neggia does and what NeXus says should be done */
/* basically - anything in the low byte (& 0xFF) means "ignore this" */
/* Neggia usses the value -2 if bit 1, 2 or 3 are set */
#define COPY_AND_MASK(in, out, size, mask) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
out[i] = in[i]; \
if (mask[i] & 0xFF) out[i] = -1; \
if (mask[i] & 30) out[i] = -2; \
} \
} else { \
for (i = 0; i < size; i++) { \
out[i] = in[i]; \
} \
} \
}
#define APPLY_MASK(buffer, mask, size) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
if (mask[i] & 0xFF) buffer[i] = -1; \
if (mask[i] & 30) buffer[i] = -2; \
} \
} \
}
#define APPLY_MASK(buffer, mask, size) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
if (mask[i] & 0xFF) \
buffer[i] = -1; \
if (mask[i] & 30) \
buffer[i] = -2; \
} \
} \
}
static hid_t file_id = 0;
static struct ds_desc_t *data_desc = NULL;
static int *mask_buffer = NULL;
void fill_info_array(int info[1024]) {
info[0] = DLS_CUSTOMER_ID;
info[1] = VERSION_MAJOR;
info[2] = VERSION_MINOR;
info[3] = VERSION_PATCH;
info[4] = VERSION_TIMESTAMP;
info[0] = DLS_CUSTOMER_ID;
info[1] = VERSION_MAJOR;
info[2] = VERSION_MINOR;
info[3] = VERSION_PATCH;
info[4] = VERSION_TIMESTAMP;
}
int convert_to_int_and_mask(void *in_buffer, int d_width, int *out_buffer, int length, int *mask) {
/* transfer data to output buffer, performing data conversion as required */
int retval = 0;
/* TODO: decide how conversion of data should work */
/* Should we sign extend? Neggia doesn't (casts from uint*), but may be more intuitive */
if (d_width == sizeof(signed char)) {
signed char *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(short)) {
short *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(int)) {
int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(long int)) {
long int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(long long int)) {
long long int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else {
char message[128];
sprintf(message, "Unsupported conversion of data width %d to %ld (int)", d_width, sizeof(int));
ERROR_JUMP(-1, done, message);
}
int convert_to_int_and_mask(void *in_buffer, int d_width, int *out_buffer,
int length, int *mask) {
/* transfer data to output buffer, performing data conversion as required */
int retval = 0;
/* TODO: decide how conversion of data should work */
/* Should we sign extend? Neggia doesn't (casts from uint*), but may be more
* intuitive */
if (d_width == sizeof(signed char)) {
signed char *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(short)) {
short *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(int)) {
int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(long int)) {
long int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else if (d_width == sizeof(long long int)) {
long long int *in = in_buffer;
COPY_AND_MASK(in, out_buffer, length, mask);
} else {
char message[128];
sprintf(message, "Unsupported conversion of data width %d to %ld (int)",
d_width, sizeof(int));
ERROR_JUMP(-1, done, message);
}
done:
return retval;
return retval;
}
#ifdef __cplusplus
extern "C" {
#endif
void plugin_open(
const char *filename,
int info[1024],
int *error_flag) {
int retval = 0;
*error_flag = 0;
void plugin_open(const char *filename, int info[1024], int *error_flag) {
int retval = 0;
*error_flag = 0;
init_error_handling();
init_error_handling();
if (H5dont_atexit() < 0) {
ERROR_JUMP(-2, done, "Failed configuring HDF5 library behaviour");
}
if (H5dont_atexit() < 0) {
ERROR_JUMP(-2, done, "Failed configuring HDF5 library behaviour");
}
if (init_h5_error_handling() < 0) {
ERROR_JUMP(-2, done, "Failed to configure HDF5 error handling");
}
if (init_h5_error_handling() < 0) {
ERROR_JUMP(-2, done, "Failed to configure HDF5 error handling");
}
fill_info_array(info);
file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if (file_id < 0) {
char message[128] = {0};
sprintf(message, "Could not open %.100s", filename);
ERROR_JUMP(-4, done, message);
}
fill_info_array(info);
file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if (file_id < 0) {
char message[128] = {0};
sprintf(message, "Could not open %.100s", filename);
ERROR_JUMP(-4, done, message);
}
reset_error_stack();
retval = get_detector_info(file_id, &data_desc);
if (retval < 0) {
ERROR_JUMP(-4, done, "");
}
reset_error_stack();
retval = get_detector_info(file_id, &data_desc);
if (retval < 0) {
ERROR_JUMP(-4, done, "");
}
mask_buffer = malloc(data_desc->dims[1] * data_desc->dims[2] * sizeof(int));
if (mask_buffer) {
retval = data_desc->get_pixel_mask(data_desc, mask_buffer);
if (retval < 0) {
fprintf(ERROR_OUTPUT, "WARNING: Could not read pixel mask - no masking will be applied\n");
dump_error_stack(ERROR_OUTPUT);
free(mask_buffer);
mask_buffer = NULL;
}
}
retval = 0;
mask_buffer = malloc(data_desc->dims[1] * data_desc->dims[2] * sizeof(int));
if (mask_buffer) {
retval = data_desc->get_pixel_mask(data_desc, mask_buffer);
if (retval < 0) {
fprintf(
ERROR_OUTPUT,
"WARNING: Could not read pixel mask - no masking will be applied\n");
dump_error_stack(ERROR_OUTPUT);
free(mask_buffer);
mask_buffer = NULL;
}
}
retval = 0;
done:
*error_flag = retval;
if (retval < 0) {
if ((data_desc) && (data_desc->free_desc)) {
data_desc->free_desc(data_desc);
data_desc = NULL;
}
dump_error_stack(ERROR_OUTPUT);
}
*error_flag = retval;
if (retval < 0) {
if ((data_desc) && (data_desc->free_desc)) {
data_desc->free_desc(data_desc);
data_desc = NULL;
}
dump_error_stack(ERROR_OUTPUT);
}
}
void plugin_get_header(int *nx, int *ny, int *nbytes, float *qx, float *qy,
int *number_of_frames, int info[1024], int *error_flag) {
int err = 0;
int retval = 0;
double x_pixel_size, y_pixel_size;
reset_error_stack();
fill_info_array(info);
void plugin_get_header(
int *nx, int *ny,
int *nbytes,
float *qx, float *qy,
int *number_of_frames,
int info[1024],
int *error_flag) {
int err = 0;
int retval = 0;
double x_pixel_size, y_pixel_size;
reset_error_stack();
fill_info_array(info);
err =
data_desc->get_pixel_properties(data_desc, &x_pixel_size, &y_pixel_size);
if (err < 0) {
ERROR_JUMP(err, done, "Failed to retrieve pixel information");
}
err = data_desc->get_pixel_properties(data_desc, &x_pixel_size, &y_pixel_size);
if (err < 0) {
ERROR_JUMP(err, done, "Failed to retrieve pixel information");
}
*nx = data_desc->dims[2];
*ny = data_desc->dims[1];
*nbytes = data_desc->data_width;
*number_of_frames = data_desc->dims[0];
*qx = (float) x_pixel_size;
*qy = (float) y_pixel_size;
*nx = data_desc->dims[2];
*ny = data_desc->dims[1];
*nbytes = data_desc->data_width;
*number_of_frames = data_desc->dims[0];
*qx = (float)x_pixel_size;
*qy = (float)y_pixel_size;
done:
*error_flag = retval;
if (retval < 0) {
dump_error_stack(ERROR_OUTPUT);
}
*error_flag = retval;
if (retval < 0) {
dump_error_stack(ERROR_OUTPUT);
}
}
void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array,
int info[1024], int *error_flag) {
void plugin_get_data(
int *frame_number,
int *nx, int *ny,
int *data_array,
int info[1024],
int *error_flag) {
int retval = 0;
int frame_size_px = data_desc->dims[1] * data_desc->dims[2];
reset_error_stack();
fill_info_array(info);
int retval = 0;
int frame_size_px = data_desc->dims[1] * data_desc->dims[2];
reset_error_stack();
fill_info_array(info);
void *buffer = NULL;
if (sizeof(*data_array) == data_desc->data_width) {
buffer = data_array;
} else {
buffer = malloc(data_desc->data_width * frame_size_px);
if (!buffer) {
ERROR_JUMP(-1, done, "Unable to allocate data buffer");
}
}
void *buffer = NULL;
if (sizeof(*data_array) == data_desc->data_width) {
buffer = data_array;
} else {
buffer = malloc(data_desc->data_width * frame_size_px);
if (!buffer) {
ERROR_JUMP(-1, done, "Unable to allocate data buffer");
}
}
if (data_desc->get_data_frame(data_desc, (*frame_number) - 1, buffer) < 0) {
char message[64] = {0};
sprintf(message, "Failed to retrieve data for frame %d", *frame_number);
ERROR_JUMP(-2, done, message);
}
if (data_desc->get_data_frame(data_desc, (*frame_number) - 1, buffer) < 0) {
char message[64] = {0};
sprintf(message, "Failed to retrieve data for frame %d", *frame_number);
ERROR_JUMP(-2, done, message);
}
if (buffer != data_array) {
if (convert_to_int_and_mask(buffer, data_desc->data_width, data_array, frame_size_px, mask_buffer) < 0) {
char message[64];
sprintf(message, "Error converting data for frame %d", *frame_number);
ERROR_JUMP(-2, done, message);
}
} else {
APPLY_MASK(data_array, mask_buffer, frame_size_px);
}
if (buffer != data_array) {
if (convert_to_int_and_mask(buffer, data_desc->data_width, data_array,
frame_size_px, mask_buffer) < 0) {
char message[64];
sprintf(message, "Error converting data for frame %d", *frame_number);
ERROR_JUMP(-2, done, message);
}
} else {
APPLY_MASK(data_array, mask_buffer, frame_size_px);
}
done:
*error_flag = retval;
if (retval < 0) {
dump_error_stack(ERROR_OUTPUT);
}
if (buffer && (buffer != data_array)) free(buffer);
*error_flag = retval;
if (retval < 0) {
dump_error_stack(ERROR_OUTPUT);
}
if (buffer && (buffer != data_array))
free(buffer);
}
void plugin_close(int *error_flag) {
if (file_id) {
if (H5Fclose(file_id) < 0) {
/* TODO: backtrace */
*error_flag = -1;
}
}
file_id = 0;
if (file_id) {
if (H5Fclose(file_id) < 0) {
/* TODO: backtrace */
*error_flag = -1;
}
}
file_id = 0;
if (mask_buffer) free(mask_buffer);
if (data_desc->free_desc) {
data_desc->free_desc(data_desc);
data_desc = NULL;
}
if (H5close() < 0) {
*error_flag = -1;
}
if (mask_buffer) {
free(mask_buffer);
mask_buffer = NULL;
}
if (data_desc->free_desc) {
data_desc->free_desc(data_desc);
data_desc = NULL;
}
if (H5close() < 0) {
*error_flag = -1;
}
}
#ifdef __cplusplus
+7 -23
View File
@@ -15,39 +15,23 @@
extern "C" {
#endif
#define DLS_CUSTOMER_ID 0x01 /* pretend we're Dectris, otherwise XDS doesn't work */
#define DLS_CUSTOMER_ID \
0x01 /* pretend we're Dectris, otherwise XDS doesn't work */
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_PATCH 0
#define VERSION_TIMESTAMP -1 /* good enough for Dectris apparantely */
void plugin_open(const char *filename, int info[1024], int *error_flag);
void plugin_open(
const char *filename,
int info[1024],
int *error_flag);
void plugin_get_header(
int *nx, int *ny,
int *nbytes,
float *qx, float *qy,
int *number_of_frames,
int info[1024],
int *error_flag);
void plugin_get_data(
int *frame_number,
int *nx, int *ny,
int *data_array,
int info[1024],
int *error_flag);
void plugin_get_header(int *nx, int *ny, int *nbytes, float *qx, float *qy,
int *number_of_frames, int info[1024], int *error_flag);
void plugin_get_data(int *frame_number, int *nx, int *ny, int *data_array,
int info[1024], int *error_flag);
void plugin_close(int *error_flag);
#ifdef __cplusplus
} /* extern "C" */
#endif
+119 -112
View File
@@ -1,134 +1,141 @@
#include "err.h"
#include "file.h"
#include <hdf5.h>
#include <stdio.h>
#include <stdlib.h>
#include <hdf5.h>
#include "file.h"
#include "err.h"
#define COPY_AND_MASK(in, out, size, mask) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
out[i] = in[i]; \
if (mask[i] & 0xFE) out[i] = -2; \
if (mask[i] & 0x01) out[i] = -1; \
} \
} else { \
for (i = 0; i < size; i++) { \
out[i] = in[i]; \
} \
} \
}
#define COPY_AND_MASK(in, out, size, mask) \
{ \
int i; \
if (mask) { \
for (i = 0; i < size; ++i) { \
out[i] = in[i]; \
if (mask[i] & 0xFE) \
out[i] = -2; \
if (mask[i] & 0x01) \
out[i] = -1; \
} \
} else { \
for (i = 0; i < size; i++) { \
out[i] = in[i]; \
} \
} \
}
int parse_args(int argc, char **argv, char **file_name, int *frame_idx) {
int retval = 0;
if (argc == 2) {
*frame_idx = 0;
*file_name = argv[1];
} else if (argc >= 2) {
*file_name = argv[1];
*frame_idx = atoi(argv[2]);
} else {
ERROR_JUMP(-1, done, "Require filename argument");
}
int retval = 0;
if (argc == 2) {
*frame_idx = 0;
*file_name = argv[1];
} else if (argc >= 2) {
*file_name = argv[1];
*frame_idx = atoi(argv[2]);
} else {
ERROR_JUMP(-1, done, "Require filename argument");
}
done:
return retval;
return retval;
}
int main(int argc, char **argv) {
int err = 0;
int retval = 0;
char *test_file = "";
struct ds_desc_t *desc;
int dims[3] = {0};
hid_t fid = 0;
int frame_idx = 0;
int *mask = NULL;
int *data = NULL;
void *buffer = NULL;
int err = 0;
int retval = 0;
char *test_file = "";
struct ds_desc_t *desc;
int dims[3] = {0};
hid_t fid = 0;
int frame_idx = 0;
int *mask = NULL;
int *data = NULL;
void *buffer = NULL;
init_error_handling();
if (init_h5_error_handling() < 0) {
ERROR_JUMP(-1, done, "");
}
init_error_handling();
if (init_h5_error_handling() < 0) {
ERROR_JUMP(-1, done, "");
}
if (parse_args(argc, argv, &test_file, &frame_idx) < 0) {
ERROR_JUMP(-1, done, "Failure parsing arguments");
}
if (parse_args(argc, argv, &test_file, &frame_idx) < 0) {
ERROR_JUMP(-1, done, "Failure parsing arguments");
}
fid = H5Fopen(test_file, H5F_ACC_RDONLY, H5P_DEFAULT);
if (fid < 0) ERROR_JUMP(-1, done, "Error opening file");
fid = H5Fopen(test_file, H5F_ACC_RDONLY, H5P_DEFAULT);
if (fid < 0)
ERROR_JUMP(-1, done, "Error opening file");
err = get_detector_info(fid, &desc);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
dims[0] = desc->dims[0];
dims[1] = desc->dims[1];
dims[2] = desc->dims[2];
err = get_detector_info(fid, &desc);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
dims[0] = desc->dims[0];
dims[1] = desc->dims[1];
dims[2] = desc->dims[2];
printf("Dims: %d, %d, %d\n", dims[0], dims[1], dims[2]);
printf("Dims: %d, %d, %d\n", dims[0], dims[1], dims[2]);
mask = malloc(dims[1] * dims[2] * sizeof(*mask));
if (!mask) {
ERROR_JUMP(err, done, "Failed to allocate space for pixel mask");
}
err = desc->get_pixel_mask(desc, mask);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
mask = malloc(dims[1] * dims[2] * sizeof(*mask));
if (!mask) {
ERROR_JUMP(err, done, "Failed to allocate space for pixel mask");
}
err = desc->get_pixel_mask(desc, mask);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
data = malloc(dims[1] * dims[2] * sizeof(*data));
if (sizeof(*data) != desc->data_width) {
buffer = malloc(dims[1] * dims[2] * desc->data_width);
} else {
buffer = data;
}
data = malloc(dims[1] * dims[2] * sizeof(*data));
if (sizeof(*data) != desc->data_width) {
buffer = malloc(dims[1] * dims[2] * desc->data_width);
} else {
buffer = data;
}
err = desc->get_data_frame(desc, frame_idx, buffer);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
err = desc->get_data_frame(desc, frame_idx, buffer);
if (err < 0) {
ERROR_JUMP(err, done, "");
}
if (buffer != data) {
if (desc->data_width == sizeof(signed char)) {
signed char *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(short)) {
short *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(int)) {
int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(long int)) {
long int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(long long int)) {
long long int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
}
}
if (buffer != data) {
if (desc->data_width == sizeof(signed char)) {
signed char *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(short)) {
short *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(int)) {
int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(long int)) {
long int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
} else if (desc->data_width == sizeof(long long int)) {
long long int *in = buffer;
COPY_AND_MASK(in, data, dims[1] * dims[2], mask);
}
}
{
int i, j;
int max_i = 30;
int max_j = 10;
max_j = max_j < dims[1] ? max_j : dims[1];
max_i = max_i < dims[2] ? max_i : dims[2];
for (j = 0; j < max_j; j++) {
for (i = 0; i < max_i; i++) {
printf("%3d ", data[i + j*dims[2]]);
}
printf("\n");
}
}
{
int i, j;
int max_i = 30;
int max_j = 10;
max_j = max_j < dims[1] ? max_j : dims[1];
max_i = max_i < dims[2] ? max_i : dims[2];
for (j = 0; j < max_j; j++) {
for (i = 0; i < max_i; i++) {
printf("%3d ", data[i + j * dims[2]]);
}
printf("\n");
}
}
done:
if (fid > 0) H5Fclose(fid);
if (data) free(data);
if (buffer && (data != buffer)) free(buffer);
if (mask) free(mask);
if (retval != 0) dump_error_stack(stderr);
return retval;
if (fid > 0)
H5Fclose(fid);
if (data)
free(data);
if (buffer && (data != buffer))
free(buffer);
if (mask)
free(mask);
if (retval != 0)
dump_error_stack(stderr);
return retval;
}