diff options
author | Thomas White <taw@physics.org> | 2010-01-21 15:36:44 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2010-01-21 15:36:44 +0100 |
commit | 552d860fa1bf4fd699d0af2e8ca0a13345fc624b (patch) | |
tree | 0185aa85891d64cd7c521dba06dc04d67c757ccf | |
parent | 395b2bd7770fb9a9f11be939c22d7abce702e4da (diff) |
Fix hdfile layering violations
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/displaywindow.c | 22 | ||||
-rw-r--r-- | src/displaywindow.h | 4 | ||||
-rw-r--r-- | src/filters.c | 97 | ||||
-rw-r--r-- | src/filters.h | 23 | ||||
-rw-r--r-- | src/hdf5-file.c | 103 | ||||
-rw-r--r-- | src/hdf5-file.h | 3 | ||||
-rw-r--r-- | src/peaks.c | 74 | ||||
-rw-r--r-- | src/peaks.h | 1 | ||||
-rw-r--r-- | src/render.c | 96 | ||||
-rw-r--r-- | src/render.h | 5 |
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); |