diff options
author | Thomas White <taw@bitwiz.org.uk> | 2011-02-17 11:53:00 -0800 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2012-02-22 15:27:15 +0100 |
commit | 6ffd78ac10f229608bbdf920799bb3aa8f4fdd2d (patch) | |
tree | 9ca3b44c7f63c3f287a4f0a9b1dda81679203c59 | |
parent | 50523729d22be834315ff9084f73a36a235400ab (diff) |
Decouple renderer from 'hdfsee'
-rw-r--r-- | src/displaywindow.c | 35 | ||||
-rw-r--r-- | src/displaywindow.h | 1 | ||||
-rw-r--r-- | src/hdf5-file.c | 17 | ||||
-rw-r--r-- | src/hdf5-file.h | 2 | ||||
-rw-r--r-- | src/render.c | 193 | ||||
-rw-r--r-- | src/render.h | 13 |
6 files changed, 55 insertions, 206 deletions
diff --git a/src/displaywindow.c b/src/displaywindow.c index 04377ef5..b3e9f7ab 100644 --- a/src/displaywindow.c +++ b/src/displaywindow.c @@ -49,9 +49,9 @@ static void displaywindow_update(DisplayWindow *dw) gint width; GdkGeometry geom; - if ( dw->hdfile != NULL ) { - dw->width = hdfile_get_width(dw->hdfile)/dw->binning; - dw->height = hdfile_get_height(dw->hdfile)/dw->binning; + if ( dw->image != NULL ) { + dw->width = dw->image->width/dw->binning; + dw->height = dw->image->height/dw->binning; } else { dw->width = 320; dw->height = 320; @@ -73,8 +73,9 @@ static void displaywindow_update(DisplayWindow *dw) if ( dw->pixbuf != NULL ) { gdk_pixbuf_unref(dw->pixbuf); } - if ( dw->hdfile != NULL ) { - dw->pixbuf = render_get_image(dw); + if ( dw->image != NULL ) { + dw->pixbuf = render_get_image(dw->image, dw->binning, dw->scale, + dw->boostint); } else { dw->pixbuf = NULL; } @@ -164,8 +165,8 @@ static gint displaywindow_set_binning_response(GtkWidget *widget, gint response, "binning factor."); done = 0; } else { - if ((binning < hdfile_get_width(dw->hdfile)/10) - && (binning < hdfile_get_height(dw->hdfile)/10)) { + if ((binning < dw->image->width/10) + && (binning < dw->image->height/10)) { dw->binning = binning; displaywindow_update(dw); } else { @@ -250,8 +251,7 @@ static gint displaywindow_set_binning(GtkWidget *widget, DisplayWindow *dw) 1, 3, 1, 2); snprintf(tmp, 63, "Raw image size: %i by %i pixels", - (int)hdfile_get_width(dw->hdfile), - (int)hdfile_get_height(dw->hdfile)); + dw->image->width, dw->image->height); label = gtk_label_new(tmp); gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 1, 3, 2, 3); @@ -539,11 +539,11 @@ static gint displaywindow_save_response(GtkWidget *d, gint response, type = gtk_combo_box_get_active(GTK_COMBO_BOX(cd->cb)); if ( type == 0 ) { - r = render_png(dw, file); + r = render_png(dw->pixbuf, file); } else if ( type == 1 ) { - r = render_tiff_fp(dw, file); + r = render_tiff_fp(dw->image, file); } else if ( type == 2 ) { - r = render_tiff_int16(dw, file); + r = render_tiff_int16(dw->image, file, dw->boostint); } else { r = -1; } @@ -879,7 +879,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 */ + hdf5_read(nh->dw->hdfile, nh->dw->image, 0, 0.0); displaywindow_update(nh->dw); return 0; } @@ -1083,6 +1083,7 @@ static gint displaywindow_motion(GtkWidget *widget, GdkEventMotion *event, } + static gint displaywindow_press(GtkWidget *widget, GdkEventButton *event, DisplayWindow *dw) { @@ -1130,7 +1131,6 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, dw->motion_callback = 0; dw->numbers_window = NULL; dw->image = NULL; - dw->image_dirty = 0; dw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -1163,11 +1163,14 @@ DisplayWindow *displaywindow_open(const char *filename, const char *peaks, dw->hdfile = hdfile_open(filename); if ( dw->hdfile == NULL ) { - fprintf(stderr, "Couldn't open file '%s'\n", filename); + ERROR("Couldn't open file '%s'\n", filename); displaywindow_disable(dw); } else if ( hdfile_set_first_image(dw->hdfile, "/") ) { - fprintf(stderr, "Couldn't select path\n"); + ERROR("Couldn't select path\n"); displaywindow_disable(dw); + } else { + dw->image = calloc(1, sizeof(struct image)); + hdf5_read(dw->hdfile, dw->image, 0, 0.0); } } else { diff --git a/src/displaywindow.h b/src/displaywindow.h index 142243fe..870a3d5b 100644 --- a/src/displaywindow.h +++ b/src/displaywindow.h @@ -52,7 +52,6 @@ typedef struct { struct hdfile *hdfile; struct image *image; - int image_dirty; /* Dialog boxes */ BinningDialog *binning_dialog; diff --git a/src/hdf5-file.c b/src/hdf5-file.c index 3a541584..de25d396 100644 --- a/src/hdf5-file.c +++ b/src/hdf5-file.c @@ -89,18 +89,6 @@ int hdfile_set_image(struct hdfile *f, const char *path) } -int hdfile_get_width(struct hdfile *f) -{ - return f->ny; -} - - -int hdfile_get_height(struct hdfile *f) -{ - return f->nx; -} - - int get_peaks(struct image *image, struct hdfile *f) { hid_t dh, sh; @@ -408,9 +396,8 @@ int hdf5_read(struct hdfile *f, struct image *image, int satcorr, uint16_t *flags; hid_t mask_dh; - image->width = hdfile_get_width(f); - image->height = hdfile_get_height(f); - STATUS("%i, %i\n", image->width, image->height); + image->width = f->ny; + image->height = f->nx; /* Note axis swap */ buf = malloc(sizeof(float)*f->nx*f->ny); diff --git a/src/hdf5-file.h b/src/hdf5-file.h index 4f849638..342dfe72 100644 --- a/src/hdf5-file.h +++ b/src/hdf5-file.h @@ -32,8 +32,6 @@ extern int hdf5_read(struct hdfile *f, struct image *image, int satcorr, extern struct hdfile *hdfile_open(const char *filename); extern int hdfile_set_image(struct hdfile *f, const char *path); -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 char **hdfile_read_group(struct hdfile *f, int *n, const char *parent, diff --git a/src/render.c b/src/render.c index daf0551a..08ced66b 100644 --- a/src/render.c +++ b/src/render.c @@ -139,14 +139,19 @@ void render_scale(float val, float max, int scale, #ifdef HAVE_GTK - -static void *render_bin(float *in, int inw, int inh, int binning, float *maxp) +static float *get_binned_image(struct image *image, int binning, float *pmax) { float *data; int x, y; int w, h; + int inw, inh; + float *in; float max; + inw = image->width; + inh = image->height; + in = image->data; + w = inw / binning; h = inh / binning; /* Some pixels might get discarded */ @@ -174,44 +179,9 @@ static void *render_bin(float *in, int inw, int inh, int binning, float *maxp) } } - *maxp = max; + *pmax = max; return data; -} - - -float *render_get_image_binned(DisplayWindow *dw, int binning, float *max) -{ - struct image *image; - float *data; - - if ( (dw->image == NULL) || (dw->image_dirty) ) { - - image = malloc(sizeof(struct image)); - if ( image == NULL ) return NULL; - image->features = NULL; - image->data = NULL; - - /* We don't care about the photon energy here */ - hdf5_read(dw->hdfile, image, 1, 0.0); - dw->image_dirty = 0; - if ( dw->cmfilter ) filter_cm(image); - if ( dw->noisefilter ) filter_noise(image, NULL); - - /* 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); - free(dw->image); - } - - dw->image = image; - - } - - data = render_bin(dw->image->data, dw->image->width, dw->image->height, - binning, max); - return data; } @@ -267,21 +237,23 @@ 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(DisplayWindow *dw) +GdkPixbuf *render_get_image(struct image *image, int binning, int scale, + double boost) { - int mw, mh, w, h; + int w, h; guchar *data; float *hdr; - size_t x, y; + int x, y; float max; + int mw, mh; - mw = hdfile_get_width(dw->hdfile); - mh = hdfile_get_height(dw->hdfile); - w = mw / dw->binning; - h = mh / dw->binning; + mw = image->width; + mh = image->height; + w = mw / binning; + h = mh / binning; /* High dynamic range version */ - hdr = render_get_image_binned(dw, dw->binning, &max); + hdr = get_binned_image(image, binning, &max); if ( hdr == NULL ) return NULL; /* Rendered (colourful) version */ @@ -291,7 +263,7 @@ GdkPixbuf *render_get_image(DisplayWindow *dw) return NULL; } - max /= dw->boostint; + max /= boost; if ( max <= 6 ) { max = 10; } /* These x,y coordinates are measured relative to the bottom-left * corner */ @@ -302,7 +274,7 @@ GdkPixbuf *render_get_image(DisplayWindow *dw) float r, g, b; val = hdr[x+w*y]; - render_scale(val, max, dw->scale, &r, &g, &b); + render_scale(val, max, scale, &r, &g, &b); /* Stuff inside square brackets makes this pixel go to * the expected location in the pixbuf (which measures @@ -314,7 +286,7 @@ GdkPixbuf *render_get_image(DisplayWindow *dw) } } - show_marked_features(dw->image, data, w, h, dw->binning); + show_marked_features(image, data, w, h, binning); /* Finished with this */ free(hdr); @@ -324,6 +296,7 @@ GdkPixbuf *render_get_image(DisplayWindow *dw) w, h, w*3, render_free_data, NULL); } + GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale) { guchar *data; @@ -360,122 +333,20 @@ GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale) } -int render_png(DisplayWindow *dw, const char *filename) +int render_png(GdkPixbuf *pixbuf, const char *filename) { -#ifdef HAVE_LIBPNG - FILE *fh; - png_structp png_ptr; - png_infop info_ptr; - png_bytep *row_pointers; - int x, y; - float *hdr; - float max; - int w, h; - - w = dw->width; - h = dw->height; - - hdr = render_get_image_binned(dw, dw->binning, &max); - if ( hdr == NULL ) return 1; - - fh = fopen(filename, "wb"); - if ( !fh ) { - ERROR("Couldn't open output file.\n"); - return 1; - } - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - if ( !png_ptr ) { - ERROR("Couldn't create PNG write structure.\n"); - fclose(fh); - return 1; - } - info_ptr = png_create_info_struct(png_ptr); - if ( !info_ptr ) { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - ERROR("Couldn't create PNG info structure.\n"); - fclose(fh); - return 1; - } - if ( setjmp(png_jmpbuf(png_ptr)) ) { - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fh); - ERROR( "PNG write failed.\n"); - return 1; - } - png_init_io(png_ptr, fh); - - png_set_IHDR(png_ptr, info_ptr, w, h, 8, - PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - row_pointers = malloc(h*sizeof(png_bytep *)); - - /* Write the image data */ - max /= dw->boostint; - if ( max <= 6 ) { max = 10; } - - for ( y=0; y<h; y++ ) { - - row_pointers[y] = malloc(w*3); - - for ( x=0; x<w; x++ ) { - - float r, g, b; - float val; - - val = hdr[x+w*y]; - - render_scale(val, max, dw->scale, &r, &g, &b); - row_pointers[y][3*x] = (png_byte)255*r; - row_pointers[y][3*x+1] = (png_byte)255*g; - row_pointers[y][3*x+2] = (png_byte)255*b; - - } - } - - for ( y=0; y<h/2+1; y++ ) { - png_bytep scratch; - scratch = row_pointers[y]; - row_pointers[y] = row_pointers[h-y-1]; - row_pointers[h-y-1] = scratch; - } - - png_set_rows(png_ptr, info_ptr, row_pointers); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); - - png_destroy_write_struct(&png_ptr, &info_ptr); - for ( y=0; y<h; y++ ) { - free(row_pointers[y]); - } - free(row_pointers); - fclose(fh); - - free(hdr); -#else - STATUS("No PNG support.\n"); -#endif + gdk_pixbuf_save(pixbuf, filename, "png", NULL, NULL); return 0; } -int render_tiff_fp(DisplayWindow *dw, const char *filename) +int render_tiff_fp(struct image *image, const char *filename) { #ifdef HAVE_TIFF TIFF *th; - struct image *image; float *line; int y; - /* Get raw, unbinned image data */ - image = malloc(sizeof(struct image)); - if ( image == NULL ) return 1; - image->features = NULL; - image->data = NULL; - hdf5_read(dw->hdfile, image, 1, 0.0); - if ( dw->cmfilter ) filter_cm(image); - if ( dw->noisefilter ) filter_noise(image, NULL); - th = TIFFOpen(filename, "w"); if ( th == NULL ) return 1; @@ -507,24 +378,14 @@ int render_tiff_fp(DisplayWindow *dw, const char *filename) } -int render_tiff_int16(DisplayWindow *dw, const char *filename) +int render_tiff_int16(struct image *image, const char *filename, double boost) { #ifdef HAVE_TIFF TIFF *th; - struct image *image; int16_t *line; int x, y; float max; - /* Get raw, unbinned image data */ - image = malloc(sizeof(struct image)); - if ( image == NULL ) return 1; - image->features = NULL; - image->data = NULL; - hdf5_read(dw->hdfile, image, 1, 0.0); - if ( dw->cmfilter ) filter_cm(image); - if ( dw->noisefilter ) filter_noise(image, NULL); - th = TIFFOpen(filename, "w"); if ( th == NULL ) return 1; @@ -556,7 +417,7 @@ int render_tiff_int16(DisplayWindow *dw, const char *filename) float val; val = image->data[x+(image->height-1-y)*image->width]; - val *= ((float)dw->boostint/max); + val *= ((float)boost/max); /* Clamp to 16-bit range, * and work round inability of most readers to deal diff --git a/src/render.h b/src/render.h index ae9fb637..a193ae4a 100644 --- a/src/render.h +++ b/src/render.h @@ -20,7 +20,6 @@ #include <stddef.h> - #include "image.h" enum { @@ -29,6 +28,7 @@ enum { SCALE_INVMONO }; +/* Colour scale lookup */ extern void render_scale(float val, float max, int scale, float *rp, float *gp, float *bp); @@ -36,14 +36,15 @@ extern void render_scale(float val, float max, int scale, #ifdef HAVE_GTK #include <gdk-pixbuf/gdk-pixbuf.h> -#include "displaywindow.h" -extern GdkPixbuf *render_get_image(DisplayWindow *dw); +extern GdkPixbuf *render_get_image(struct image *image, + int binning, int scale, double boost); extern GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale); -extern int render_png(DisplayWindow *dw, const char *filename); -extern int render_tiff_fp(DisplayWindow *dw, const char *filename); -extern int render_tiff_int16(DisplayWindow *dw, const char *filename); +extern int render_png(GdkPixbuf *pixbuf, const char *filename); +extern int render_tiff_fp(struct image *image, const char *filename); +extern int render_tiff_int16(struct image *image, const char *filename, + double boost); #endif /* HAVE_GTK */ |