aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2010-01-21 15:36:44 +0100
committerThomas White <taw@physics.org>2010-01-21 15:36:44 +0100
commit552d860fa1bf4fd699d0af2e8ca0a13345fc624b (patch)
tree0185aa85891d64cd7c521dba06dc04d67c757ccf
parent395b2bd7770fb9a9f11be939c22d7abce702e4da (diff)
Fix hdfile layering violations
-rw-r--r--Makefile.am3
-rw-r--r--src/Makefile.am5
-rw-r--r--src/displaywindow.c22
-rw-r--r--src/displaywindow.h4
-rw-r--r--src/filters.c97
-rw-r--r--src/filters.h23
-rw-r--r--src/hdf5-file.c103
-rw-r--r--src/hdf5-file.h3
-rw-r--r--src/peaks.c74
-rw-r--r--src/peaks.h1
-rw-r--r--src/render.c96
-rw-r--r--src/render.h5
12 files changed, 235 insertions, 201 deletions
diff --git a/Makefile.am b/Makefile.am
index c4954775..148e9e8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,5 +2,6 @@ EXTRA_DIST = configure src/cell.h src/hdf5-file.h src/image.h src/relrod.h \
src/utils.h src/diffraction.h src/detector.h src/ewald.h \
src/sfac.h src/intensities.h src/reflections.h src/list_tmp.h \
src/statistics.h src/displaywindow.h src/render.h src/hdfsee.h \
- data/displaywindow.ui src/dirax.h src/peaks.h src/index.h
+ data/displaywindow.ui src/dirax.h src/peaks.h src/index.h \
+ src/filters.h
SUBDIRS = src data
diff --git a/src/Makefile.am b/src/Makefile.am
index 8dd6af85..57ee19c4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,11 +17,12 @@ process_hkl_SOURCES = process_hkl.c sfac.c statistics.c cell.c utils.c \
process_hkl_LDADD = @LIBS@
indexamajig_SOURCES = indexamajig.c hdf5-file.c utils.c dirax.c cell.c image.c \
- intensities.c ewald.c peaks.c index.c
+ intensities.c ewald.c peaks.c index.c filters.c
indexamajig_LDADD = @LIBS@
if HAVE_GTK
-hdfsee_SOURCES = hdfsee.c displaywindow.c render.c hdf5-file.c utils.c image.c
+hdfsee_SOURCES = hdfsee.c displaywindow.c render.c hdf5-file.c utils.c image.c \
+ filters.c
hdfsee_LDADD = @LIBS@
endif
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 06884d64..ba0ac922 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -74,8 +74,7 @@ static void displaywindow_update(DisplayWindow *dw)
gdk_pixbuf_unref(dw->pixbuf);
}
if ( dw->hdfile != NULL ) {
- dw->pixbuf = render_get_image(dw->hdfile, dw->binning,
- dw->boostint, dw->monochrome);
+ dw->pixbuf = render_get_image(dw);
} else {
dw->pixbuf = NULL;
}
@@ -445,7 +444,7 @@ static gint displaywindow_peaklist_response(GtkWidget *d, gint response,
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
- load_features_from_file(hdfile_get_image(dw->hdfile), filename);
+ load_features_from_file(dw->image, filename);
displaywindow_update(dw);
g_free(filename);
@@ -622,12 +621,20 @@ static void numbers_update(DisplayWindow *dw)
int16_t val;
GtkWidget *l;
int x, y;
+ int valid;
x = dw->binning * dw->numbers_window->cx + (px-8);
y = dw->binning * dw->numbers_window->cy + (py-8);
- if ( (x>0) && (y>0) &&
- !hdfile_get_unbinned_value(dw->hdfile, x, y, &val) ) {
+ if ( (x>=dw->image->width) || (y>=dw->image->height) ) {
+ valid = 0;
+ val = 0;
+ } else {
+ val = dw->image->data[x+y*dw->image->width];
+ valid = 1;
+ }
+
+ if ( (x>0) && (y>0) && valid ) {
snprintf(s, 31, "%i", val);
} else {
strcpy(s, "--");
@@ -720,6 +727,7 @@ struct newhdf {
static gint displaywindow_newhdf(GtkMenuItem *item, struct newhdf *nh)
{
hdfile_set_image(nh->dw->hdfile, nh->name);
+ nh->dw->image_dirty = 1; /* dw->image now contains the wrong thing */
displaywindow_update(nh->dw);
return 0;
}
@@ -944,6 +952,8 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
dw->boostint = 1;
dw->motion_callback = 0;
dw->numbers_window = NULL;
+ dw->image = NULL;
+ dw->image_dirty = 0;
dw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -995,7 +1005,7 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks,
/* Peak list provided at startup? */
if ( peaks != NULL ) {
- load_features_from_file(hdfile_get_image(dw->hdfile), peaks);
+ load_features_from_file(dw->image, peaks);
displaywindow_update(dw);
}
diff --git a/src/displaywindow.h b/src/displaywindow.h
index 8902bcbd..f0491460 100644
--- a/src/displaywindow.h
+++ b/src/displaywindow.h
@@ -17,6 +17,8 @@
#ifndef DISPLAYWINDOW_H
#define DISPLAYWINDOW_H
+#include <gtk/gtk.h>
+
typedef struct {
GtkWidget *window;
@@ -48,6 +50,8 @@ typedef struct {
gulong motion_callback;
struct hdfile *hdfile;
+ struct image *image;
+ int image_dirty;
/* Dialog boxes */
BinningDialog *binning_dialog;
diff --git a/src/filters.c b/src/filters.c
new file mode 100644
index 00000000..235d2822
--- /dev/null
+++ b/src/filters.c
@@ -0,0 +1,97 @@
+/*
+ * filters.c
+ *
+ * Image filtering
+ *
+ * (c) 2006-2010 Thomas White <taw@physics.org>
+ *
+ * Part of CrystFEL - crystallography with a FEL
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+#include <gsl/gsl_statistics_int.h>
+
+#include "image.h"
+
+
+static int compare_vals(const void *ap, const void *bp)
+{
+ const signed int a = *(signed int *)ap;
+ const signed int b = *(signed int *)bp;
+
+ if ( a > b ) return 1;
+ if ( a < b ) return -1;
+ return 0;
+}
+
+
+static void clean_panel(struct image *image, int sx, int sy)
+{
+ int x, y;
+ const int s = sizeof(signed int);
+
+ for ( y=0; y<128; y++ ) {
+
+ signed int vals[512];
+ double m;
+
+ for ( x=0; x<512; x++ ) {
+ vals[x] = image->data[(x+sx)+(y+sy)*image->width];
+ }
+
+ qsort(&vals[0], 512, s, compare_vals);
+
+ m = gsl_stats_int_median_from_sorted_data(vals, 1, 512);
+
+ for ( x=0; x<512; x++ ) {
+ image->data[(x+sx)+(y+sy)*image->width] -= m;
+ }
+
+ }
+
+ for ( x=0; x<512; x++ ) {
+
+ signed int vals[128];
+ double m;
+
+ for ( y=0; y<128; y++ ) {
+ vals[y] = image->data[(x+sx)+(y+sy)*image->width];
+ }
+
+ qsort(&vals[0], 128, s, compare_vals);
+
+ m = gsl_stats_int_median_from_sorted_data(vals, 1, 128);
+
+ for ( y=0; y<128; y++ ) {
+ image->data[(x+sx)+(y+sy)*image->width] -= m;
+ }
+
+ }
+}
+
+
+/* Pre-processing to make life easier */
+void clean_image(struct image *image)
+{
+ int px, py;
+
+ if ( (image->width != 1024) || (image->height != 1024) ) return;
+
+ for ( px=0; px<2; px++ ) {
+ for ( py=0; py<8; py++ ) {
+
+ clean_panel(image, 512*px, 128*py);
+
+ }
+ }
+}
diff --git a/src/filters.h b/src/filters.h
new file mode 100644
index 00000000..b28cb908
--- /dev/null
+++ b/src/filters.h
@@ -0,0 +1,23 @@
+/*
+ * peaks.h
+ *
+ * Image filtering
+ *
+ * (c) 2006-2010 Thomas White <taw@physics.org>
+ *
+ * Part of CrystFEL - crystallography with a FEL
+ *
+ */
+
+
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+extern void clean_image(struct image *image);
+
+#endif /* FILTERS_H */
diff --git a/src/hdf5-file.c b/src/hdf5-file.c
index ceb4c0ab..d8aee21d 100644
--- a/src/hdf5-file.c
+++ b/src/hdf5-file.c
@@ -28,9 +28,6 @@ struct hdfile {
const char *path; /* Current data path */
- struct image *image;
- int image_dirty;
-
size_t nx; /* Image width */
size_t ny; /* Image height */
@@ -46,8 +43,6 @@ struct hdfile *hdfile_open(const char *filename)
f = malloc(sizeof(struct hdfile));
if ( f == NULL ) return NULL;
- f->image = NULL;
- f->image_dirty = 1;
f->fh = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if ( f->fh < 0 ) {
@@ -82,8 +77,6 @@ int hdfile_set_image(struct hdfile *f, const char *path)
f->nx = size[0];
f->ny = size[1];
- f->image_dirty = 1;
-
return 0;
}
@@ -103,105 +96,10 @@ int hdfile_get_height(struct hdfile *f)
void hdfile_close(struct hdfile *f)
{
H5Fclose(f->fh);
- if ( f->image != NULL ) {
- if ( f->image->features != NULL ) {
- image_feature_list_free(f->image->features);
- }
- free(f->image->data);
- free(f->image);
- }
free(f);
}
-static void *hdfile_bin(int16_t *in, int inw, int inh,
- int binning, int16_t *maxp)
-{
- int16_t *data;
- int x, y;
- int w, h;
- int16_t max;
-
- w = inw / binning;
- h = inh / binning; /* Some pixels might get discarded */
-
- data = malloc(w*h*sizeof(int16_t));
- max = 0;
-
- for ( x=0; x<w; x++ ) {
- for ( y=0; y<h; y++ ) {
-
- /* Big enough to hold large values */
- unsigned long long int total;
- size_t xb, yb;
-
- total = 0;
- for ( xb=0; xb<binning; xb++ ) {
- for ( yb=0; yb<binning; yb++ ) {
-
- total += in[binning*x+xb + (binning*y+yb)*(w*binning)];
-
- }
- }
-
- data[x+w*y] = total / (binning * binning);
- if ( data[x+w*y] > max ) max = data[x+w*y];
-
- }
- }
-
- *maxp = max;
- return data;
-}
-
-
-int16_t *hdfile_get_image_binned(struct hdfile *f, int binning, int16_t *max)
-{
- struct image *image;
- int16_t *data;
-
- if ( (f->image == NULL) || (f->image_dirty) ) {
-
- image = malloc(sizeof(struct image));
- if ( image == NULL ) return NULL;
- image->features = NULL;
- image->data = NULL;
-
- hdf5_read(f, image);
-
- /* Deal with the old image, if existing */
- if ( f->image != NULL ) {
- image->features = f->image->features;
- if ( f->image->data != NULL ) free(f->image->data);
- free(f->image->data);
- }
-
- f->image = image;
-
- }
-
- data = hdfile_bin(f->image->data, f->nx, f->ny, binning, max);
-
- return data;
-}
-
-
-struct image *hdfile_get_image(struct hdfile *f)
-{
- return f->image;
-}
-
-
-int hdfile_get_unbinned_value(struct hdfile *f, int x, int y, int16_t *val)
-{
- if ( (x>=f->image->width) || (y>=f->image->height) ) {
- return 1;
- }
- *val = f->image->data[x+y*f->image->width];
- return 0;
-}
-
-
int hdf5_write(const char *filename, const int16_t *data,
int width, int height)
{
@@ -293,7 +191,6 @@ int hdf5_read(struct hdfile *f, struct image *image)
image->data = buf;
image->height = f->nx;
image->width = f->ny;
- f->image_dirty = 0;
/* Always camera length/lambda formulation for FEL */
image->fmode = FORMULATION_CLEN;
diff --git a/src/hdf5-file.h b/src/hdf5-file.h
index 32a76505..e1e9d2a1 100644
--- a/src/hdf5-file.h
+++ b/src/hdf5-file.h
@@ -34,14 +34,11 @@ extern int hdfile_get_width(struct hdfile *f);
extern int hdfile_get_height(struct hdfile *f);
extern int16_t *hdfile_get_image_binned(struct hdfile *hdfile,
int binning, int16_t *maxp);
-extern int hdfile_get_unbinned_value(struct hdfile *f, int x, int y,
- int16_t *val);
extern char **hdfile_read_group(struct hdfile *f, int *n, const char *parent,
int **p_is_group, int **p_is_image);
extern int hdfile_set_first_image(struct hdfile *f, const char *group);
extern void hdfile_close(struct hdfile *f);
extern char *hdfile_get_string_value(struct hdfile *f, const char *name);
-extern struct image *hdfile_get_image(struct hdfile *f);
#endif /* HDF5_H */
diff --git a/src/peaks.c b/src/peaks.c
index 0e87135b..c6394787 100644
--- a/src/peaks.c
+++ b/src/peaks.c
@@ -26,6 +26,7 @@
#include "index.h"
#include "peaks.h"
#include "detector.h"
+#include "filters.h"
#define PEAK_WINDOW_SIZE (10)
@@ -267,79 +268,6 @@ static void cull_peaks(struct image *image)
}
-static int compare_vals(const void *ap, const void *bp)
-{
- const signed int a = *(signed int *)ap;
- const signed int b = *(signed int *)bp;
-
- if ( a > b ) return 1;
- if ( a < b ) return -1;
- return 0;
-}
-
-
-static void clean_panel(struct image *image, int sx, int sy)
-{
- int x, y;
- const int s = sizeof(signed int);
-
- for ( y=0; y<128; y++ ) {
-
- signed int vals[512];
- double m;
-
- for ( x=0; x<512; x++ ) {
- vals[x] = image->data[(x+sx)+(y+sy)*image->width];
- }
-
- qsort(&vals[0], 512, s, compare_vals);
-
- m = gsl_stats_int_median_from_sorted_data(vals, 1, 512);
-
- for ( x=0; x<512; x++ ) {
- image->data[(x+sx)+(y+sy)*image->width] -= m;
- }
-
- }
-
- for ( x=0; x<512; x++ ) {
-
- signed int vals[128];
- double m;
-
- for ( y=0; y<128; y++ ) {
- vals[y] = image->data[(x+sx)+(y+sy)*image->width];
- }
-
- qsort(&vals[0], 128, s, compare_vals);
-
- m = gsl_stats_int_median_from_sorted_data(vals, 1, 128);
-
- for ( y=0; y<128; y++ ) {
- image->data[(x+sx)+(y+sy)*image->width] -= m;
- }
-
- }
-}
-
-
-/* Pre-processing to make life easier */
-void clean_image(struct image *image)
-{
- int px, py;
-
- if ( (image->width != 1024) || (image->height != 1024) ) return;
-
- for ( px=0; px<2; px++ ) {
- for ( py=0; py<8; py++ ) {
-
- clean_panel(image, 512*px, 128*py);
-
- }
- }
-}
-
-
void search_peaks(struct image *image)
{
int x, y, width, height;
diff --git a/src/peaks.h b/src/peaks.h
index c4cbfb48..2e868342 100644
--- a/src/peaks.h
+++ b/src/peaks.h
@@ -21,6 +21,5 @@
extern int image_fom(struct image *image);
extern void search_peaks(struct image *image);
extern void dump_peaks(struct image *image);
-extern void clean_image(struct image *image);
#endif /* PEAKS_H */
diff --git a/src/render.c b/src/render.c
index 842c1b86..5b47775f 100644
--- a/src/render.c
+++ b/src/render.c
@@ -20,6 +20,83 @@
#include "hdf5-file.h"
#include "render.h"
+#include "peaks.h"
+#include "filters.h"
+
+
+static void *render_bin(int16_t *in, int inw, int inh,
+ int binning, int16_t *maxp)
+{
+ int16_t *data;
+ int x, y;
+ int w, h;
+ int16_t max;
+
+ w = inw / binning;
+ h = inh / binning; /* Some pixels might get discarded */
+
+ data = malloc(w*h*sizeof(int16_t));
+ max = 0;
+
+ for ( x=0; x<w; x++ ) {
+ for ( y=0; y<h; y++ ) {
+
+ /* Big enough to hold large values */
+ unsigned long long int total;
+ size_t xb, yb;
+
+ total = 0;
+ for ( xb=0; xb<binning; xb++ ) {
+ for ( yb=0; yb<binning; yb++ ) {
+
+ total += in[binning*x+xb + (binning*y+yb)*(w*binning)];
+
+ }
+ }
+
+ data[x+w*y] = total / (binning * binning);
+ if ( data[x+w*y] > max ) max = data[x+w*y];
+
+ }
+ }
+
+ *maxp = max;
+ return data;
+}
+
+
+int16_t *render_get_image_binned(DisplayWindow *dw, int binning, int16_t *max)
+{
+ struct image *image;
+ int16_t *data;
+
+ if ( (dw->image == NULL) || (dw->image_dirty) ) {
+
+ image = malloc(sizeof(struct image));
+ if ( image == NULL ) return NULL;
+ image->features = NULL;
+ image->data = NULL;
+
+ hdf5_read(dw->hdfile, image);
+ dw->image_dirty = 0;
+ clean_image(image);
+
+ /* Deal with the old image, if existing */
+ if ( dw->image != NULL ) {
+ image->features = dw->image->features;
+ if ( dw->image->data != NULL ) free(dw->image->data);
+ }
+
+ dw->image = image;
+
+ }
+
+ data = render_bin(dw->image->data, hdfile_get_width(dw->hdfile),
+ hdfile_get_height(dw->hdfile), binning, max);
+
+ return data;
+}
+
#define RENDER_RGB \
\
@@ -130,8 +207,7 @@ static void show_marked_features(struct image *image, guchar *data,
/* Return a pixbuf containing a rendered version of the image after binning.
* This pixbuf might be scaled later - hopefully mostly in a downward
* direction. */
-GdkPixbuf *render_get_image(struct hdfile *hdfile, int binning, int boostint,
- int monochrome)
+GdkPixbuf *render_get_image(DisplayWindow *dw)
{
int mw, mh, w, h;
guchar *data;
@@ -139,13 +215,13 @@ GdkPixbuf *render_get_image(struct hdfile *hdfile, int binning, int boostint,
size_t x, y;
int16_t max;
- mw = hdfile_get_width(hdfile);
- mh = hdfile_get_height(hdfile);
- w = mw / binning;
- h = mh / binning;
+ mw = hdfile_get_width(dw->hdfile);
+ mh = hdfile_get_height(dw->hdfile);
+ w = mw / dw->binning;
+ h = mh / dw->binning;
/* High dynamic range version */
- hdr = hdfile_get_image_binned(hdfile, binning, &max);
+ hdr = render_get_image_binned(dw, dw->binning, &max);
if ( hdr == NULL ) return NULL;
/* Rendered (colourful) version */
@@ -155,7 +231,7 @@ GdkPixbuf *render_get_image(struct hdfile *hdfile, int binning, int boostint,
return NULL;
}
- max /= boostint;
+ max /= dw->boostint;
if ( max <= 6 ) { max = 10; }
/* These x,y coordinates are measured relative to the bottom-left
* corner */
@@ -166,7 +242,7 @@ GdkPixbuf *render_get_image(struct hdfile *hdfile, int binning, int boostint,
guchar r, g, b;
val = hdr[x+w*y];
- if ( !monochrome ) {
+ if ( !dw->monochrome ) {
RENDER_RGB
} else {
RENDER_MONO
@@ -182,7 +258,7 @@ GdkPixbuf *render_get_image(struct hdfile *hdfile, int binning, int boostint,
}
}
- show_marked_features(hdfile_get_image(hdfile), data, w, h, binning);
+ show_marked_features(dw->image, data, w, h, dw->binning);
/* Finished with this */
free(hdr);
diff --git a/src/render.h b/src/render.h
index e687da72..e030f27b 100644
--- a/src/render.h
+++ b/src/render.h
@@ -21,8 +21,9 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <stddef.h>
-extern GdkPixbuf *render_get_image(struct hdfile *micron, int binning,
- int boostint, int monochrome);
+#include "displaywindow.h"
+
+extern GdkPixbuf *render_get_image(DisplayWindow *dw);
extern GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int monochrome);