diff options
author | Thomas White <taw@physics.org> | 2020-06-29 13:55:20 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2020-07-29 18:53:44 +0200 |
commit | 6dfea8ddd0b7cb717fc120dc68edc42b0e1fbdd8 (patch) | |
tree | 0579adcdcee8bb37c8028c26065b068276868204 | |
parent | 93be7a848a320d8eaa0966f57aa56b0337525d4c (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.
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | libcrystfel/CMakeLists.txt | 7 | ||||
-rw-r--r-- | libcrystfel/src/render.c | 264 | ||||
-rw-r--r-- | libcrystfel/src/render.h | 61 | ||||
-rw-r--r-- | src/crystfelimageview.c | 170 | ||||
-rw-r--r-- | src/geoptimiser.c | 44 |
6 files changed, 217 insertions, 335 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7697e141..77018925 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,6 +326,12 @@ list(APPEND CRYSTFEL_EXECUTABLES ambigator) # ---------------------------------------------------------------------- # geoptimiser + # FIXME! +#if (GDKPIXBUF_FOUND) +# target_include_directories(${PROJECT_NAME} PRIVATE ${GDKPIXBUF_INCLUDE_DIRS}) +# target_link_libraries(${PROJECT_NAME} PRIVATE ${GDKPIXBUF_LIBRARIES}) +#endif (GDKPIXBUF_FOUND) + # FIXME: Restore! #set(GEOPTIMISER_SOURCES src/geoptimiser.c) #add_executable(geoptimiser ${GEOPTIMISER_SOURCES}) diff --git a/libcrystfel/CMakeLists.txt b/libcrystfel/CMakeLists.txt index 6bc74981..7e89ed7c 100644 --- a/libcrystfel/CMakeLists.txt +++ b/libcrystfel/CMakeLists.txt @@ -42,7 +42,6 @@ set(LIBCRYSTFEL_SOURCES src/peaks.c src/reflist-utils.c src/filters.c - src/render.c src/index.c src/dirax.c src/mosflm.c @@ -84,7 +83,6 @@ set(LIBCRYSTFEL_HEADERS src/peakfinder8.h src/peaks.h src/stream.h - src/render.h src/index.h src/image.h src/filters.h @@ -166,11 +164,6 @@ if (CURSES_FOUND) target_link_libraries(${PROJECT_NAME} PRIVATE ${CURSES_LIBRARIES}) endif (CURSES_FOUND) -if (GDKPIXBUF_FOUND) - target_include_directories(${PROJECT_NAME} PRIVATE ${GDKPIXBUF_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PRIVATE ${GDKPIXBUF_LIBRARIES}) -endif (GDKPIXBUF_FOUND) - target_compile_options(${PROJECT_NAME} PRIVATE -Wall) set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${LIBCRYSTFEL_HEADERS}") diff --git a/libcrystfel/src/render.c b/libcrystfel/src/render.c deleted file mode 100644 index ff2df162..00000000 --- a/libcrystfel/src/render.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * render.c - * - * Render image data to GdkPixbufs - * - * Copyright © 2012-2020 Deutsches Elektronen-Synchrotron DESY, - * a research centre of the Helmholtz Association. - * - * Authors: - * 2009-2020 Thomas White <taw@physics.org> - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include <stdlib.h> -#include <math.h> -#include <stdint.h> - -#ifdef HAVE_GDKPIXBUF -#include <gdk-pixbuf/gdk-pixbuf.h> -#endif - - -#include "render.h" -#include "peaks.h" -#include "colscale.h" -#include "detgeom.h" - -/** \file render.h */ - -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; -} - - -#ifdef HAVE_GDKPIXBUF - -/* NB This function is shared between render_get_image() and - * render_get_colour_scale() */ -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; -} - - -GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale) -{ - guchar *data; - size_t x, y; - int max; - - data = malloc(3*w*h); - if ( data == NULL ) return NULL; - - max = h-(h/6); - - for ( y=0; y<h; y++ ) { - - double r, g, b; - int val; - - val = y-(h/6); - - render_scale(val, max, scale, &r, &g, &b); - - data[3*( 0+w*(h-1-y) )+0] = 0; - data[3*( 0+w*(h-1-y) )+1] = 0; - data[3*( 0+w*(h-1-y) )+2] = 0; - for ( x=1; x<w; x++ ) { - data[3*( x+w*(h-1-y) )+0] = 255*r; - data[3*( x+w*(h-1-y) )+1] = 255*g; - data[3*( x+w*(h-1-y) )+2] = 255*b; - } - - } - - y = h/6; - for ( x=1; x<w; x++ ) { - data[3*( x+w*(h-1-y) )+0] = 255; - data[3*( x+w*(h-1-y) )+1] = 255; - data[3*( x+w*(h-1-y) )+2] = 255; - } - - return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8, - w, h, w*3, render_free_data, NULL); -} - -#endif /* HAVE_GDKPIXBUF */ diff --git a/libcrystfel/src/render.h b/libcrystfel/src/render.h deleted file mode 100644 index 411c50ce..00000000 --- a/libcrystfel/src/render.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * render.h - * - * Render image data to GdkPixbufs - * - * Copyright © 2012-2020 Deutsches Elektronen-Synchrotron DESY, - * a research centre of the Helmholtz Association. - * - * Authors: - * 2009-2012 Thomas White <taw@physics.org> - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifndef RENDER_H -#define RENDER_H - -#include "image.h" - -/** - * \file render.h - * Render image data to GdkPixbufs - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_GDKPIXBUF -#include <gdk-pixbuf/gdk-pixbuf.h> - -extern GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale); - -extern GdkPixbuf **render_panels(struct image *image, - int binning, int scale, double boost, - int *n_pixbufs); -#endif /* HAVE_GDKPIXBUF */ - -#ifdef __cplusplus -} -#endif - -#endif /* RENDER_H */ 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; diff --git a/src/geoptimiser.c b/src/geoptimiser.c index ec4fbcd4..385a85d4 100644 --- a/src/geoptimiser.c +++ b/src/geoptimiser.c @@ -59,7 +59,6 @@ #include "crystal.h" #include "image.h" #include "utils.h" -#include "render.h" #include "colscale.h" struct imagefeature; @@ -157,6 +156,49 @@ struct gpanel }; +static GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale) +{ + guchar *data; + size_t x, y; + int max; + + data = malloc(3*w*h); + if ( data == NULL ) return NULL; + + max = h-(h/6); + + for ( y=0; y<h; y++ ) { + + double r, g, b; + int val; + + val = y-(h/6); + + render_scale(val, max, scale, &r, &g, &b); + + data[3*( 0+w*(h-1-y) )+0] = 0; + data[3*( 0+w*(h-1-y) )+1] = 0; + data[3*( 0+w*(h-1-y) )+2] = 0; + for ( x=1; x<w; x++ ) { + data[3*( x+w*(h-1-y) )+0] = 255*r; + data[3*( x+w*(h-1-y) )+1] = 255*g; + data[3*( x+w*(h-1-y) )+2] = 255*b; + } + + } + + y = h/6; + for ( x=1; x<w; x++ ) { + data[3*( x+w*(h-1-y) )+0] = 255; + data[3*( x+w*(h-1-y) )+1] = 255; + data[3*( x+w*(h-1-y) )+2] = 255; + } + + return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8, + w, h, w*3, render_free_data, NULL); +} + + static void compute_x_y(double fs, double ss, struct panel *p, double *x, double *y) { |