/* * render.c * * Render a high dynamic range buffer in some sensible way * * (c) 2008-2009 Thomas White * * hdfileview - view Ditabis Micron images * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "hdf5-file.h" /* Set to 1 to measure mean intensity in a rectangle */ #define MEASURE_INT 0 #define RENDER_RGB \ \ int s; \ float p; \ \ s = val / (max/6); \ p = fmod(val, max/6); \ p /= (max/6); \ \ r = 0; g = 0; b = 0; \ \ switch ( s ) { \ case 0 : { /* Black to blue */ \ r = 0; g = 0; b = p*255; \ break; \ } \ case 1 : { /* Blue to green */ \ r = 0; g = 255*p; b = (1-p)*255; \ break; \ } \ case 2 : { /* Green to red */ \ r =p*255; g = (1-p)*255; b = 0; \ break; \ } \ case 3 : { /* Red to Orange */ \ r = 255; g = 127*p; b = 0; \ break; \ } \ case 4 : { /* Orange to Yellow */ \ r = 255; g = 127 + 127*p; b = 0; \ break; \ } \ case 5 : { /* Yellow to White */ \ r = 255; g = 255; b = 255*p; \ break; \ } \ case 6 : { /* Pixel has hit the maximum value */ \ r = 255; g = 255; b = 255; \ break; \ } \ default : { /* Above saturation */ \ r = 255; g = 255; b = 255; \ break; \ } \ } #define RENDER_MONO \ float p; \ p = (float)val / (float)max; \ r = 255.0*p; g = 255.0*p; b = 255.0*p; /* 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); } /* 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) { int mw, mh, w, h; guchar *data; int16_t *hdr; size_t x, y; int16_t max; mw = hdfile_get_width(hdfile); mh = hdfile_get_height(hdfile); w = mw / binning; h = mh / binning; /* High dynamic range version */ hdr = hdfile_get_image_binned(hdfile, binning, &max); if ( hdr == NULL ) return NULL; /* Rendered (colourful) version */ data = malloc(3*w*h); if ( data == NULL ) { free(hdr); return NULL; } max /= boostint; if ( max <= 6 ) { max = 10; } /* These x,y coordinates are measured relative to the bottom-left * corner */ for ( y=0; y