aboutsummaryrefslogtreecommitdiff
path: root/src/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/render.c')
-rw-r--r--src/render.c442
1 files changed, 0 insertions, 442 deletions
diff --git a/src/render.c b/src/render.c
deleted file mode 100644
index dbaca2fd..00000000
--- a/src/render.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * render.c
- *
- * Render a high dynamic range buffer in some sensible way
- *
- * (c) 2006-2011 Thomas White <taw@physics.org>
- *
- * Part of CrystFEL - crystallography with a FEL
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-#ifdef HAVE_GTK
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#endif
-
-#include <stdlib.h>
-#include <math.h>
-#include <stdint.h>
-
-#ifdef HAVE_TIFF
-#include <tiffio.h>
-#endif
-
-
-#include "hdf5-file.h"
-#include "render.h"
-#include "peaks.h"
-#include "filters.h"
-#include "utils.h"
-
-
-static void render_rgb(double val, double max,
- double *rp, double *gp, double *bp)
-{
- int s;
- double p;
- double r, g, b;
-
- s = val / (max/6);
- p = fmod(val, max/6.0);
- p /= (max/6.0);
-
- r = 0.0; g = 0.0; b = 0.0;
-
- if ( (val < 0.0) ) {
- s = 0;
- p = 0;
- }
- if ( (val > max) ) {
- s = 6;
- }
- switch ( s ) {
- case 0 : { /* Black to blue */
- r = 0; g = 0; b = p;
- break;
- }
- case 1 : { /* Blue to pink */
- r = p; g = 0; b = 1.0;
- break;
- }
- case 2 : { /* Pink to red */
- r = 1.0; g = 0; b = (1.0-p)*1.0;
- break;
- }
- case 3 : { /* Red to Orange */
- r = 1.0; g = 0.5*p; b = 0;
- break;
- }
- case 4 : { /* Orange to Yellow */
- r = 1.0; g = 0.5 + 0.5*p; b = 0;
- break;
- }
- case 5 : { /* Yellow to White */
- r = 1.0; g = 1.0; b = 1.0*p;
- break;
- }
- case 6 : { /* Pixel has hit the maximum value */
- r = 1.0; g = 1.0; b = 1.0;
- break;
- }
- }
-
- *rp = r;
- *gp = g;
- *bp = b;
-}
-
-
-static void render_ratio(double val, double max,
- double *rp, double *gp, double *bp)
-{
- if ( val <= 1.0 ) {
- render_rgb(val, 2.0, rp, gp, bp);
- } else {
- /* Your homework is to simplify this expression */
- val = ((val-1.0)/(max-1.0)) * (max/2.0) + max/2.0;
- render_rgb(val, max, rp, gp, bp);
- }
-}
-
-
-static void render_mono(double val, double max,
- double *rp, double *gp, double *bp)
-{
- double p;
- p = val / max;
- if ( val < 0.0 ) p = 0.0;
- if ( val > max ) p = 1.0;
- *rp = p;
- *gp = p;
- *bp = p;
-}
-
-
-static void render_invmono(double val, double max,
- double *rp, double *gp, double *bp)
-{
- double p;
- p = val / max;
- p = 1.0 - p;
- if ( val < 0.0 ) p = 1.0;
- if ( val > max ) p = 0.0;
- *rp = p;
- *gp = p;
- *bp = p;
-}
-
-
-void render_scale(double val, double max, int scale,
- double *rp, double *gp, double *bp)
-{
- switch ( scale ) {
- case SCALE_COLOUR :
- render_rgb(val, max, rp, gp, bp);
- break;
- case SCALE_MONO :
- render_mono(val, max, rp, gp, bp);
- break;
- case SCALE_INVMONO :
- render_invmono(val, max, rp, gp, bp);
- break;
- case SCALE_RATIO :
- render_ratio(val, max, rp, gp, bp);
- break;
- }
-}
-
-
-#ifdef HAVE_GTK
-
-static float *get_binned_panel(struct image *image, int binning,
- int min_fs, int max_fs, int min_ss, int max_ss)
-{
- float *data;
- int x, y;
- int w, h;
- int fw;
- float *in;
-
- fw = image->width;
- in = image->data;
-
- /* Some pixels might get discarded */
- w = (max_fs - min_fs + 1) / binning;
- h = (max_ss - min_ss + 1) / binning;
-
- data = malloc(w*h*sizeof(float));
-
- for ( x=0; x<w; x++ ) {
- for ( y=0; y<h; y++ ) {
-
- double total;
- size_t xb, yb;
-
- total = 0;
- for ( xb=0; xb<binning; xb++ ) {
- for ( yb=0; yb<binning; yb++ ) {
-
- double v;
- v = in[binning*x+xb+min_fs + (binning*y+yb+min_ss)*fw];
- total += v;
-
- }
- }
-
- data[x+w*y] = total / ((double)binning * (double)binning);
-
- }
- }
-
- return data;
-}
-
-
-/* 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(struct image *image,
- int binning, int scale, double boost,
- int min_fs, int max_fs, int min_ss, int max_ss)
-{
- int w, h;
- guchar *data;
- float *hdr;
- int x, y;
- double max;
- int pw, ph;
- int i;
-
- /* Calculate panel width and height
- * (add one because min and max are inclusive) */
- pw = max_fs - min_fs + 1;
- ph = max_ss - min_ss + 1;
- w = pw / binning;
- h = ph / binning;
-
- /* High dynamic range version */
- max = 0.0;
- for ( i=0; i<image->width*image->height; i++ ) {
- if ( image->data[i] > max ) max = image->data[i];
- }
- hdr = get_binned_panel(image, binning, min_fs, max_fs, min_ss, max_ss);
- if ( hdr == NULL ) return NULL;
-
- /* Rendered (colourful) version */
- data = malloc(3*w*h);
- if ( data == NULL ) {
- free(hdr);
- return NULL;
- }
-
- max /= boost;
- if ( max <= 6 ) { max = 10; }
- /* 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];
- 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;
-
- }
- }
-
- /* Finished with this */
- free(hdr);
-
- /* 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 = image->det->n_panels;
- GdkPixbuf **pixbufs;
-
- pixbufs = calloc(np, sizeof(GdkPixbuf*));
- if ( pixbufs == NULL ) {
- *n_pixbufs = 0;
- return NULL;
- }
-
- for ( i=0; i<np; i++ ) {
-
- pixbufs[i] = render_panel(image, binning, scale, boost,
- image->det->panels[i].min_fs,
- image->det->panels[i].max_fs,
- image->det->panels[i].min_ss,
- image->det->panels[i].max_ss);
-
- }
-
- *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;
-
- for ( y=0; y<h; y++ ) {
-
- double r, g, b;
- int val;
-
- val = y;
-
- 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;
- }
-
- }
-
- return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8,
- w, h, w*3, render_free_data, NULL);
-}
-
-
-int render_tiff_fp(struct image *image, const char *filename)
-{
-#ifdef HAVE_TIFF
- TIFF *th;
- float *line;
- int y;
-
- th = TIFFOpen(filename, "w");
- if ( th == NULL ) return 1;
-
- TIFFSetField(th, TIFFTAG_IMAGEWIDTH, image->width);
- TIFFSetField(th, TIFFTAG_IMAGELENGTH, image->height);
- TIFFSetField(th, TIFFTAG_SAMPLESPERPIXEL, 1);
- TIFFSetField(th, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
- TIFFSetField(th, TIFFTAG_BITSPERSAMPLE, 32);
- TIFFSetField(th, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
- TIFFSetField(th, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
- TIFFSetField(th, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(th, TIFFTAG_ROWSPERSTRIP,
- TIFFDefaultStripSize(th, image->width*4));
-
- line = _TIFFmalloc(TIFFScanlineSize(th));
- for ( y=0; y<image->height; y++ ) {
- memcpy(line, &image->data[(image->height-1-y)*image->width],
- image->width*4);
- TIFFWriteScanline(th, line, y, 0);
- }
- _TIFFfree(line);
-
- TIFFClose(th);
-
-#else
- STATUS("No TIFF support.\n");
-#endif
- return 0;
-}
-
-
-int render_tiff_int16(struct image *image, const char *filename, double boost)
-{
-#ifdef HAVE_TIFF
- TIFF *th;
- int16_t *line;
- int x, y;
- double max;
-
- th = TIFFOpen(filename, "w");
- if ( th == NULL ) return 1;
-
- TIFFSetField(th, TIFFTAG_IMAGEWIDTH, image->width);
- TIFFSetField(th, TIFFTAG_IMAGELENGTH, image->height);
- TIFFSetField(th, TIFFTAG_SAMPLESPERPIXEL, 1);
- TIFFSetField(th, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); /* (signed) */
- TIFFSetField(th, TIFFTAG_BITSPERSAMPLE, 16);
- TIFFSetField(th, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
- TIFFSetField(th, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
- TIFFSetField(th, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(th, TIFFTAG_ROWSPERSTRIP,
- TIFFDefaultStripSize(th, image->width*4));
-
- line = _TIFFmalloc(TIFFScanlineSize(th));
- max = 0.0;
- for ( y=0; y<image->height; y++ ) {
- for ( x=0;x<image->width; x++ ) {
- double val;
- val = image->data[x+image->height*y];
- if ( val > max ) max = val;
- }
- }
- max /= 32767.0;
-
- for ( y=0; y<image->height; y++ ) {
- for ( x=0;x<image->width; x++ ) {
-
- double val;
-
- val = image->data[x+(image->height-1-y)*image->width];
- val *= ((double)boost/max);
-
- /* Clamp to 16-bit range,
- * and work round inability of most readers to deal
- * with signed integers. */
- val += 1000.0;
- if ( val > 32767.0 ) val = 32767.0;
- if ( val < 0.0 ) val = 0.0;
-
- line[x] = val;
- }
-
- TIFFWriteScanline(th, line, y, 0);
- }
- _TIFFfree(line);
-
- TIFFClose(th);
-#else
- STATUS("No TIFF support.\n");
-#endif
- return 0;
-}
-
-#endif /* HAVE_GTK */