aboutsummaryrefslogtreecommitdiff
path: root/src/crystfelimageview.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2020-06-29 13:55:20 +0200
committerThomas White <taw@physics.org>2020-07-29 18:53:44 +0200
commit6dfea8ddd0b7cb717fc120dc68edc42b0e1fbdd8 (patch)
tree0579adcdcee8bb37c8028c26065b068276868204 /src/crystfelimageview.c
parent93be7a848a320d8eaa0966f57aa56b0337525d4c (diff)
Break render.c down and move to geoptimiser and CrystFELImageView
These two functions will diverge in the future. Also, this change removes the last remaining dependency of libcrystfel on Gdk/Gtk-anything.
Diffstat (limited to 'src/crystfelimageview.c')
-rw-r--r--src/crystfelimageview.c170
1 files changed, 168 insertions, 2 deletions
diff --git a/src/crystfelimageview.c b/src/crystfelimageview.c
index 35636a73..7cb3f9b6 100644
--- a/src/crystfelimageview.c
+++ b/src/crystfelimageview.c
@@ -39,7 +39,6 @@
#include <utils.h>
#include <detgeom.h>
-#include <render.h>
#include <colscale.h>
#include "crystfelimageview.h"
@@ -68,7 +67,6 @@ G_DEFINE_TYPE_WITH_CODE(CrystFELImageView, crystfel_image_view,
G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE,
scroll_interface_init))
-
static void redraw(CrystFELImageView *iv)
{
gint w, h;
@@ -676,6 +674,174 @@ static void detgeom_pixel_extents(struct detgeom *det,
}
+static float *get_binned_panel(struct image *image, int binning,
+ int pi, double *max, int *pw, int *ph)
+{
+ float *data;
+ int x, y;
+ int w, h;
+
+ struct detgeom_panel *p = &image->detgeom->panels[pi];
+
+ /* Some pixels might get discarded */
+ w = p->w / binning;
+ h = p->h / binning;
+ *pw = w;
+ *ph = h;
+
+ data = malloc(w*h*sizeof(float));
+
+ *max = 0.0;
+ for ( x=0; x<w; x++ ) {
+ for ( y=0; y<h; y++ ) {
+
+ double total;
+ size_t xb, yb;
+ int bad = 0;
+ double val;
+
+ total = 0;
+ for ( xb=0; xb<binning; xb++ ) {
+ for ( yb=0; yb<binning; yb++ ) {
+
+ double v;
+ int fs, ss;
+
+ fs = binning*x+xb;
+ ss = binning*y+yb;
+ v = image->dp[pi][fs+ss*p->w];
+ total += v;
+
+ if ( (image->bad != NULL)
+ && (image->bad[pi][fs+ss*p->w]) ) bad = 1;
+
+ }
+ }
+
+ val = total / ((double)binning * (double)binning);
+
+ if ( bad ) {
+ data[x+w*y] = -INFINITY;
+ } else {
+ data[x+w*y] = val;
+ if ( val > *max ) *max = val;
+ }
+
+ }
+ }
+
+ return data;
+}
+
+
+static void render_free_data(guchar *data, gpointer p)
+{
+ free(data);
+}
+
+
+static GdkPixbuf *render_panel(float *hdr, int scale, double max, int w, int h)
+{
+ guchar *data;
+ int x, y;
+
+ /* Rendered (colourful) version */
+ data = malloc(3*w*h);
+ if ( data == NULL ) return NULL;
+
+ /* These x,y coordinates are measured relative to the bottom-left
+ * corner */
+ for ( y=0; y<h; y++ ) {
+ for ( x=0; x<w; x++ ) {
+
+ double val;
+ double r, g, b;
+
+ val = hdr[x+w*y];
+
+ if ( val > -INFINITY ) {
+
+ 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
+ * from the top-left corner */
+ data[3*( x+w*y )+0] = 255*r;
+ data[3*( x+w*y )+1] = 255*g;
+ data[3*( x+w*y )+2] = 255*b;
+
+ } else {
+
+ data[3*( x+w*y )+0] = 30;
+ data[3*( x+w*y )+1] = 20;
+ data[3*( x+w*y )+2] = 0;
+
+ }
+
+ }
+ }
+
+ /* Create the pixbuf from the 8-bit display data */
+ return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8,
+ w, h, w*3, render_free_data, NULL);
+
+}
+
+
+/* Render an image into multiple pixbufs according to geometry */
+GdkPixbuf **render_panels(struct image *image,
+ int binning, int scale, double boost,
+ int *n_pixbufs)
+{
+ int i;
+ int np;
+ GdkPixbuf **pixbufs;
+ float **hdrs;
+ double max;
+ int *ws, *hs;
+
+ np = image->detgeom->n_panels;
+
+ hdrs = calloc(np, sizeof(float *));
+ ws = calloc(np, sizeof(int));
+ hs = calloc(np, sizeof(int));
+ if ( (hdrs == NULL) || (ws == NULL) || (hs == NULL) ) {
+ *n_pixbufs = 0;
+ return NULL;
+ }
+
+ /* Find overall max value for whole image */
+ max = 0.0;
+ for ( i=0; i<np; i++ ) {
+ double this_max = 0.0;
+ hdrs[i] = get_binned_panel(image, binning, i, &this_max,
+ &ws[i], &hs[i]);
+ if ( this_max > max ) max = this_max;
+ }
+
+ max /= boost;
+ if ( max <= 6 ) { max = 10; }
+
+ pixbufs = calloc(np, sizeof(GdkPixbuf*));
+ if ( pixbufs == NULL ) {
+ *n_pixbufs = 0;
+ return NULL;
+ }
+
+ for ( i=0; i<np; i++ ) {
+ pixbufs[i] = render_panel(hdrs[i], scale, max, ws[i], hs[i]);
+ free(hdrs[i]);
+ }
+
+ free(hdrs);
+ free(ws);
+ free(hs);
+ *n_pixbufs = np;
+
+ return pixbufs;
+}
+
+
static int reload_image(CrystFELImageView *iv)
{
if ( iv->dtempl == NULL ) return 0;