From: Steele Date: Mon, 5 Aug 2013 19:00:05 +0000 (+0200) Subject: Removing more backup files X-Git-Url: https://nsweb.tn.tudelft.nl/gitweb/?a=commitdiff_plain;h=dfa81508fd649a2b4fda6f47f1bd050176e3a705;p=spyview.git Removing more backup files --- diff --git a/spyview/ImageData.C.~1.114.~ b/spyview/ImageData.C.~1.114.~ deleted file mode 100644 index bf42c8b..0000000 --- a/spyview/ImageData.C.~1.114.~ +++ /dev/null @@ -1,3367 +0,0 @@ -#include -#include "ImageData.H" -#include "string.h" -#include -#include -#include -#include -#include "misc.h" -#include "mypam.h" -#include "../config.h" - -#include -// From http://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/gcc/variadic-macros.html - -#define badfile(A, ...) {info(A, ## __VA_ARGS__); return -1;} -#define badfilec(A, ...) {fclose(fp); info(A, ## __VA_ARGS__); return -1;} // ALso close the file. - -#define LINESIZE 1024*1024 - -#define MTX_HEADER_SIZE 256*10 - -// mingw32 does not seem to implement NAN properly: it seems to be set to 0. -#ifdef WIN32 -#define NAN INFINITY -#define isnan(A) isinf(A) -#endif - -//some handy local functions - -double parse_reading(char *line, int col); -double nextreading(FILE *fp, int col, int &lnum); -int nextline(FILE *fp, char *buf); - -ImageData::ImageData() -{ - data_loaded = 0; - orig_data = NULL; - qmin = xmin = ymin = 0; - qmax = xmax = ymax = 1; - auto_quant = 1; - auto_quant_percent = 50.0; - incorrect_column = COPY_ADJACENT; - mtx_cut_type = XY; - mtx_index = 0; - do_mtx_cut_title = false; - data3d = false; - gpload_type = COLUMNS; - gp_column = 2; - datfile_type = MATRIX; - fallbackfile_type = PGM; -} - -ImageData::~ImageData() -{ - clear(); -} - -void ImageData::clear() -{ - if (orig_data != NULL) //was using "data_loaded", but we had a big memory leak... - { - //info("clearing image data arrays\n"); - delete [] orig_data; - delete [] raw_data; - delete [] quant_data; - delete [] threshold_reject; - orig_data = NULL; - } - data_loaded = 0; -} - -void ImageData::reallocate() -{ - clear(); - orig_data = new double[width*height]; - raw_data = new double[width*height]; - quant_data = new int[width*height]; - threshold_reject = new bool[width*height]; - data_loaded = 1; -} - -void ImageData::resize_tmp_arrays(int new_width, int new_height) -{ - // Only ever make things bigger - if (new_width*new_height > orig_width*orig_height) - { - delete [] quant_data; - delete [] threshold_reject; - quant_data = new int[new_width*new_height]; - threshold_reject = new bool[new_width*new_height]; - } -} - -void ImageData::reset() -{ - memcpy(raw_data, orig_data, sizeof(double)*orig_width*orig_height); - width = orig_width; - height = orig_height; - xmin = orig_xmin; - ymin = orig_ymin; - xmax = orig_xmax; - ymax = orig_ymax; - xname = orig_xname; - yname = orig_yname; -} - -void ImageData::saveMTX(const char *filename) -{ - FILE *fp = fopen(filename, "wb"); - if (fp == NULL) - { - info("error opening file %s", filename); - return; - } - - fprintf(fp, "Units, %s," - "%s, %e, %e," - "%s, %e, %e," - "Nothing, 0, 1\n", - zname.c_str(), - xname.c_str(), xmin, xmax, - yname.c_str(), ymax, ymin); - fprintf(fp, "%d %d 1 8\n", width, height); - - for (int i=0; i=after_row) - { - for (int i=0; i width-1) i2 = i2 % (width); - if (i2 < 0) i2 = i2 + (-i2/width+1)*width; - if (i2>=0 && i2 < width) - new_row[i] = raw(i2,j); - else - new_row[i] = -1e2; // we should never get here if we - // did the bounds checking right - } - for (int i=0; i 5) && (s3 > 2)) - hdrlen = 0x1000; - else - hdrlen = 0x800; - } - - // Rewind and now read the correct header length - rewind(fp); - assert(hdrlen > 0); - if (fread(header, 1, hdrlen, fp) < static_cast(hdrlen)) - badfilec("Invalid STM file"); - - if (sscanf(strstr(header, "Pix"), "Pix %d", &w) != 1) - badfilec("Invalid width\n"); - - if (sscanf(strstr(header, "Lin"), "Lin %d", &h) != 1) - badfilec("Invalid height\n"); - - if (sscanf(strstr(header, "SR0"), "SR0 %lf", &xvrange) != 1) // range in volts - badfilec("Invalid xrange\n"); - - if (sscanf(strstr(header, "SR1"), "SR1 %lf", &yvrange) != 1) - badfilec("Invalid yrange\n"); - - if (sscanf(strstr(header, "S00"), "S00 %lf", &xcal) != 1) // scanner calibration in Ang/V - badfilec("Invalid xscale\n"); - - if (sscanf(strstr(header, "S10"), "S10 %lf", &ycal) != 1) - badfilec("Invalid xscale\n"); - - if (sscanf(strstr(header, "ImC"), "ImC %d", &chnum) != 1) - badfilec("Invalid chnum\n"); - - sprintf(buf1, "A%dN", chnum); - sprintf(buf2, "A%dN %%256\[^\n]", chnum); - if (sscanf(strstr(header, buf1), buf2, ch_name) != 1) - badfilec("Invalid channel name\n"); - - sprintf(buf1, "A%dU", chnum); - sprintf(buf2, "A%dU %%256[^\n]", chnum); - if (sscanf(strstr(header, buf1), buf2, ch_units) != 1) - badfilec("Invalid channel units\n"); - - sprintf(buf1, "A%dV", chnum); - sprintf(buf2, "A%dV %%lf\n", chnum); - if (sscanf(strstr(header, buf1), buf2, &ch_scale) != 1) - badfilec("Invalid channel scale\n"); - - - // Now update the ranges and stuff - - xmin = 0; - xmax = xvrange * xcal / 10000; // in microns - xname = "Microns"; - - ymin = 0; - ymax = yvrange * ycal / 10000; // in microns - yname = "Microns"; - - // Let's leave the STM file Z scale just as 0 to 65535 - // (It's usually just the +/- 10V anyway, which is not any more physical...) - - zname = "DAC Value"; - - width = w; height = h; - - reallocate(); - - for (int i=0; i 65535 || raw_data[i] < 0) - { - warn("%4d %4d Data %02x %02x %.1f %6d\n", i/w, i%w, tmp[0], tmp[1], raw_data[i], datatmp); - //getchar(); - } - } - fclose(fp); - store_orig(); - data3d = false; - return 0; -} - - -int ImageData::load_PGM(const char *name) -{ - char buf[1024]; - char *p; - - char xunit[256]; - char yunit[256]; - char zunit[256]; - - int maxval; - - //FILE *fp = fopen(name, "rb"); - // This is very annoying! pgm_readpgm exits on error... - // I will have to write a more fault tolerant routine myself. - //gray **image; - //gray maxval; - //image = pgm_readpgm(fp, &width, &height, &maxval); - //reallocate(); - //fclose(fp); - - FILE *fp = fopen(name, "rb"); - if(fp == NULL) - badfile("Unable to open file \"%s\": %s\n",name,strerror(errno)); - - qmin = 0; - qmax = 65535; - xmin = 0; - xmax = width-1; - ymin = 0; - ymax = height-1; - - sprintf(xunit, "Pixels"); - sprintf(yunit, "Pixels"); - sprintf(zunit, "Gray Value"); - - // Get the first two lines: I always put comments below the image size - if (fgets(buf,sizeof(buf),fp) == NULL) - badfilec("no characters read: empty or short file?"); - if (strncmp(buf, "P5", 2) != 0) - badfilec("wrong magic number %s: only raw pgm files are supported", buf); - if (fgets(buf,sizeof(buf),fp) == NULL) - badfilec("no characters read: empty or short file?"); - while (buf[0] == '#') // ignore any non-spyview comments - fgets(buf,sizeof(buf),fp); - if (sscanf(buf, "%d %d", &width, &height) != 2) - badfilec("error reading width and height from line %s", buf); - - // Allocate the arrays now that we have the width and height - reallocate(); - - // Now get any lines that contain comments - while (true) - { - fgets(buf, 1024, fp); - if (buf[0] != '#') - break; - p = &buf[1]; - while (*p == ' ') p++; - if (parse_pgm_comments("zmin", "%lf", &qmin, p, name)) continue; - if (parse_pgm_comments("zmax", "%lf", &qmax, p, name)) continue; - if (parse_pgm_comments("xmin", "%lf", &xmin, p, name)) continue; - if (parse_pgm_comments("xmax", "%lf", &xmax, p, name)) continue; - if (parse_pgm_comments("ymin", "%lf", &ymin, p, name)) continue; - if (parse_pgm_comments("ymax", "%lf", &ymax, p, name)) continue; - if (parse_pgm_comments("xunit", "%s", xunit, p, name)) continue; - if (parse_pgm_comments("yunit", "%s", yunit, p, name)) continue; - if (parse_pgm_comments("zunit", "%s", zunit, p, name)) continue; - } - xname = xunit; - yname = yunit; - zname = zunit; - - // The next item is the maxval, which should already be in the - // buffer: we need to know if the data is one byte or two. - if (sscanf(buf, "%d", &maxval) != 1) - badfilec("error reading maxval"); - - unsigned char b1; - unsigned char b2; - int data; - // Now lets read the data - for (int i=0; i 255) - { - if (fread(&b2, 1, 1, fp) != 1) - badfilec("short file at pixel %d", i); - data = b1*256+b2; - } - else - data = b1; - raw_data[i] = qmin + 1.0*data*(qmax-qmin)/QUANT_MAX; - } - - store_orig(); - fclose(fp); - data3d = false; - return 0; -} - -int ImageData::parse_pgm_comments(const char *ident, const char *fmt, void *val, char *p, const char *filename) -{ - if (strncmp(p, ident, 3) == 0) - { - p = strchr(p, ' '); - if (strcmp(fmt, "%s") == 0) - { - char *cval = (char *)val; - while (*p == ' ') p++; - strcpy(cval, p); - for(int i = strlen(cval)-1; i > 0 && isspace(cval[i]); i--) - cval[i] = 0; // get rid of blank spaces at the end - return 1; - } - if (sscanf(p, fmt, val) != 1) - badfile( "Invalid %s %s in file %s\n", ident, p, filename); - return(1); - } - return(0); -} - -int ImageData::load_MTX(const char *name) -{ - if (mtx.load_file(name) == -1) return -1; - load_mtx_cut(); - data3d = true; - return 0; -} - -int ImageData::load_GP(const char *name) -{ - if (gpload_type == COLUMNS) - { - if (mtx.load_gp_cols(name) == -1) return -1; - // Good default settings for gp_cols - mtx_index = gp_column; - mtx_cut_type = 0; - do_mtx_cut_title = false; - } - if (gpload_type == INDEX) - { - if (mtx.load_gp_index(name, gp_column) == -1) return -1; - //mtx_index = 0; - //mtx_cut_type = 2; - do_mtx_cut_title = true; - } - - load_mtx_cut(); - data3d = true; - return 0; -} - -int ImageData::load_DAT_meta(const char *name) -{ - int n = mtx.load_dat_meta(name, gp_column); - if (n == -1) - { - warn("Error reading metadata file\n"); - return -1; - } - else if (n == -2) - { - warn("Error reading data file\n"); - return -1; - } - // Why would I set these? - //mtx_index = 0; - //mtx_cut_type = 2; // Range checking should be done in load_mtx_cut(), which it is. - load_mtx_cut(); - data3d = true; - return 0; -} - - -void ImageData::load_mtx_cut() -{ - if (!mtx.data_loaded) - error("load_mtx_cut called with no mtx data loaded!"); - - mtx_cut_type = static_cast(mtx_cut_type % 3); //in case the user set it to an integer instead of using the enums - - //info("loading mtx cut type %d (YZ = 0, XY = 1, XZ = 2)\n", mtx_cut_type); - - if (mtx_index<0) mtx_index = 0; - if (mtx_index > mtx.size[mtx_cut_type]-1) mtx_index = mtx.size[mtx_cut_type]-1; - - int xaxis = (mtx_cut_type+1)%3; - int yaxis = (mtx_cut_type+2)%3; - int zaxis = (mtx_cut_type)%3; - - width = mtx.size[xaxis]; - height = mtx.size[yaxis]; - - //info("xaxis is %d width %d\n", xaxis, width); - //info("yaxis is %d height %d\n", yaxis, height); - - reallocate(); - - //warn( "mtx_cut_type = %d, xaxis = %d, yaxis = %d\n", mtx_cut_type, xaxis, yaxis); - //warn( "width %d height %d\n", width, height); - //warn( "loading index %d type %d\n", mtx_index, mtx_cut_type); - - for (int i=0; ivalue(buf); - Fl::check(); - } - } - - if (strstr(linebuffer, "0 XL") != NULL) - { - //info("found sweep, line %d", nread);getchar(); - if (num_sweeps == -1) // this is the XL line at top of file - { - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - nread += 3; - first_sweep_header = linebuffer; - num_sweeps = 0; - continue; - } - else - { - // if (isnan(sweep_max)) doesn't seem to work under win32? - if (!found_sweep_max) - { - sweep_max = last_sweep; - found_sweep_max = true; - info("settings sweep max to %e from line %d\n", sweep_max, nread+4-1); - } - num_sweeps++; - if (points_per_sweep == -1) - points_per_sweep = num_points; - else if (num_points != points_per_sweep) - badfilec("%d points in sweep %d doesn't match previous value %d\nline number %d\n", - num_points, num_sweeps, points_per_sweep, nread); - num_points = 0; - - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - if (fgets(linebuffer, LINESIZE, fp) == NULL) break; - nread+=3; - last_sweep_header = linebuffer; - - if (num_sweeps == 1) - second_sweep_header = last_sweep_header; - - continue; - } - - } - - if (strchr("#\n\r",linebuffer[0]) != NULL) - continue; - - //if (sscanf(linebuffer, "%*f\t%lf\t%lf", &last_sweep, &last_data) != 2) - last_data = parse_reading(linebuffer, gp_column); - if (isnan(last_data)) - { - //info("line\n%s\ncgp_column %d\nval %e\n", linebuffer, gp_column, last_data); - badfilec("invalid data in delft file at line %d\nline: %s\n", nread, linebuffer); - } - - data.push_back(last_data); - if (num_points == 0) sweep_min = last_sweep; - num_points++; - } - - if (mtx.progress_gui) - mtx.close_progress_gui(); - - num_sweeps++; - if (num_points != points_per_sweep) - { - info("Incomplete last sweep: \n" - "%d points in sweep %d doesn't match previous value %d\n", - num_points, num_sweeps, points_per_sweep); - num_sweeps--; - } - - - info("points_per_sweep %d num_sweeps %d\n", points_per_sweep, num_sweeps); - - unsigned int i,j; - i = first_sweep_header.find("sw=", 0); - j = first_sweep_header.find("D1", i); - - string sweepname = first_sweep_header.substr(i+3,j-i-4); - - info("i %d j %d sweepname set to _%s_", i, j, sweepname.c_str()); - - info("\n\n%s%s%s\n", - first_sweep_header.c_str(), - second_sweep_header.c_str(), - last_sweep_header.c_str()); - - height = points_per_sweep; - width = num_sweeps; - reallocate(); - - info("data " _STF " w*h %d\n", data.size(), width*height); - - //for (int i=0; i data; - - char linebuffer[LINESIZE]; - char *p; - - double datatmp; - - char sep[] = " \t\n\r"; - - FILE *fp = fopen(name, "rb"); - if(fp == NULL) - badfile("Unable to open file \"%s\": %s\n",name,strerror(errno)); - - row = col = w = h = 0; - - while (1) - { - if (fgets(linebuffer, LINESIZE, fp) == NULL) - break; - - // Figure out what kind of line this is - for(p = linebuffer; *p != 0 && isspace(*p); p++) - ; - - if(*p == '\n' || *p == 0 || *p == '#') - continue; - - col = 0; - p = strtok(linebuffer, sep); - while (p != NULL) - { - if (sscanf(p, "%lf", &datatmp) != 1) - warn( "load_DAT: invalid data at row %d col %d: \"%s\", copying last read value\n", row, col, p); - data.push_back(datatmp); - col++; - p = strtok(0, sep); - } - - if (row == 0) - w = col; - else if (w != col) - { - if (col == 0) - break; // ignore empty lines at the end. - if(col < w) // This row is too short - { - warn( "number of columns %d at row %d does not match width of previous rows (%d)\n", col, row, w); - double d = 0; // This is used for ZERO; Mean updates the value so they can share insertion code. - switch(incorrect_column) - { - case EXIT: - exit(-1); - case COPY_ADJACENT: - d = data[data.size()]; - for (int i=0; i < (w-col); i++) - data.push_back(d); - break; - case DROP: - data.erase(data.begin()+(row*w),data.end()); - row--; - break; - case FILL_MEAN: - for(int i = 0; i < col; i++) - d += data[row*w + i]; - d = d / col; - case FILL_ZERO: // Warning! Falling case! - assert(col < w); - for(int i = 0; i < (w-col); i++) - data.push_back(d); - break; - default: - badfilec( "Invalid setting for incorrect_column width: %c\n",incorrect_column); - } - } - else // This row is too long - { - switch(incorrect_column) - { - case EXIT: - badfilec( "number of columns %d at row %d does not match width of previous rows (%d)\n", col, row, w); - case COPY_ADJACENT: - case FILL_ZERO: // Warning! Falling case! - case FILL_MEAN: - warn( "number of columns %d at row %d does not match; fill_mean and fill_zero no ready yet for this case.\n",col,row); - warn( "dropping column."); - while(col > w) - { - data.pop_back(); - col--; - } - break; - case DROP: - data.erase(data.begin(),data.begin()+(row*w)); - row = 0; - w = col; - break; - default: - badfilec( "Invalid argument for -i: %c\n",incorrect_column); - } - - } - - } - row++; - assert((int)data.size() == row * w); - } - h = row; - - fclose(fp); - - width = w; - height = h; - reallocate(); - - for (int i=0; i rawmax) rawmax = raw_data[i]; - } -} - -void ImageData::quantize() -{ - if (auto_quant) - { - find_raw_limits(); - qmin = (rawmin+rawmax)/2 - (rawmax-rawmin)/2/auto_quant_percent*100; - qmax = (rawmin+rawmax)/2 + (rawmax-rawmin)/2/auto_quant_percent*100; - } - - for (int i=0; i0) v1 = fabs(epsilon); - else v1 = fabs(epsilon); - } - v2 = pow(v1, gamma); - //if (!isfinite(v2)) - //info("v1 %e v2 %e eps %e\n", v1, v2, epsilon); - if (isnan(v2)) - raw_data[i] = 0; - else - raw_data[i] = v2; - - } -} - -// calculate a 2D histogram of the dataset -// For each x-value, tranform the y axis of the dataset into a histogram of the measured datavalues - -void ImageData::hist2d(double dmin, double dmax, int num_bins) -{ - int new_height = num_bins; - int histogram[new_height]; - double tmp; - int i,j; - - // never shrink the arrays (leads to segfaults somewhere...) - double *new_data; - if (width * new_height > orig_width*orig_height) - new_data = new double[width*new_height]; - else - new_data = new double[orig_width*orig_height]; - - for (i=0; i= 0 && tmp < new_height) - histogram[(int)tmp]++; - } - for (j=0; j orig_width*orig_height) - new_data = new double[new_width*new_height]; - else - new_data = new double[orig_width*orig_height]; - - double x_step = (double)width/(double)new_width; - double y_step = (double)height/(double)new_height; - - for (int j=0; j max) min = max; - } - for (int i=0; i min && raw_data[i] < max) - threshold_reject[i] = 0; - else - threshold_reject[i] = 1; - } - } - - // The more difficult ones: thresholds based on percentages for a - // given row or column - - else if (type == 1) - { - vector line_data; - for (int j=0; j bottom_limit && raw(i,j) < top_limit) - line_data.push_back(raw(i,j)); - find_threasholds(line_data, low, high, min, max); - for (int i=0; i min && raw(i,j) < max) - threshold_reject[j*width+i] = 0; - else - threshold_reject[j*width+i] = 1; - } - } - } - else //if (type == 2) - { - vector col_data; - for (int i=0; i bottom_limit && raw(i,j) < top_limit) - col_data.push_back(raw(i,j)); - find_threasholds(col_data, low, high, min, max); - for (int j=0; j min && raw(i,j) < max) - threshold_reject[j*width+i] = 0; - else - threshold_reject[j*width+i] = 1; - } - } - } -} - -// A handy simple way to calculate threasholds for things like line -// cuts. Note that you have to put the data first into an STL -// container. It is more expensive, though. - -void ImageData::find_threasholds(vector data, - double bottom_percent, double top_percent, - double &low, double &high) -{ - if (bottom_percent < 0) bottom_percent = 0; - if (bottom_percent > 100) bottom_percent = 100; - - if (top_percent < 0) top_percent = 0; - if (top_percent > 100) top_percent = 100; - - sort(data.begin(), data.end()); - int low_index = (int) (data.size()*bottom_percent/100.0); - int high_index = (int) (data.size()*(100-top_percent)/100.0-1); - low = data[low_index]; - high = data[high_index]; -} - -// A function which calculates threasholds for the whole image using -// the same truncation method we use to calculate the histogram, which -// should be faster than putting the whole dataset in an stl container -// and sorting it. - -void ImageData::find_image_threasholds(double bottom_percent, double top_percent, - double &low, double &high) -{ - int levels = 1000; - int histogram[levels]; - - double tmp; - int i; - int lowint, highint; - int count; - - find_raw_limits(); - - if (bottom_percent < 0) bottom_percent = 0; - if (bottom_percent > 100) bottom_percent = 100; - - if (top_percent < 0) top_percent = 0; - if (top_percent > 100) top_percent = 100; - - for (i=0; i levels) - { - info("tmp is %g \n", tmp); - } - histogram[(int)tmp]++; - } - - count = 0; - for (lowint=0; lowint bottom_percent/100.0*width*height) break; - } - low = rawmin + lowint*(rawmax-rawmin)/levels; - - count = 0; - for (highint=levels-1; highint>=0; highint--) - { - count += histogram[highint]; - if (count > top_percent/100.0*width*height) break; - } - high = rawmin + highint*(rawmax-rawmin)/levels; - - info("image threashold: min %e max %e\n", low, high); -} - -void ImageData::remove_lines(int start, int nlines) -{ - for (int y = start; y < height - nlines; y++) - memcpy(raw_data+y*width, raw_data+(y+nlines)*width, sizeof(double)*width); - double new_ymin = getY(height-nlines); - height = height-nlines; - ymin = new_ymin; -} - -void ImageData::lbl(double bp, double tp, - bool whole_image_threashold, bool percentiles, - double bottom_limit, double top_limit) -{ - double line_average; - int navg; - - int type; - - if (percentiles & whole_image_threashold) - type = 0; - else if (percentiles) - type = 1; - else //if (!percentiles) - type = 3; - - calculate_thresholds(type, bp, tp, bottom_limit, top_limit); - double offset; - - for (int j=0; j height || pos < 0) - return; - for(int i = 0; i < width; i++) - raw(i,pos)=0; - if(pos-1 >= 0) - { - for(int i = 0; i < width; i++) - raw(i,pos)=raw(i,pos)+raw(i,pos-1); - cnt++; - } - if(pos+1 < height) - { - for(int i = 0; i < width; i++) - raw(i,pos)=raw(i,pos)+raw(i,pos+1); - cnt++; - } - if(cnt > 1) - for(int i = 0; i < width; i++) - raw(i,pos) = raw(i,pos)/cnt; - } - else - { - if(pos > width || pos < 0) - return; - for(int i = 0; i < height; i++) - raw(pos,i)=0; - if(pos-1 >= 0) - { - cnt++; - for(int i = 0; i < height; i++) - raw(pos,i)=raw(pos,i)+raw(pos-1,i); - } - if(pos+1 < width) - { - cnt++; - for(int i = 0; i < height; i++) - raw(pos,i)=raw(pos,i)+raw(pos+1,i); - } - if(cnt > 1) - for(int i = 0; i < height; i++) - raw(pos,i) = raw(pos,i)/cnt; - } -} -void ImageData::sub_linecut(bool horizontal, int pos) -{ - if(horizontal) - { - if(pos >= height || pos < 0) - return; - for(int j = 0; j < height; j++) - for(int i = 0; i < width; i++) - if (j != pos) raw(i,j) -= raw(i,pos); - for(int i = 0; i < width; i++) - raw(i,pos) = 0; - } - else - { - if(pos >= width || pos < 0) - return; - for(int i = 0; i < width; i++) - for(int j = 0; j < height; j++) - if (i != pos) raw(i,j) -= raw(pos,j); - for(int j = 0; j < height; j++) - raw(pos, j) = 0; - } -} - -void ImageData::norm_lbl() -{ - double min, max; - for (int j=0; j max) max = raw(i,j); - } - for (int i=0; i max) max = raw(i,j); - } - for (int j=0; j low && val < high) - { - Zavg += (double) val; - Xavg += (double) (x-width/2); - Yavg += (double) (y-height/2); - sXZ += (double) val * (x-width/2); - sYZ += (double) val * (y-height/2); - sXX += (double) (x-width/2)*(x-width/2); - sYY += (double) (y-height/2)*(y-height/2); - N++; - } - } - } - - Xavg /= N; - Yavg /= N; - Zavg /= N; - - a = (sXZ - N*Xavg*Zavg)/(sXX - N*Xavg*Xavg); - b = (sYZ - N*Yavg*Zavg)/(sYY - N*Yavg*Yavg); - c = Zavg - a*Xavg - b*Yavg; - - for (int x=0; x= 0) - { - avg1 += raw(i-m,j); - n++; - } - if (n>0) avg1 = avg1/n; - // If our next point deviates from the average by enough, then we've got switch - if (fabs(raw(i,j)-avg1) > threshold) - { - // Calculate the average for the next "avgwin" points too, and ignore subsequent points that might be a switch - avg2 = offset; n = 1; - for (m=0; m<=avgwin; m++) - if (i+m < width && fabs(raw(i+m,j)+offset-raw(i,j)) < threshold) - { - avg2 += raw(i+m,j) + offset; - n++; - } - avg2 = avg2/n; - avg2 = raw(i,j); - offset += avg1 - avg2; - raw(i,j) += avg1 - avg2; - } - } - } -} - - -void ImageData::xderv() -{ - int w = width-1; - int h = height; - - double xstep = (xmax - xmin)/w; - - for (int j=0; j width-1) left = left % (width); - if (right > width-1) right = right % (width); - if (upper > height-1) upper = upper % (height); - if (lower > height-1) lower = lower % (height); - - if (left < 0) left = left + (-left/width+1)*width - 1; - if (upper < 0) upper = upper + (-upper/height+1)*height - 1; - if (right <= 0) right = right + (-right/width+1)*width; - if (lower <= 0) lower = lower + (-lower/height+1)*height; - - // Now check that things make sense - // Modified April 2010 -- the below crashed if right was at edge already. - if (lower < upper) - std::swap(upper,lower); - if (right < left) - std::swap(left,right); - - // Finally, make sure that we aren't cropping to nothing. - if(lower == upper) - if(upper > 0) - upper--; - else - lower++; - if(left == right) - if(left > 0) - left--; - else - right++; - - int w = (right-left); - int h = (lower-upper); - - for (int j=0; jymax) ? (raw(i,j+1) - raw(i,j)) : (raw(i,j) - raw(i,j+1)); - - ymin = ymin+(ymax-ymin)/height/2; - ymax = ymax-(ymax-ymin)/height/2; - width = w; - height = h; -} - -void ImageData::ederv(double pscale, double nscale) -{ - int w = width; - int h = height-1; - int h0 = -ymin * h / (ymax - ymin); - printf("ymin is %g, ymax is %g, h is %d, h0 is %d\n",ymin,ymax,h,h0); - for (int j=0; jymax) ? (raw(i,j+1) - raw(i,j)) : (raw(i,j) - raw(i,j+1))) * sign; - if(raw_data[j*w+i] < 0) - raw_data[j*w+i] *= nscale; - else - raw_data[j*w+i] *= pscale; - } - - ymin = ymin+(ymax-ymin)/height/2; - ymax = ymax-(ymax-ymin)/height/2; - width = w; - height = h; -} - -void ImageData::grad_mag(double axis_bias) -{ - printf("%g bias\n",axis_bias); - int w = width; - int h = height; - double *tmpx = (double *)malloc(sizeof(double) * width * height); - - memcpy(tmpx,raw_data,sizeof(double)*width*height); - xderv(); - width = w; - height = h; - swap(tmpx,raw_data); - yderv(); - width = w; - height = h; - double *result = (double *)malloc(sizeof(double) * (width-1) * (height-1)); - for(int x = 0; x < width-1; x++) - for(int y = 0; y < height-1; y++) - { - double g1 = tmpx[x+(width-1)*y]; - double g2 = raw_data[x+width*y]; - result[x+(width-1)*y] = sqrt(g1*g1*(1.0-axis_bias)+g2*g2*axis_bias); - } - memcpy(raw_data,result,sizeof(double)*(width-1)*(height-1)); - free(result); - free(tmpx); - width = width-1; - height = height-1; -} - -void ImageData::equalize() // Hist. eq.. We work on the quantized data here for simplicity. -{ - quantize(); - int cumsum[QUANT_MAX+1]; - int mapping[QUANT_MAX+1]; - - // Generate the cumulative sum. - memset(cumsum, 0, sizeof(cumsum)); - int *p = quant_data; - for(int i = 0; i < width*height; i++) - { - assert(*p <= QUANT_MAX && *p >= 0); - cumsum[*p++]++; - } - for(int i = 1; i <= QUANT_MAX; i++) - cumsum[i] += cumsum[i-1]; - - // Find the minimum value. - int minval = -1; - for(int i = 0; i <= QUANT_MAX; i++) - if(cumsum[i] != 0) - { - minval = cumsum[i]; - break; - } - assert(minval >= 0); - - // Generate the mapping; see http://en.wikipedia.org/wiki/Histogram_equalization - for(int i = 0; i <= QUANT_MAX; i++) - { - mapping[i]=round((1.0*cumsum[i]-1.0*minval)*(QUANT_MAX*1.0)/(1.0*width*height-1.0*minval)); - } - - // Apply the mapping using an extra-clever linear interpolation on the floating point data! Yay! - for(int i = 0; i < width*height; i++) - { - double raw = raw_data[i]; - double v = 1.0*(raw-qmin)*QUANT_MAX/(qmax-qmin); - assert(v >= 0 && floor(v) < QUANT_MAX); - double dv = v-floor(v); - assert(dv >= 0); - assert(dv <= 1.0); - double quant = mapping[(int)v]*(1.0-dv)+mapping[(int)(v+0.5)]*dv; - raw_data[i] = quant_to_raw(quant); - } -} - -void ImageData::dderv(double theta) // theta in degrees! -{ - int w = width; - int h = height; - double *tmpx = (double *)malloc(sizeof(double) * width * height); - - memcpy(tmpx,raw_data,sizeof(double)*width*height); - xderv(); - width = w; - height = h; - swap(tmpx,raw_data); - yderv(); - width = w; - height = h; - double *result = (double *)malloc(sizeof(double) * (width-1) * (height-1)); - double t1=cos(theta*M_PI/180.0); - double t2=sin(theta*M_PI/180.0); - for(int x = 0; x < width-1; x++) - for(int y = 0; y < height-1; y++) - { - double g1 = tmpx[x+(width-1)*y]; - double g2 = raw_data[x+width*y]; - result[x+(width-1)*y] = g1*t1+g2*t2; - } - memcpy(raw_data,result,sizeof(double)*(width-1)*(height-1)); - free(result); - free(tmpx); - width = width-1; - height = height-1; -} - - -void ImageData::make_lowpass_kernel(double *data, double dev, int size, ImageData::lowpass_kernel_t type) -{ - double center = floor(size/2.0); - double sum = 0.0; - for(int i = 0; i < size; i++) - { - double dx = (static_cast(i)-center); - dx /= dev; - double y; - switch(type) - { - case LOWPASS_GAUSS: - y = exp(-(dx*dx)/(2.0)); - break; - case LOWPASS_EXP: - y = exp(-fabs(dx)*sqrt(2.0)); - break; - case LOWPASS_LORENTZ: - // Lorentzian has no std. dev, so set FWHM = sigma - y = 1.0/(dx*dx+1.0); - break; - case LOWPASS_THERMAL: // Derivative of Fermi function; dev is temperature in pixels - y = exp(dx)/(dev*(1+exp(dx))*(1+exp(dx))); - break; - default: - assert(0); - } - sum += y; - data[i] = y; - } - sum = 1.0/sum; - for(int i = 0; i < size; i++) - data[i] *= sum; -} - -// This executes a gaussian blur low pass filter -void ImageData::lowpass(double xsize, double ysize, ImageData::lowpass_kernel_t type, double mult) -{ - int kernel_size; - double sum; - - if (xsize == 0 && ysize == 0) - return; - - kernel_size = xsize*mult; - if (kernel_size > 0 && kernel_size < mult) kernel_size = mult; - - if (kernel_size > 0) - { - // For really big images, I think it is better not to reallocate an entire 2D image array (?) - double filtered[width]; - double kernel[kernel_size]; - make_lowpass_kernel(kernel, xsize, kernel_size,type); - int kernel_offset = -kernel_size/2; - - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - sum = 0.0; - for(int k = 0; k < kernel_size; k++) - { - int nx = x + k + kernel_offset; - if(nx < 0) nx = 0; - if(nx >= width) nx = width-1; - sum += kernel[k]*raw(nx,y); - } - filtered[x] = sum; - } - memcpy(&raw(0,y), filtered, sizeof(double)*width); - } - } - - kernel_size = ysize*mult; - - if (kernel_size > 0 && kernel_size < mult) kernel_size = mult; - - if (kernel_size > 0) - { - double filtered[height]; - double kernel[kernel_size]; - make_lowpass_kernel(kernel, ysize, kernel_size,type); - int kernel_offset = -kernel_size/2; - - for(int x = 0; x < width; x++) - { - for(int y = 0; y < height; y++) - { - sum = 0.0; - for(int k = 0; k < kernel_size; k++) - { - int ny = y + k + kernel_offset; - if(ny < 0) ny = 0; - if(ny >= height) ny = height-1; - sum += kernel[k]*raw(x,ny); - } - filtered[y] = sum; - } - for(int y = 0; y < height; y++) - raw(x,y) = filtered[y]; // can't use memcpy here - } - } -} - -// This could be made much more memory efficent if need be; see lowpass. -void ImageData::highpass(double xsize, double ysize, double passthrough, ImageData::lowpass_kernel_t type, double mult) -{ - double *d2 = new double[width*height]; - assert(d2); - memcpy(d2,raw_data,sizeof(double)*width*height); - lowpass(xsize,ysize,type,mult); - for(int x = 0; x < width; x++) - for(int y = 0; y < height; y++) - raw(x,y)=d2[y*width+x]-(1.0-passthrough)*raw(x,y); - delete[] d2; -} - -void ImageData::notch(double xlow, double xhigh, double ylow, double yhigh, double mult) // width is width of mask to use measured in units of xsize, ysize -{ - lowpass(xlow,ylow,LOWPASS_GAUSS,mult); - highpass(xhigh,yhigh,0.0,LOWPASS_GAUSS,mult); -} - -// Despeckle an image with a median filter -// Helper functions -inline static int median_3(double a, double b, double c) -{ - if(((a <= b) && (b <= c)) || ((c <= b) && (b <= a))) - return b; - if(((b <= c) && (c <= a)) || ((a <= c) && (c <= b))) - return c; - return a; -} -static int compare_doubles(const void *ap, const void *bp) -{ - double a = *reinterpret_cast(ap); - double b = *reinterpret_cast(bp); - if(a < b) - return -1; - if(a == b) - return 0; - return 1; -} -inline static int median_3x3(double *r1, double *r2, double *r3) -{ - double tmp[9]; - memcpy(tmp, r1, sizeof(double)*3); - memcpy(tmp+3, r2, sizeof(double)*3); - memcpy(tmp+6, r3, sizeof(double)*3); - qsort(tmp, 9, sizeof(double), compare_doubles); - return tmp[4]; -} -// Main functions -void ImageData::despeckle(bool d_x, bool d_y) -{ - if(d_x && d_y) - { - double *tmp = new double[width * height]; - memcpy(tmp,raw_data,sizeof(double)*width*height); - for(int x = 1; x < width-1; x++) - for(int y = 1; y < height-1; y++) - raw(x,y) = median_3x3(tmp+(y-1)*width+x-1,tmp+y*width+x-1, tmp+(y+1)*width+x-1); - delete[] tmp; - } - else if(d_x) - { - double tmp[width]; - for(int y = 0; y < height; y++) - { - for(int x = 1; x < (width-1); x++) - tmp[x] = median_3(raw(x-1,y),raw(x,y),raw(x+1,y)); - for(int x = 1; x < (width-1); x++) - raw(x,y) = tmp[x]; - } - } - else if(d_y) - { - double tmp[height]; - for(int x = 0; x < width; x++) - { - for(int y = 1; y < (height-1); y++) - tmp[y] = median_3(raw(x,y-1),raw(x,y),raw(x,y+1)); - for(int y = 1; y < (height-1); y++) - raw(x,y) = tmp[y]; - } - } -} - - -MTX_Data::MTX_Data() -{ - size[0] = size[1] = size[2] = 0; - data_loaded = 0; - progress_gui = true; - delft_raw_units = true; - delft_settings = false; - win = NULL; -} - -MTX_Data::~MTX_Data() -{ - clear(); -} - -void MTX_Data::open_progress_gui() -{ - if (win == NULL) - { - win = new Fl_Double_Window(220,25, "Loading file..."); - win->begin(); - msg = new Fl_Output(0,0,220,25); - msg->color(FL_BACKGROUND_COLOR); - win->end(); - } - win->show(); -} - -void MTX_Data::close_progress_gui() -{ - win->hide(); -} - - -int MTX_Data::load_file(const char *name) -{ - FILE *fp = fopen(name, "rb"); - if(fp == NULL) - badfile("Unable to open file \"%s\": %s\n",name,strerror(errno)); - filename = name; - - char buf[MTX_HEADER_SIZE]; - int i,j,k; - fgets(buf, sizeof(buf), fp); - int bytes = 8; - - char units_header[MTX_HEADER_SIZE]; // 256 characters is not long enough... - int found_units = 0; - - // First read the header information, which include the axis ranges and names - - if (strncmp(buf, "Units", 5) == 0) - { - found_units = 1; - strncpy(units_header, buf, sizeof(buf)); - fgets(buf, sizeof(buf), fp); // fixme ; check for errors here. - } - if (sscanf(buf, "%d %d %d", &size[0], &size[1], &size[2]) != 3) - badfilec("Malformed mtx header: %s", filename.c_str()); - if (sscanf(buf, "%*d %*d %*d %d", &bytes) != 1) - warn( "Legacy mtx file found (%s): assuming double data (bytes = %d)\n", filename.c_str(), bytes); - - clear(); - data = new double [size[0]*size[1]*size[2]]; - data_loaded = 1; - - - bool progress = (size[0]*size[1]*size[2]) > 100*100*100*5; - - int t1 = time(NULL); - - if (progress && progress_gui) - { - open_progress_gui(); - msg->value("Reading file: 0%"); - } - - static char msgbuf[256]; - - // Now actually read the data in from the file - - for (i=0; ivalue(msgbuf); - else - info("%s\r", msgbuf); - } - } - - if (!progress_gui && progress) - info("\n"); - - if (progress_gui && progress) - close_progress_gui(); - - int t2 = time(NULL); - // Output timing info here if you want - - if (found_units) - { - char *p = strtok(units_header, ","); - p = strtok(0, ","); - while (isspace(*p)) p++; - dataname = p; - for (int i = 0; i<3; i++) - { - p = strtok(0, ","); - while (isspace(*p)) p++; - axisname[i] = p; - p = strtok(0, ","); - while (isspace(*p)) p++; - sscanf(p, "%lf", &axismin[i]); - p = strtok(0, ","); - while (isspace(*p)) p++; - sscanf(p, "%lf", &axismax[i]); - } - } - else - { - dataname = "Data Value"; - axismin[0] = axismin[1] = axismin[2] = 0; - axismax[0] = size[0]; axisname[0] = "X"; - axismax[1] = size[1]; axisname[1] = "Y"; - axismax[2] = size[2]; axisname[2] = "Z"; - } - - data_loaded = 1; - fclose(fp); - return 0; -} - - -// Load data from a gnuplot formatted files into a 3D matrix. -// Here, we use the index number as the third dimensiont of the 3d matrix. -// The user must specify which column of the gnuplot file the data should be read from. - -int MTX_Data::load_gp_index(const char *name, int colnum) -{ - vector datavec; - double datatmp; - char linebuffer[LINESIZE]; - char *p; - - - char sep[] = " \t\n\r"; - - FILE *fp = fopen(name, "rb"); - if(fp == NULL) - badfile("Unable to open file \"%s\": %s\n",name,strerror(errno)); - - int lines_per_block; // size of the datablocks - int line; - - int blocks_per_index; - int block; - - int num_indices; - - bool first_block = true; - bool first_index = true; - - line = lines_per_block = 0; - block = blocks_per_index = 0; - num_indices = 0; - - int nread = 0; - bool block_ended = false; - bool index_ended = false; - int nptread = 0; - - bool found_data; - - int t1 = time(NULL); - if (progress_gui) - { - open_progress_gui(); - msg->value("Lines read: 0"); - } - - while (1) - { - nread++; - if (fgets(linebuffer, LINESIZE, fp) == NULL) - break; - - // Figure out what kind of line this is - // Get rid of spaces at beginning of line - for(p = linebuffer; *p != 0 && isspace(*p); p++) - ; - // Ignore comment lines - if(*p == '#') - continue; - // A blank line signals the end of a datablock or of an index - if (*p == '\n' || *p == 0) - { - if (!block_ended) // We have reached the end of a block - { - if (first_block) //we found the end of the first block - { - if (line == 0) //ignore blank lines at the top of the file - continue; - lines_per_block = line; - first_block = false; - } - if (line != lines_per_block) - { - info("block %d ended early, assuming incomplete file\n"); - break; - } - //badfilec( "block %d at line %d has %d lines < %d\n", - //block, nread, line, lines_per_block); - line = 0; - block_ended = true; - block++; - continue; - } - if (!index_ended) // this means we have found two blank lines - { - if (first_index) - { - blocks_per_index = block; - first_index = false; - } - if (block != blocks_per_index) - badfilec( "index %d at line %d has %d blocks < %d\n", - num_indices, nread, block, blocks_per_index); - block = 0; - index_ended = true; - num_indices++; - continue; - } - else //discard any addional blank lines after we finish an index - continue; - } - - // This line contains real data - index_ended = block_ended = false; - - // Parse the line and perform the conversions - int col = 0; - found_data = false; - p = strtok(linebuffer, sep); - while (p != NULL) - { - if (sscanf(p, "%lf", &datatmp) != 1) - warn("mtx gnuplot: invalid data at line %d col %d: \"%s\", copying last read value\n", nread, col, p); - if (col == colnum) - { - datavec.push_back(datatmp); - found_data = true; - break; - } - col++; - p = strtok(0, sep); - } - - if (!found_data) - badfile( "Failed to find data in column %d at line %d", colnum, nread); - nptread++; - line++; - - if (nread%100 == 0) - { - static char buf[256]; - snprintf(buf, sizeof(buf), "Lines read: %d", nread); - if (progress_gui) - { - msg->value(buf); - Fl::check(); - } - else - info("%s\r", buf); - } - } - - if (progress_gui) - close_progress_gui(); - else - info("\n"); - - fclose(fp); - - int t2 = time(NULL); - - info("points: %d of %d\n", nptread, lines_per_block * blocks_per_index * num_indices); - info("lines: %d of %d\n", line, lines_per_block); - info("blocks: %d of %d\n", block, blocks_per_index); - info("indices: %d\n", num_indices); - - if (blocks_per_index == 0) // if we're still reading the first index... - { - blocks_per_index = block+1; - info("not yet finished the first index, settigns blocks_per_index to %d", blocks_per_index); - } - - //if (nptread < lines_per_block * blocks_per_index * num_indices) - if (block != 0 || line != 0) // we didn't find the end of and index or the end of a line. - { - num_indices++; - int npts_needed = lines_per_block * blocks_per_index * num_indices; - int nadd = npts_needed - nptread; - info("looks like an incomplete file\n"); - info("will assume size is %d, %d, %d", lines_per_block, blocks_per_index, num_indices); - info("read %d data points, need %d\n", nptread, npts_needed); - info("adding %d points with last value found in file %e", nadd, datatmp); - if (nadd > 0) - for (int i = 0; i < nadd ; i++) - datavec.push_back(datatmp); - } - -// info( "lines per block %d blocks per index %d num indices %d\n", lines_per_block, blocks_per_index, num_indices); - -// info("Number of points read: %d\n", nptread); -// info("Number of points expe: %d\n", lines_per_block * blocks_per_index * num_indices); -// info("Lines per block: %d\n", lines_per_block); -// info("Line in last block: %d\n", line); - - if (lines_per_block == 0 || blocks_per_index == 0 || num_indices == 0) - return -1; - - // When loading data linearly into MTX matrix from gnuplot3d format, we get the following data ordering: - // X = loop 2 = index nimber - // Y = loop 1 = block - // Z = sweep = point number - - size[0] = lines_per_block; - size[1] = blocks_per_index; - size[2] = num_indices; - - if (size[0]*size[1]*size[2] == 0) - { - info("file has no complete lines\n"); - return -1; - } - - clear(); - data = new double [size[0]*size[1]*size[2]]; - data_loaded = 1; - - for (int k=0; k datavec; - double datatmp; - char linebuffer[LINESIZE]; - char *p; - - char sep[] = " \t\n\r"; - - FILE *fp = fopen(name, "rb"); - if(fp == NULL) - badfile("Unable to open file \"%s\": %s\n",strerror(errno)); - - int col; - int cols_per_line; - - int line; - int lines_per_block; - - int num_blocks; // number of datablocks so far (note: we count - // indexes (ie. blocks separated by two blank - // lines) also as datablocks - - bool first_line = true; - bool first_block = true; - - col = cols_per_line = 0; - line = lines_per_block = 0; - num_blocks = 0; - - int nread = 0; - - int t1 = time(NULL); - if (progress_gui) - { - open_progress_gui(); - msg->value("Lines read: 0"); - } - - while (1) - { - nread++; - if (fgets(linebuffer, LINESIZE, fp) == NULL) - break; - - // Figure out what kind of line this is - - // Get rid of spaces at beginning of line - for(p = linebuffer; *p != 0 && isspace(*p); p++) - ; - - // Ignore comment lines - if(*p == '#') - continue; - - // A blank line signals the end of a datablock - if (*p == '\n' || *p == 0) - { - if (line == 0) //ignore blank lines at the top of the file and extra blank lines between blocks - continue; - num_blocks++; - if (first_block) //we found the end of the first block - { - lines_per_block = line; - first_block = false; - } - if (line != lines_per_block) //this is possible if the dataset is not done yet, so we'll be nice and not exit - { - info("Block size does not match on datablock %d (line %d)! Ending file read and discarding block.\n", num_blocks, nread); - num_blocks--; - break; - } - line = 0; - continue; - } - - // Parse the line and perform the conversions - col = 0; - p = strtok(linebuffer, sep); - while (p != NULL) - { - if (sscanf(p, "%lf", &datatmp) != 1) - info("mtx gnuplot: invalid data at line %d col %d: \"%s\", copying last read value\n", nread, col, p); - datavec.push_back(datatmp); - col++; - if (!first_line && col == cols_per_line) - break; - p = strtok(0, sep); - } - if (first_line) - { - first_line = false; - cols_per_line = col; - //info( "gp_cols: found %d columns\n", cols_per_line); - } - line++; - - if (nread%100 == 0) - { - static char buf[256]; - snprintf(buf, sizeof(buf), "Lines read: %d", nread); - if (progress_gui) - { - msg->value(buf); - Fl::check(); - } - else - info("%s\r", buf); - } - - // We will ignore extra columns, but we will be cowardly and exit if - // we don't find enough columns - if (col < cols_per_line) - { - info("Too few columns at line %d, assuming incomplete file\n", nread); - break; - } - } - - fclose(fp); - - if (progress_gui) - close_progress_gui(); - else - info("\n"); - - // info( "gp_cols: cols_per_line %d lines_per_block %d num_blocks %d\n", - // cols_per_line, lines_per_block, num_blocks); - - int t2 = time(NULL); - - //info("Read %d lines at %.3f thousand lines per second\n", nread, 1.0*nread/(t2-t1)/1e3); - - size[0] = cols_per_line; - size[1] = lines_per_block; - size[2] = num_blocks; - - if (size[0]*size[1]*size[2] == 0) - { - warn("file has no complete lines\n"); - return -1; - } - - clear(); - data = new double [size[0]*size[1]*size[2]]; - data_loaded = 1; - - for (int k=0; k 100*100*100*5; - static char msgbuf[256]; - if (progress && progress_gui) - { - open_progress_gui(); - msg->value("Reading file: 0%"); - } - - double val, last_val; - val = last_val = 0; - int lnum = 0; // line number - int npoints = 0; - bool incomplete = false; - - int i,j,k; - int i0, j0, k0; - - // In test file from Vincent, the meta.txt code is getting the wrong order? - // for (k=0; k=0; j--) // flip y data around in matrix... - { - for (k=0; kvalue(msgbuf); - else - info("%s\r", msgbuf); - } - } - } - } - fclose(fp); - return 0; -} diff --git a/spyview/ImageData.H.~1.56.~ b/spyview/ImageData.H.~1.56.~ deleted file mode 100644 index 56b18f8..0000000 --- a/spyview/ImageData.H.~1.56.~ +++ /dev/null @@ -1,480 +0,0 @@ -#ifndef ImageData_H -#define ImageData_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include "message.h" - -#define QUANT_MAX 65535 - -// Checking array limits will help debugging but will increase the -// execution time. I have benchmarked this by calling load_file() on a -// 1x801x601 mtx (which load the YZ cut by default), and then -// reloading the YZ cut. Without limit checking, the excution time as -// 0.299s. With limit checking, it was 0.370s. - -#define CHECK_ARRAY_LIMITS 0 - -using namespace std; - -typedef enum { YZ = 0, XY = 2, XZ = 1 } mtxcut_t; -typedef enum { COLUMNS = 0, INDEX = 1} gpload_t; -typedef enum { DROP = 'd', FILL_MEAN = 'm', FILL_ZERO = 'z', EXIT = 'x', COPY_ADJACENT = 'a'} incorrect_column_t; -typedef enum { MATRIX = 0, GNUPLOT = 1, DELFT_LEGACY = 2, DAT_META = 3} datfile_t; -typedef enum { PGM = 0, MTX = 1, DAT = 2} fallbackfile_t; - -class MTX_Data -{ - -public: - - string filename; - double *data; - string axisname[3]; - string dataname; - int size[3]; - double axismin[3]; // the ranges for the x, y, and z axes - double axismax[3]; // the ranges for the x, y, and z axes - bool data_loaded; - bool data3d; - bool parse_txt; - bool delft_raw_units; - bool progress_gui; - bool delft_settings; - - string settings; - - MTX_Data(); - ~MTX_Data(); - - int load_file(const char *name); - int load_gp_index(const char *name, int col); - int load_gp_cols(const char *name); - int load_dat_meta(const char *name, int col); - void parse_delft_txt(const char *name, bool columns); - void parse_comments(char *comments, const char *ident, int *dac, int *size, char *name, double *range); - void parse_var2_comments(char *comments, const char *ident, int *dac, char *name, double *range); - void get_settings(const char *name); - - inline double get_coordinate(int axis, int i) - { - axis = axis%3; - if (size[axis] == 1) - return (axismin[axis]+axismax[axis])/2.0; - else - return axismin[axis] + 1.0*i*(axismax[axis]-axismin[axis])/(size[axis]-1); - //return axismin[axis] + 1.0*i*(axismax[axis]-axismin[axis])/(size[axis]); // why not minus one? - }; - - inline double &getData(int i, int j, int k) - { -#if CHECK_ARRAY_LIMITS - if (!data_loaded) - { fprintf(stderr, "MTX data not yet loaded!\n"); exit(-1);} - if (i>=size[0] || i < 0) - { fprintf(stderr, "attempt to access i = %d, size[0] = %d\n", i, size[0]); exit(-1);} - if (j>=size[1] || j < 0) - { fprintf(stderr, "attempt to access j = %d, size[1] = %d\n", j, size[1]); exit(-1);} - if (k>=size[2] || k < 0) - { fprintf(stderr, "attempt to access k = %d, size[2] = %d\n", k, size[2]); exit(-1);} -#endif - return data[k*size[1]*size[0] + j*size[0] + i]; - }; - void clear() { if (data_loaded) delete [] data; data_loaded = 0;}; - - void open_progress_gui(); - void close_progress_gui(); - - Fl_Double_Window *win; - Fl_Output *msg; - -private: -}; - -class ImageData -{ - -public: - - double *orig_data; - double *raw_data; - int *quant_data; - int width, height; - bool *threshold_reject; - - MTX_Data mtx; - - // Keep track of which mtx index and gp column are loaded - mtxcut_t mtx_cut_type; - int mtx_index; - bool do_mtx_cut_title; - gpload_t gpload_type; - int gp_column; - - bool auto_quant; - double auto_quant_percent; - - bool data_loaded; - bool data3d; - - datfile_t datfile_type; - fallbackfile_t fallbackfile_type; - - - double rawmin, rawmax; // the actual min and max of the raw dataset - double qmin, qmax; // the raw values corresponding to 0 and QUANT_MAX - double xmin, xmax; // the values of i=0 and i=width-1 - double ymin, ymax; // the values of j=0 and j=height-1 - - string xname; - string yname; - string zname; - - // We need to keep track of the orignal stuff for the reset() function - int orig_width, orig_height; - double orig_xmin; - double orig_xmax; - double orig_ymin; - double orig_ymax; - string orig_xname; - string orig_yname; - - // Action on incorrect number of columns when reading DAT files - incorrect_column_t incorrect_column; - - // Constructor will not do much by default - ImageData(); - ~ImageData(); - - // Functions for loading new data - - // Copy data from an existing fp matrix - void load_raw(double *data, - int w, int h, - double x1=NAN, double x2=NAN, - double y1=NAN, double y2=NAN); - - // Copy data from an existing int matrix - void load_int(int *data, - int w, int h, - double x1=NAN, double x2=NAN, - double y1=NAN, double y2=NAN, - double z1=NAN, double z2=NAN); - // Reset the data back to the original (for reprocesing data without - // reloading from file) - void reset(); - - // Memory allocation - void clear(); - // reallocated space for arrays according to current width and height - // this is used when we load new data (will clear all arrays) - void reallocate(); - - // So far, we've tried to keep memory allocation to a minimum. This - // has worked so far because all of the image processing stuff that - // changes the size of the datasets _shrink_ the dataset. However, - // with the introduction of the interpolate function, we'll also - // need to make the storage arrays (like quant_data, - // threshold_reject) bigger. This is what this function does (note - // that it will never reallocate them smaller since we need to be - // able to restore the original data). We will leave the work of - // allocating raw_data to the image processing function. - void resize_tmp_arrays(int new_width, int new_height); - - - // Many different functions will support threasholding Using this - // function, and the threshold_reject array, we will unify all of - // these to keep them consistent. It will also simplify the other - // code. - - // Type: 0 = whole image, 1 = line, 2 = column, 3 = data value - void calculate_thresholds(int type, double low, double high, - double bottom_limit=-INFINITY, double top_limit=INFINITY); - - // Generic Load from file (determine filetype from extension) - // Programs using the this class can either use this function - // directly, but can also use the helper function directly - // - // All load functions will return -1 if the file was not succesfully - // loaded. - int load_file(const char *name); - - // Helpers to load data from specific files - int load_STM(const char *name); - int load_PGM(const char *name); - int load_DAT(const char *name); - int load_XL30S_TIF(const char *name); // hacked to read TIF files from XL30S - int load_Delft(const char *name); - // For the following functions, user should set the desired - // mtx_cut_type, mtx_index, gpload_type and gp_column. If they - // change during load (for example if they are out of range), then - // the variables in the class will store the correct value. - // Alternatively, you can use the inline functions below - int load_MTX(const char *name); - int load_GP(const char *name); - // A new function that loads data from a "columns" formatted data - // file with the help of a new metadata file. The metadata file will - // be called "file.meta.txt". It will use gp_column number to pick - // the column. It will load 3D data into an MTX. - int load_DAT_meta(const char *name); - void load_mtx_cut(); - void saveMTX(const char *name); // Write the current image data to an MTX file - - // Some handy functions: - - inline int limit(int A) { if (A<0) return 0; else if (A>QUANT_MAX) return QUANT_MAX; else return A; }; - - inline int raw_to_quant(double raw) {return limit((int)round(1.0*(raw-qmin)*QUANT_MAX/(qmax-qmin)));} - inline double quant_to_raw(double quant) {return qmin + 1.0*quant*(qmax-qmin)/QUANT_MAX;}; - - // Given a pixel coordinate x, return the united coordinate. - inline double getX(double i) {return xmin + ((width==1) ? 0 : 1.0*i*(xmax-xmin)/(width-1));}; - inline double getY(double j) {return ymin + ((height==1) ? 0 : 1.0*(height-1-j)*(ymax-ymin)/(height-1));}; // ymax is flipped - - // Given a united coordinate x, return the un-united. - inline double getX_inv(double x, double zoom=1.0) { return (width==1) ? 0 : (zoom*(x-xmin)/(xmax-xmin)*(width-1)); } - inline double getY_inv(double y, double zoom=1.0) { return (height==1) ? 0 : zoom*(height-1-(y-ymin)/(ymax-ymin)*(height-1)); } - inline double getX_inv(double x, int zoom) { return (width==1) ? 0 : ((zoom > 0 ? zoom : -1.0/zoom)*(x-xmin)/(xmax-xmin)*(width-1)); } - inline double getY_inv(double y, int zoom) { return (height==1) ? 0 : (zoom > 0 ? zoom : -1.0/zoom)*(height-1-(y-ymin)/(ymax-ymin)*(height-1)); } - - // This will rescale the floating point making the old qmin and qmax - // into the new qmin and qmax. This is the equivalent of changing - // the zunit settings in the old setup. - - void rescale_data(double new_qmin, double new_qmax); - - // More convenient functions - - inline void load_mtx_cut(int index) - {mtx_index = index; load_mtx_cut();}; - inline void load_mtx_cut(int index, mtxcut_t type) - {mtx_index = index; mtx_cut_type = type; load_mtx_cut();}; - - inline void load_GP_cols(const char *name) - {gpload_type = COLUMNS; load_GP(name);} - inline void load_GP_index(const char *name, int colnum) - {gpload_type = INDEX; gp_column = colnum; load_GP(name);} - - - // Copy original data back into raw data matrix (saves reloading from file) - inline void reload_orig() { memcpy(raw_data, orig_data, width*height*sizeof(double)); } - - // Quantizing the data - void quantize(); - - // Image Processing Operations on data: - - // Even simpler (inline) functions - - inline void scale_axes(double xscale, double yscale) - { - //info("scale %e %e %e %e %e %e\n", xmin, xmax, ymin, ymax, xscale, yscale); - xmin *= xscale; - xmax *= xscale; - ymin *= yscale; - ymax *= yscale; - //info("scale %e %e %e %e\n", xmin, xmax, ymin, ymax); - } - - inline void offset_axes(double xoff, double yoff) - { - info("off %e %e %e %e %e %e\n", xmin, xmax, ymin, ymax, xoff, yoff); - xmin += xoff; - xmax += xoff; - ymin += yoff; - ymax += yoff; - info("off %e %e %e %e\n", xmin, xmax, ymin, ymax); - } - - // Very simple functions (one liners) - - void log10(bool do_offset, double new_offset);// data[i] = log10(data[i]) for all i - void magnitude();// data[i] = abs(data[i]) for all i, !using z unit! - void neg();// data[i] = -(data[i]) for all i, !using z unit! - void offset(double offset, bool do_auto);// add an offset - void scale(double factor); // scale the data - void gamma(double gamma, double epsilon); // gamma scaling operation on 16 bit data - - // More complicated functions that preserve the images size - - void lbl(double bp=0.0, double tp=0.0, bool whole_image_threashold=false, bool percentiles=true, - double bottom_limit = -INFINITY, double top_limit = INFINITY); // subtract line average from each line - void cbc(double bp=0.0, double tp=0.0, bool whole_image_threashold=false, bool percentiles=true, - double bottom_limit = -INFINITY, double top_limit = INFINITY); // subtract column average from each column - void sub_linecut(bool horizontal, int pos); // Subtract a specific line form each line. - void outlier_line(bool horizontal, int pos); // Remove an outlier line - void norm_lbl(); // Normalize each line individually. - void norm_cbc(); // Normalize each line individually. - void fitplane(double bp=0, double tp=0, bool percentiles=true); // subtract a plane - void plane(double b, double a); // subtract a plane - void xflip(); - void yflip(); - void rotate_cw(); - void rotate_ccw(); - void grad_mag(double bias); // Replace each pixel with the magnitude of the gradient. 0= width || i < 0) - {fprintf(stderr, "attempt to acces i = %d, width = %d\n", i, width); return raw_data[0];} - if (j >= height || j < 0) - {fprintf(stderr, "attempt to acces j = %d, height = %d\n", i, height); return raw_data[0];} -#endif - return raw_data[j*width+i]; - }; - - inline const double &raw(int i, int j) const - { - #if CHECK_ARRAY_LIMITS - if (!data_loaded) - {fprintf(stderr, "Data not loaded!\n"); exit(-1);} - if (i >= width || i < 0) - {fprintf(stderr, "attempt to acces i = %d, width = %d\n", i, width); exit(-1);} - if (j >= height || j < 0) - {fprintf(stderr, "attempt to acces j = %d, height = %d\n", i, height); exit(-1);} -#endif - return raw_data[j*width+i]; - }; - - inline int &quant(int i, int j) - { - #if CHECK_ARRAY_LIMITS - if (!data_loaded) - {fprintf(stderr, "Data not loaded!\n"); exit(-1);} - if (i >= width || i < 0) - {fprintf(stderr, "attempt to acces i = %d, width = %d\n", i, width); exit(-1);} - if (j >= height || j < 0) - {fprintf(stderr, "attempt to acces j = %d, height = %d\n", i, height); exit(-1);} -#endif - return quant_data[j*width+i]; - }; - - - // How cool an idea is this? - // - // Eventually, use bicubic interpolation for the pixels in the middle: - // - // http://www.paulinternet.nl/?page=bicubic - // - // but then bilinear interpolation for ones at the edges. - // - // Start by just using bilinear everywhere...the add the bicubic later. (maybe) - - inline double raw_interp(double x, double y) - { - int i = (int)floor(x); - int j = (int)floor(y); - - if (i<0 || i > width-1 || j < 0 || j > height-1) - { - info("interp outside dataset: %e (%d) %e (%d)\n", x, width-1, y, height-1); - return NAN; - } - - double dx = x-(double)i; - double dy = y-(double)j; - - // The boundary corner - if (i == width-1 && j == height-1) - return raw(i,j); - - // The right edge - if (i == width-1) - return raw(i,j) + (raw(i,j+1)-raw(i,j))*dy; - - // The bottom edge - if (j == height-1) - return raw(i,j) + (raw(i+1,j)-raw(i,j))*dx; - - - // The rest (from wikipedia) - return - ((raw(i,j)) + //b1 - (raw(i+1,j)-raw(i,j))*dx + // b2*x - (raw(i,j+1)-raw(i,j))*dy + // b3*y - (raw(i,j)-raw(i+1,j)-raw(i,j+1)+raw(i+1,j+1))*dx*dy); // b4*x*y - }; - -private: - - // Some internal functions - int parse_pgm_comments(const char *ident, const char *fmt, void *val, char *p, const char *filename); - - inline int check_loaded() { - if (data_loaded == 0) - { - fprintf(stderr, "data accessed before loading! exiting...\n"); - exit(-1); - } - } - - void find_raw_limits(); // find the min/max of the raw data: we - - void find_threasholds(vector data, - double bottom_percent, double top_percent, - double &low, double &high); - void find_image_threasholds(double bottom_percent, double top_percent, - double &low, double &high); - void store_orig(); -}; - - -#endif diff --git a/spyview/ImagePrinter.C.~1.104.~ b/spyview/ImagePrinter.C.~1.104.~ deleted file mode 100644 index 4c2a3db..0000000 --- a/spyview/ImagePrinter.C.~1.104.~ +++ /dev/null @@ -1,1778 +0,0 @@ -#include -#include "ImagePrinter.H" -#include "ImageWindow.H" -#include "ImageWindow_LineDraw.H" -#include "message.h" -#include "throttle.H" -#include -#include -#include "eng.h" -#include -#include - -// Violating all rules of abstraction, but I can't figure our any other way to get access to argv[0] -#include "spyview.H" - -static bool Clip(double &x1,double &y1,double &x2,double &y2, double wx1, double wy1, double wx2, double wy2); -static void setColor(FILE *out, Fl_Color_Chooser *c); - -#ifndef WIN32 -#include -using namespace boost; -using namespace serialization; -using namespace std; -#endif - -static const double INCH=72.0; // Inch in points. -using namespace std; -std::string Image_Printer::settingsDir; - -// Implementation of cohen-sutherland algorithm. -static const int NONE=0; -static const int LEFT=1; -static const int RIGHT=2; -static const int TOP=4; -static const int BOTTOM=8; - -int wx1,wy1,wx2,wy2; - -Image_Printer::Image_Printer(ImageWindow *p_iw, Image_Printer_Control *p_ipc) -{ - iw = p_iw; - ipc = p_ipc; - ipc->ip = this; - ipc->face->value("Palatino"); - ipc->fontsize->value("24"); - width=7; - ipc->height->value("7.0"); - xoff=1; - yoff=1; - boxwidth=4; - tickwidth=4; - ticklength=.25; - zero=1e-15; - xspacing=0; - yspacing=0; - ipc->xscale->value("1.0"); - ipc->yscale->value("1.0"); - ipc->zscale->value("1.0"); - - ipc->xticfmt->value("%.2g"); - ipc->yticfmt->value("%.2g"); - ipc->cticfmt->value("%.2g"); - page_width = 11; - page_height = 8.5; - ipc->landscape->value(1); - ipc->colorbar->value(0); - loadPrintSettings(""); // Load the default settings... - previewFileName = tmpnam(NULL); - previewProc = -1; - - // Some default settings for the preview & formats, in case the - // settings file is not found - ipc->png_dpi->value("300"); -#ifdef WIN32 - ipc->gs_cmd->value("\"c:/Program Files/gs/gs8.64/gswin32c.exe\""); - ipc->preview_cmd->value("\"c:/Programs Files/Ghostgum/gsview/gsview32.exe\""); -#else - ipc->gs_cmd->value("gs"); - ipc->preview_cmd->value("gv --watch"); -#endif - loadPreviewSettings(); -} - -Image_Printer::~Image_Printer() -{ - info("Cleaning up\n"); - -#ifndef WIN32 - if(previewProc != -1) // We're about to unlink the preview ps file. Better kill gs first. - kill(previewProc,SIGTERM); -#endif - - unlink(previewFileName.c_str()); -} - -void Image_Printer::do_extra_conversions(string basename) -{ - string command = ""; - if (ipc->extra_pdf->value()) - { - command = ""; - command = ipc->gs_cmd->value(); - if (ipc->cmyk->value()) - command += " -dProcessColorModel=/DeviceCMYK "; - if (ipc->paper_letter->value()) - command += " -sPAPERSIZE=letter "; - else if (ipc->paper_a4->value()) - command += " -sPAPERSIZE=a4 "; - command += " -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -dEPSCrop "; - command += " -dAutoFilterColorImages=false -dAutoFilterGrayImages=false "; - command += " -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode "; - command += " -sOutputFile=\"" + basename + ".pdf\" \""; - command += basename + ".ps\""; - info("pdf command:\n%s\n",command.c_str()); - // Don't you just love win32? This is pretty obvious, right? - // http://jason.diamond.name/weblog/2005/04/14/dont-quote-me-on-this -#ifdef WIN32 - system(("\""+command+"\"").c_str()); -#else - system(command.c_str()); -#endif - } - if (ipc->extra_png->value()) - { - command = ""; - command = ipc->gs_cmd->value(); - if (ipc->paper_letter->value()) - command += " -sPAPERSIZE=letter "; - else if (ipc->paper_a4->value()) - command += " -sPAPERSIZE=a4 "; - command += " -q -sDEVICE=pngalpha -dBATCH -dNOPAUSE -dEPSCrop "; - command += " -r"; - command += ipc->png_dpi->value(); - command += " -sOutputFile=\"" + basename + ".png\" \""; - command += basename + ".ps\""; - info("png command:\n%s\n",command.c_str()); -#ifdef WIN32 - system(("\""+command+"\"").c_str()); -#else - system(command.c_str()); -#endif - } - if(ipc->extra_svs->value()) - { - savesettings(basename + ".svs"); - } - - if(ipc->extra_set->value()) - { - savePrintSettings(basename + ".set"); - } - info("done\n"); -} - -void Image_Printer::startPreview() -{ -#ifndef WIN32 - if(previewProc != -1) - kill(previewProc,SIGTERM); -#endif - updatePreview(true); -#ifndef WIN32 - previewProc = fork(); -#endif - if(previewProc == 0) // We're the baby - execlp("gv","gv",previewFileName.c_str(),"--watch", NULL); -} - -void Image_Printer::updatePreview(bool first) -{ - static Throttle throttle(this,&Image_Printer::updatePreview, 1.0); - if(!throttle.throttle()) - return; - //reset_time(); - //validatePreviewCmd(); - if (previewFileName.size() == 0) return; - if(!first) - { - if(previewProc == -1) - return; - // If the viewer has quit, exit. - int stat; - int ret = 0; -#ifndef WIN32 - ret = waitpid(previewProc,&stat,WNOHANG); -#endif - if(ret != 0) - { - warn("PS viewer has quit...\n"); - previewProc = -1; - unlink(previewFileName.c_str()); - return; - } - } - char *n = tmpnam(NULL); - - FILE *out = fopen(n,"w"); - print(out,true); - fclose(out); - - // printf("Took %g seconds to generate preview\n",current_time()); - // No need to unlink the old file; rename is guaranteed to do that atomically. - // if (unlink(previewFileName.c_str()) != 0) - // info("error deleteing file \"%s\": %s\n", previewFileName.c_str(), strerror(errno)); - if (rename(n,previewFileName.c_str()) != 0) - info("error renaming file \"%s\" to \"%s\": %s\n", n, previewFileName.c_str(), strerror(errno)); -#ifndef WIN32 - if(!first) - kill(previewProc,SIGHUP); -#endif -} - -double Image_Printer::autospace(double min, double max) -{ - double range = fabs(min-max); - if(range*range == 0) - { - return 1; - } - - double digitsRange = floor(log10(range)); - double rangeMult = (double)pow(10.0,digitsRange); - - double collapsedRange = range/rangeMult; - if(collapsedRange < 2.5) - return .25 * rangeMult; - else if(collapsedRange < 5) - return .5 * rangeMult; - else if(collapsedRange <= 10) - return 1.0 * rangeMult; - warn("Tick Pick Problem... min %e max %e\n", min, max); - return 1.0 * rangeMult; -} - -void Image_Printer::pixelToDevice(double &x, double &y) -{ - double xscale = atof(ipc->xscale->value()); - double yscale = atof(ipc->yscale->value()); - - y = iw->id.getY(y)*yscale; // Why the hell is this right? - // Why does spyview have so many coordinate systems, some of which have 0,0 as top-left, some as bottom-left? - x = iw->id.getX(x)*xscale; - unitToDevice(x,y); -} -void Image_Printer::unitToDevice(double &x, double &y) -{ - double height = atof((ipc->height->value())); - double xscale = atof(ipc->xscale->value()); - double yscale = atof(ipc->yscale->value()); - double xmin = iw->id.getX(img_x1)*xscale; - double xmax = iw->id.getX(img_x2)*xscale; - double ymin = iw->id.getY(img_y1)*yscale; - double ymax = iw->id.getY(img_y2)*yscale; - - double xrange, xoffset, yrange, yoffset; - if (ipc->precise_ticks->value()) - { - xrange=width*(img_xsize-1)/(img_xsize); // xmin is actually 1/2 pixel from the left edge, xmax is 1/2 pixel from the right. - xoffset = width*(0.5/(img_xsize)); - yrange = height*(img_ysize-1)/(img_ysize); - yoffset = height*(0.5/(img_ysize)); - } - else - { - yrange = height; - yoffset = 0; - xrange=width; - xoffset=0; - } - y = yoff + yrange*(y-ymax)/(ymin-ymax) + yoffset; - x = xoff + xrange*(x-xmin)/(xmax-xmin) + xoffset; -} -// void Image_Printer::validatePreviewCmd() -// { -// if(strstr(ipc->preview_cmd->value(),".ps")) -// { -// warn("Overriding apparently inappropriate preview command \"%s\" with default of \"%s\"\n", -// ipc->preview_cmd->value(),defaultPreviewCmd); -// ipc->preview_cmd->value(defaultPreviewCmd); -// } -// } - -void Image_Printer::box(FILE *out, double x, double y, double w, double h) -{ - fprintf(out," %g inch %g inch moveto\n",x,y); - fprintf(out," %g inch 0 rlineto\n",w); - fprintf(out," 0 %g inch rlineto\n",h); - fprintf(out," %g inch 0 rlineto closepath\n",-w); -} -void Image_Printer::pushClip(FILE *out, double xoff, double yoff,double width,double height) -{ - fprintf(out," clipsave\n"); - box(out, xoff,yoff,width,height); - fprintf(out," clip\n"); -} - -/* This function is getting *way* too long and messy. Something needs to be done.. */ -void Image_Printer::print(FILE *out_p, bool preview_p) -{ - preview = preview_p; - out = out_p; - - // initialize some variables - computePlotRange(); - max_ytic_width = 0; // for choosing the offset of the y axix label - max_ctic_width = 0; // for choosing the offset of the colorbar axix label - height = atof((ipc->height->value())); - fontsize = atof(ipc->fontsize->value()); - xscale = atof(ipc->xscale->value()); - yscale = atof(ipc->yscale->value()); - zscale = atof(ipc->zscale->value()); - - write_header(); - - if (ipc->landscape->value() && !ipc->paper_eps->value()) - fprintf(out, "%d 0 translate 90 rotate\n", bb_ur_x ); - - if(ipc->watermark->value()) - write_watermark(); - - draw_image(); - draw_lines(); - - if (ipc->colorbar->value()) - draw_colorbar(); - - draw_axis_tics(); - - // Draw the bounding box - if(boxwidth > 0) - { - fprintf(out,"%% Draw our box around the plot\n"); - setColor(out,ipc->border_color); - fprintf(out," %g setlinewidth newpath\n",boxwidth); - box(out,xoff,yoff,width,height); - fprintf(out," stroke\n"); - } - else - fprintf(out,"%% User requested no box\n"); - - draw_axis_labels(); - - // By defering the bounding box, we now have access to max_ytic_width and max_ctic_width - if (ipc->paper_eps->value()) - { - int label_x = static_cast(- (max_ytic_width+2.5)*fontsize/2.0); - int label_c = static_cast((max_ctic_width+2.5)*fontsize/2.0); - // Tricky part: estimate a nice bounding box for an EPS file - bb_ll_x = (int) (xoff*INCH - (ipc->yaxis_label->value() ? 1 : -1) * fontsize + label_x); - // the y axis tickmark labels are much wider than the x axis are tall - bb_ll_y = (int) (yoff*INCH - (ipc->xaxis_label->value() ? 3 : 2) * fontsize); - if(ipc->colorbar->value()) - bb_ur_x = (int) ((cbar_xoff+cbar_width)*INCH + label_c + (ipc->caxis_label->value() ? fontsize : 0)); - else - bb_ur_x = (int) ((xoff+width)*INCH + fontsize); - bb_ur_y = (int) ((yoff+height)*INCH + (ipc->do_title->value() ? 2 : 1) * fontsize); - } - - if (ipc->dir_stamp->value()) - add_dirstamp(); - - if (preview || !ipc->paper_eps->value()) // If we're using eps, spec says no showpage (adobe maybe disagrees) - fprintf(out,"showpage\n"); - fprintf(out,"grestore\n"); - fprintf(out,"%%%%Trailer\n"); - fprintf(out, "%%%%Actual BoundingBox was: %d %d %d %d\n", bb_ll_x, bb_ll_y, bb_ur_x, bb_ur_y); - fprintf(out,"%%%%EOF\n"); - - info("Label width actual values:\n"); - info("ytic %d ctic %d\n", max_ytic_width, max_ctic_width); - info("%%%%BoundingBox: %d %d %d %d\n", bb_ll_x, bb_ll_y, bb_ur_x, bb_ur_y); -} - -void Image_Printer::updatePlotRange(Image_Printer_Control *ipc) -{ - computePlotRange(); - double xscale = atof(ipc->xscale->value()); - double yscale = atof(ipc->yscale->value()); - - char buf[1024]; - double minx, miny, maxx, maxy; - //int img_x1, img_y1, img_x2, img_y2; // overriding class variables!!!? - switch(ipc->plotRange->value()) - { - case PLOT_ZOOM: - iw->zoom_window->getSourceArea(img_x1, img_y1, img_x2, img_y2); - //falling case! - case PLOT_MANUAL: - minx = iw->xunit(img_x1); - maxx = iw->xunit(img_x2); - miny = iw->yunit(img_y1-1); //strange: why did i need to -1? - maxy = iw->yunit(img_y2-1); - break; - case PLOT_ALL: - default: - minx = iw->xunit(0); - maxx = iw->xunit(iw->w-1); - miny = iw->yunit(0); - maxy = iw->yunit(iw->h-1); - break; - } - minx *= xscale; - miny *= yscale; - maxx *= xscale; - maxy *= yscale; - snprintf(buf,sizeof(buf),"%g,%g",minx,maxx); - ipc->xrange->value(buf); - snprintf(buf,sizeof(buf),"%g,%g",maxy,miny); - ipc->yrange->value(buf); -} - -void Image_Printer::computePlotRange() -{ - double xscale = atof(ipc->xscale->value()); - double yscale = atof(ipc->yscale->value()); - - switch(ipc->plotRange->value()) - { - case PLOT_ALL: - default: - img_x1 = 0; - img_y1 = 0; - img_x2 = iw->w-1; - img_y2 = iw->h-1; - break; - case PLOT_ZOOM: - if(iw->zoom_window) - iw->zoom_window->getSourceArea(img_x1, img_y1, img_x2, img_y2); - else - { - ipc->plotRange->value(PLOT_ALL); - computePlotRange(); - return; - } - break; - case PLOT_MANUAL: - { - double xmin,xmax,ymin,ymax; - if(sscanf(ipc->xrange->value(),"%lg,%lg",&xmin,&xmax) == 2) - { - img_x1 = round(iw->id.getX_inv(xmin / xscale)); - img_x2 = round(iw->id.getX_inv(xmax / xscale)); - if(img_x1 > img_x2) - swap(img_x1,img_x2); - } - else - { - warn("Warning: X Range \"%s\" isn't of the form 1.0,2.0\n",ipc->xrange->value()); - img_x1 = 0; - img_x2 = iw->w-1; - } - if(sscanf(ipc->yrange->value(),"%lg,%lg",&ymax,&ymin) == 2) - { - img_y1 = round(iw->id.getY_inv(ymin / yscale)); - img_y2 = round(iw->id.getY_inv(ymax / yscale)); - if(img_y1 > img_y2) - swap(img_y1,img_y2); - } - else - { - warn("Warning: Y Range \"%s\" isn't of the form 1.0,2.0\n",ipc->yrange->value()); - img_y1 = 0; - img_y2 = iw->h-1; - } - } - } - img_xsize = abs(img_x2-img_x1+1); - img_ysize = abs(img_y2-img_y1+1); -} - -void Image_Printer::updateSettings(Image_Printer_Control *ipc) -{ - char buf[64]; - - snprintf(buf,sizeof(buf),"%g",width); - ipc->width->value(buf); - snprintf(buf,sizeof(buf),"%g",xoff); - ipc->xoff->value(buf); - snprintf(buf,sizeof(buf),"%g",yoff); - ipc->yoff->value(buf); - - snprintf(buf,sizeof(buf),"%g",ticklength); - ipc->ticklength->value(buf); - snprintf(buf,sizeof(buf),"%g",xspacing); - ipc->xspacing->value(buf); - snprintf(buf,sizeof(buf),"%g",yspacing); - ipc->yspacing->value(buf); - - snprintf(buf,sizeof(buf),"%g",boxwidth); - ipc->boxwidth->value(buf); - snprintf(buf,sizeof(buf),"%g",tickwidth); - ipc->tickwidth->value(buf); - updatePlotRange(ipc); - update_page_size(); -} - -void Image_Printer::fetchSettings(Image_Printer_Control *ipc) -{ - width=atof(ipc->width->value()); - xoff=atof(ipc->xoff->value()); - yoff=atof(ipc->yoff->value()); - - ticklength=atof(ipc->ticklength->value()); - xspacing=atof(ipc->xspacing->value()); - yspacing=atof(ipc->yspacing->value()); - - boxwidth=atof(ipc->boxwidth->value()); - tickwidth=atof(ipc->tickwidth->value()); - - updatePreview(); -} - -void Image_Printer::update_page_size(int type) -{ - // This is a pain in the ass because in FLTK, the status of the - // other radio buttons is not updated until after the callback is - // executed: during the callback, two radio buttons could both be - // "1" at the same time... - - if (type == -1 && ipc->paper_letter->value()) - type = 1; - else if (type == -1 && ipc->paper_a4->value()) - type = 2; - - if (type == 1) - { - page_width = 8.5; - page_height = 11.0; - } - - else if (type == 2) - { - page_width = 8.27; - page_height = 11.69; - } - - if (ipc->landscape->value()) - { - double tmp = page_width; - page_width = page_height; - page_height = tmp; - } -} - -void Image_Printer::setAspectRatio(int change_axis) -{ - double target_width, target_height; - - double cur_height = atof(ipc->height->value()); - double cur_width = width; - - // define ar as h/w, giving h = ar*w, w = h/ar - double spyview_ar = 1.0* iw->dozoom(iw->h, iw->yzoom) / iw->dozoom(iw->w, iw->xzoom); - - // change axis: - // 1 = change width, keep left edge - // 2 = change width, center - // 3 = change width, keep right edge - // 4 = change height, keep top edge - // 5 = change height, center - // 6 = change height, keep bottom edge - - - if (change_axis < 4) // change width - { - target_width = cur_height / spyview_ar; - target_height = cur_height; - if (change_axis == 2) - xoff += (cur_width - target_width)/2; - else if (change_axis == 3) - xoff += (cur_width - target_width); - } - else - { - target_width = cur_width; - target_height = cur_width * spyview_ar; - if (change_axis == 4) - yoff += (cur_height - target_height); - else if (change_axis == 5) - yoff += (cur_height - target_height)/2; - } - - width = target_width; - - //historically, height is not a local class variable... - char buf[1024]; - snprintf(buf,sizeof(buf),"%g",target_height); - ipc->height->value(buf); - updateSettings(ipc); - //ipc->center_x->do_callback(); - //ipc->center_y->do_callback(); -} - -static void maybe_mkdir(const char *name) -{ -#ifdef WIN32 - if(mkdir(name) == 0) -#else - if(mkdir(name,0777) == 0) -#endif - - switch(errno) - { - case EEXIST: - return; - default: - warn("Unable to create directory \"%s\": %s\n",name,strerror(errno)); - return; - } -} - -void Image_Printer::initSettingsDir() -{ - string buf; -#ifdef WIN32 - if(getenv("SPYVIEW_PREF_DIR") != NULL) - buf = getenv("SPYVIEW_PREF_DIR"); - else - buf = sharedir; -#else - buf = getenv("HOME"); - buf = buf + DIRECTORY_SEPARATOR + ".spyview"; -#endif - maybe_mkdir(buf.c_str()); - buf = buf + DIRECTORY_SEPARATOR + "print_settings"; - settingsDir = buf; - maybe_mkdir(buf.c_str()); -} - -void Image_Printer::savePreviewSettings() -{ - string name; - initSettingsDir(); - if(name.empty()) - name = settingsDir + DIRECTORY_SEPARATOR + "settings.prv"; - - std::ofstream ofs(name.c_str()); - boost::archive::text_oarchive ar(ofs); - - int version; - ar & version; - // All this stuff is in version 1 - ar & flcast(ipc->preview_cmd); - ar & flcast(ipc->gs_cmd); - ar & flcast(ipc->extra_pdf); - ar & flcast(ipc->extra_png); - ar & flcast(ipc->png_dpi); - ar & flcast(ipc->cmyk); -} - -void Image_Printer::loadPreviewSettings() -{ - string name; - initSettingsDir(); - if(name.empty()) - name = settingsDir + DIRECTORY_SEPARATOR + "settings.prv"; - - std::ifstream ifs(name.c_str()); - if (!ifs.good()) - { - info("preview settings file _%s_ not found\n", name.c_str()); - return; - } - boost::archive::text_iarchive ar(ifs); - - int version; - ar & version; - ar & flcast(ipc->preview_cmd); - ar & flcast(ipc->gs_cmd); - ar & flcast(ipc->extra_pdf); - ar & flcast(ipc->extra_png); - ar & flcast(ipc->png_dpi); - ar & flcast(ipc->cmyk); -} - - -void Image_Printer::savePrintSettings(std::string name) -{ - fetchSettings(ipc); // Should be redundant, but paranoia is good. - initSettingsDir(); - if(name.empty()) - { - name = settingsDir + DIRECTORY_SEPARATOR + "default.set"; - } - - const char *fname = name.c_str(); - std::ofstream ofs(fname); - try - { - if(!ofs.good()) - throw(1); - } - catch (...) - { - warn("Unable to create or overwrite settings file \"%s\"\n",fname); - } - - try - { - boost::archive::text_oarchive oa(ofs); - - // For some reason, on WIN32 even have this code compiled into - // the program, even if it is not executed (!?), causes a - // crash. - - // Upon further inspection, this causes a crash on my machine - // at work, but not on my machine at home. Also, curiously, on - // my machine at work, the fltk widgets have now started to be - // displayed at unix "dark grey" instead of the usual windows - // "light biege". At home, where the exact same executable is - // not crashing, the fltk widgets are beige (except for the - // first warning dialog box!!!) - - oa & (*this); - } - catch (boost::archive::archive_exception e) - { - error("ImagePrinter serialization error: %s",e.what()); - } - catch (...) - { - error("Unknown serialization error\n"); - } - -} - -void Image_Printer::loadPrintSettings(std::string name) -{ - initSettingsDir(); - if(name.empty()) - { - name = settingsDir + DIRECTORY_SEPARATOR + "default.set"; - } - - const char *fname = name.c_str(); - try - { - std::ifstream ifs(fname); - if(!ifs.good()) - throw(1); - boost::archive::text_iarchive ia(ifs); - ia & (*this); - updateSettings(ipc); - } - catch (boost::archive::archive_exception e) - { - error("Serialization error: %s",e.what()); - } - catch (...) - { - warn("Unable to load settings file \"%s\": %s\n",fname,strerror(errno)); - } -} - - -static inline int chGetCode(double x, double y, double wx1, double wy1, double wx2, double wy2) -{ - double eps = max(fabs(wx1-wx2),fabs(wy1-wy2))*1e-6; - int code = NONE; - if(xwx2+eps) - code |= RIGHT; - if(ywy2+eps) - code |= BOTTOM; - return code; -} - -static inline bool SubClip(double &x1,double &y1,double &x2,double &y2, double wx1, double wy1, double wx2, double wy2) -{ - if(wy2 < wy1) - swap(wy2,wy1); - if(wx2 < wx1) - swap(wx2,wx1); - if(fabs(x2-x1) < fabs(y2 - y1)) - return SubClip(y1,x1,y2,x2,wy1,wx1,wy2,wx2); - double m, tx, ty; - int code1, code2; - m=(y2-y1)/(float)(x2-x1); - code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - code2=chGetCode(x2,y2,wx1,wy1,wx2,wy2); - for(int i = 0; i < 20; i++) - { - if(code1 == NONE) - break; - if(code1 & LEFT) - { - tx=wx1-x1; - ty=y1+(tx*m); - x1=wx1; y1=ty; - code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - } - if(code1 & RIGHT) - { - tx=wx2-x1; - ty=y1+(tx*m); - x1=wx2; y1=ty; - code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - } - if(code1 & TOP) - { - ty=wy1-y1; - tx=x1+(ty/m); - x1=tx; y1=wy1; - code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - } - if(code1 & BOTTOM) - { - ty=wy2-y1; - tx=x1+(ty/m); - x1=tx; y1=wy2; - code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - } - if((code2 & code1) != 0) - return false; - } - if(code1 != NONE) - { - fprintf(stderr,"Bad clip: %g,%g %g,%g [%g,%g]-[%g,%g]\n",x1,y1,x2,y2,wx1,wy1,wx2,wy2); - return false; - } - return true; -} - -static bool Clip(double &x1,double &y1,double &x2,double &y2, double wx1, double wy1, double wx2, double wy2) -{ - int code1=chGetCode(x1,y1,wx1,wy1,wx2,wy2); - int code2=chGetCode(x2,y2,wx1,wy1,wx2,wy2); - if((code1 & code2) != 0) - return false; - if((code1 == 0) && (code2 == 0)) - return true; - // printf("Clipping %g,%g - %g,%g to %g,%g - %g,%g\n",x1,y1,x2,y2,wx1,wy1,wx2,wy2); - bool res = SubClip(x1,y1,x2,y2,wx1,wy1,wx2,wy2); - // printf(" Clip %g,%g - %g,%g to %g,%g - %g,%g %s\n",x1,y1,x2,y2,wx1,wy1,wx2,wy2, res ? "true" : "false"); - return res && SubClip(x2,y2,x1,y1,wx1,wy1,wx2,wy2); - - -} - -void setColor(FILE *out, Fl_Color_Chooser *c) -{ - fprintf(out,"%g %g %g setrgbcolor %% Color: %s\n",c->r(),c->g(),c->b(),c->label()); -} - -void Image_Printer::write_watermark() -{ - // The "Watermark" prints a text copy of many of the settings into a small - // Rectangle clipped to the image area. You can use illustrator to delete - // the image and see it if you need to duplicate an image. - static const double ls=5.0/INCH; - fprintf(out,"%% The following puts a watermark with some info on how the file was made below the image\n"); - setColor(out,ipc->text_color); - pushClip(out,xoff,yoff,width,height); - fprintf(out,"/Courier findfont 4 scalefont setfont\n"); - double y = yoff+height-ls; - char buf[4096]; - - snprintf(buf,sizeof(buf),"filename %s colormap %s", - iw->filename.c_str(), iw->colormap_window->label()); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"hmin %d %e %s hmax %d %e", - iw->hmin, iw->id.quant_to_raw(iw->hmin), iw->id.zname.c_str(), - iw->hmax, iw->id.quant_to_raw(iw->hmax)); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"plane_a %g plane_b %g gamma %g gammacenter %g", iw->plane_a, iw->plane_b, iw->gam, iw->gcenter); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"imop \"%s\"", iw->operations_string.c_str()); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"box_int (%d,%d)-(%d,%d)", img_x1, img_y1, img_x2, img_y2); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"box (%g,%g)-(%g,%g)", iw->xunit(img_x1)*xscale, iw->yunit(img_y1)*yscale, iw->xunit(img_x2)*xscale, iw->yunit(img_y2)*yscale); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - snprintf(buf,sizeof(buf),"xscale %g yscale %g", xscale, yscale); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n", - xoff, y, buf); - y -= ls; - - - fprintf(out," cliprestore\n"); -} - -void Image_Printer::calculateBoundingBox() -{ - // Before, we put the bounding box at the end of the file after we - // calculated all the label widths. - - // However, there is an outstanding ghostscript bug that ignores - // (atend) bounding boxes gv and gsview both have hacked together - // work arounds however, if we use ghostscript to convert to png or - // pdf, the bounding box is completely ignored! - - // So, now, we have to hack it in here. - - // The y values are easy, since the height of the labels is fixed - bb_ur_y = (int) ((yoff+height)*INCH + (ipc->do_title->value() ? 2 : 1) * fontsize); - bb_ll_y = (int) (yoff*INCH - (ipc->xaxis_label->value() ? 3 : 2) * fontsize); - - // The x values are much harder, since we need to estimate the maximum width of - // the y axis labels and the colorbar labels. - // - // Let's try estimating it from the min an max values of the labels - -// double tmp; -// char buf[128]; -// tmp = iw->yunit((img_y2+img_y1)*0.667)*yscale; // a random uneven number? -// max_ytic_width = snprintf(buf,sizeof(buf),ipc->yticfmt->value(),tmp); -// info("%s\n", buf); - -// // Same for the colorbar - -// tmp = iw->getz((iw->hmin+iw->hmax)*0.667)*zscale; -// max_ctic_width = snprintf(buf,sizeof(buf),ipc->yticfmt->value(),tmp); -// info("%s\n", buf); - - // the above doesn't work so well either... - // let's just overestimate the bounding box a bit... - // it would be better to calculate the tics ahead of time... - - max_ytic_width = 10; - max_ctic_width = 10; - - int label_x = static_cast(- (max_ytic_width+2.5)*fontsize/2.0); - bb_ll_x = (int) (xoff*INCH - (ipc->yaxis_label->value() ? 1 : -1) * fontsize + label_x); - - int label_c = static_cast((max_ctic_width+2.5)*fontsize/2.0); - cbar_width = ipc->cbar_width->value(); - cbar_xoff = xoff + width + 0.3; - - if(ipc->colorbar->value()) - bb_ur_x = (int) ((cbar_xoff+cbar_width)*INCH + label_c + (ipc->caxis_label->value() ? fontsize : 0)); - else - bb_ur_x = (int) ((xoff+width)*INCH + fontsize); - - info("Label width estimates:\n"); - info("ytic %d ctic %d\n", max_ytic_width, max_ctic_width); - info("%%%%BoundingBox: %d %d %d %d\n", bb_ll_x, bb_ll_y, bb_ur_x, bb_ur_y); - - max_ytic_width = 0; - max_ctic_width = 0; -} - -void Image_Printer::write_header() -{ - - // First, reset the bouding box - bb_ll_x = bb_ll_y = 0; - - // Now that we to include support for printing the area selected - // using the zoom window (or a manually set area), we will create - // some variables here that store the area of the image - - if (ipc->paper_eps->value() && (!preview)) - fprintf(out,"%%!PS-Adobe-3.0 EPSF-3.0\n"); - else - fprintf(out,"%%!PS-Adobe-3.0\n"); - - // Add a paper description and orientation for nice cooperation with - // gs: however, for some reason, ps2pdf seems to ignore the paper - // settings we put in the postscript file and just uses Letter... - if (ipc->paper_letter->value()) - { - bb_ur_x = 612; - bb_ur_y = 792; - } - else if (ipc->paper_a4->value()) - { - bb_ur_x = 595; - bb_ur_y = 842; - } - - if (ipc->paper_eps->value()) - { - calculateBoundingBox(); - fprintf(out, "%%%%BoundingBox: %d %d %d %d\n", bb_ll_x, bb_ll_y, bb_ur_x, bb_ur_y); - if(preview) - fprintf(out, "%%%%Pages: 1\n"); - else - fprintf(out, "%%%%Pages: 0\n"); - fprintf(out,"%%%%Orientation: Portrait\n"); - } - else - { - // The PNG and PDF files will be displayed with rotated pages if we do this. - //if (ipc->landscape->value()) - //{ - // int tmp = bb_ur_x; - // bb_ur_x = bb_ur_y; - // bb_ur_y = tmp; - //} - // the above doesn't really work... - if (ipc->paper_letter->value()) - fprintf(out, "%%%%DocumentMedia: Letter %d %d 0 () ()\n", bb_ur_x,bb_ur_y); - else if (ipc->paper_a4->value()) - fprintf(out, "%%%%DocumentMedia: A4 %d %d 0 () ()\n",bb_ur_x,bb_ur_y); - - fprintf(out, "%%%%Orientation: %s\n", ipc->landscape->value() ? "Landscape" : "Portrait"); - fprintf(out, "%%%%Pages: 1\n"); - } - - // DSC comments that don't change with ps/eps... - fprintf(out,"%%%%DocumentData: Clean7Bit\n"); - fprintf(out,"%%%%Creator: Spyview PS Output\n"); - fprintf(out, - "%%%% Spyview parameters:\n" - "%%%% colorplotmin = %e ; colorplotmax = %e\n" - "%%%% gamma = %e\n" - "%%%% rawdata_min = %e, rawdata_max = %e\n", - iw->getz(iw->hmin)*zscale, iw->getz(iw->hmax)*zscale, - iw->gam, iw->id.rawmin, iw->id.rawmax); - fprintf(out,"%%%%EndComments\n\n"); - - - // Distiller magic - fprintf(out, - "%%%%BeginSetup\n" - "%% The following makes distiller not jpeg compress the spyview image.\n" - "systemdict /setdistillerparams known {\n" - "<< /AutoFilterColorImages false /ColorImageFilter /FlateEncode >>\n" - "setdistillerparams\n" - "} if\n" - "/inch {72 mul} bind def\n" - "/rightshow %% stk: string; show a string right aligned at the current location\n" - "{ dup stringwidth pop 0 exch sub 0 rmoveto show } def\n" - "/centershow %% stk: string show a string centered horizontally at the current location\n" - "{ dup stringwidth pop 0 exch sub 0.5 mul 0 rmoveto show } def\n" - "%%%%EndSetup\n"); - - if(ipc->paper_eps->value()) - { - // Tricky part: estimate a nice bounding box for an EPS file; the pagesize will crop the output pdf nicely if we get it close. - int label_c = static_cast((6)*fontsize/2.0); - if(ipc->colorbar->value()) - bb_ur_x = (int) ((cbar_xoff+cbar_width)*INCH + label_c + (ipc->caxis_label->value() ? fontsize : 0)); - else - bb_ur_x = (int) ((xoff+width)*INCH + fontsize); - bb_ur_y = (int) ((yoff+height)*INCH + (ipc->do_title->value() ? 2 : 1) * fontsize); - - // This is causing problems with ghostscript 8.54: strictly - // speaking, EPS files should not have a page size. In newer - // versions of ghostscript, if a page size is found, it - // overrides the bounding box for conversion to, for example, - // PDF and PNG files. - //fprintf(out,"<< /PageSize [%d %d] >> setpagedevice\n",bb_ur_x,bb_ur_y); - } - - if (!ipc->paper_eps->value() || preview) - fprintf(out, "%%%%Page: 1 1\n"); - fprintf(out,"gsave\n"); -} - -void Image_Printer::draw_image() -{ - - // Draw the image - fprintf(out,"%% Draw the image\n"); - //fprintf(out,"/imgstr %d string def\n\n", iw->w); - fprintf(out,"/imgstr %d string def\n\n", img_xsize); - fprintf(out,"gsave\n %g inch %g inch translate\n", xoff,yoff); - fprintf(out," %g inch %g inch scale\n",width,height); - //fprintf(out," %d %d %% Columns and Rows\n", iw->w, iw->h); - fprintf(out," %d %d %% Columns and Rows\n", img_xsize, img_ysize); - fprintf(out," 8 %% bits per color channel\n"); - //fprintf(out," [%d 0 0 %d 0 0]\n",iw->w, iw->h); // Map the unit square to our image - fprintf(out," [%d 0 0 %d 0 0]\n",img_xsize, img_ysize); // Map the unit square to our image - fprintf(out," { currentfile imgstr readhexstring pop } false 3 colorimage\n"); - fprintf(out," "); - - // number of columns before a newline in the postscript image - static const int maxcol=72; - - for(int i = img_y2; i >= img_y1; i--) - { - int c = 0; - for(int j = img_x1; j <= img_x2; j++) - { - c += 6; - if(c > maxcol) - { - fprintf(out,"\n "); - c = 6; - } - unsigned char r,g,b; - if(i >= 0 && i < iw->h && j >= 0 && j < iw->w) // This is a horrible hack, but I'm too lazy to work out the right bounds. - iw->getrgb(i,j,r,g,b); - else - { - r = g = b = 255; - } - fprintf(out,"%02x%02x%02x",r,g,b); - - } - fprintf(out,"\n "); - } - fprintf(out," grestore\n\n"); -} - -void Image_Printer::draw_lines() -{ - // We want to draw the linecut before the bounding box and the tic - // marks, so it comes out beneath them. - bool clipped=false; - - if(ipc->plotLineCut->value() && (iw->line_cut_type != NOLINE)) // Plot the line for the linecut. We use the ticmark settings at the moment, which is stupid but easy. - { - pushClip(out,xoff,yoff,width,height); - clipped=true; - fprintf(out,"%% Plot the linecut location\n"); - setColor(out, ipc->linecut_color); - fprintf(out," %g setlinewidth newpath\n",tickwidth); - double x1,y1,x2,y2,t; - switch(iw->line_cut_type) - { - case HORZLINE: - x1 = xoff; x2 = xoff + width; - y1=iw->line_cut_yp; - pixelToDevice(t,y1); - y2=y1; - break; - case VERTLINE: - x1=iw->line_cut_xp; - pixelToDevice(x1,t); - x2=x1; - y1 = yoff; y2 = yoff + height; - break; - case OTHERLINE: - x1=iw->lcx1; - x2=iw->lcx2; - y1=iw->lcy1; - y2=iw->lcy2; - pixelToDevice(x1,y1); - pixelToDevice(x2,y2); - break; - default: - warn("Unknown line cut type!\n"); - exit(1); - } - fprintf(out," %g inch %g inch moveto\n",x1,y1); - fprintf(out," %g inch %g inch lineto\n",x2,y2); - fprintf(out,"stroke\n"); - } - - if(ipc->plotZoomBox->value() && iw->zoom_window && iw->zoom_window->visible()) - { - int x1,y1,x2,y2; - iw->zoom_window->getSourceArea(x1,y1,x2,y2); - double x1d, y1d, x2d, y2d; - x1d = x1; y1d = y1; x2d = x2; y2d = y2; - pixelToDevice(x1d,y1d); - pixelToDevice(x2d,y2d); - setColor(out,ipc->zoombox_color); - fprintf(out," %g setlinewidth newpath\n",tickwidth); - fprintf(out," %g inch %g inch moveto\n",x1d,y1d); - fprintf(out," %g inch %g inch lineto\n",x1d,y2d); - fprintf(out," %g inch %g inch lineto\n",x2d,y2d); - fprintf(out," %g inch %g inch lineto\n",x2d,y1d); - fprintf(out," %g inch %g inch lineto\n",x1d,y1d); - fprintf(out," stroke\n"); - } - if (ipc->plotLines->value() && !LineDrawer->lines.empty()) - { - if(!clipped) - pushClip(out,xoff,yoff,width,height); - clipped=true; - fprintf(out,"%% Plot the lines\n"); - setColor(out,ipc->overlay_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth); - double lx = NAN; - double ly = NAN; - - for(LineDraw::lines_t::iterator i = LineDrawer->lines.begin(); i != LineDrawer->lines.end(); i++) - { - double x1,y1,x2,y2; - x1=i->x1*xscale; - x2=i->x2*xscale; - y1=i->y1*yscale; - y2=i->y2*yscale; - unitToDevice(x1,y1); - unitToDevice(x2,y2); - if(Clip(x1,y1,x2,y2,xoff,yoff,xoff+width,yoff+height)) - { - if(!(isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))) - { - if((x1 != lx) || (y1 != ly)) // Skip unnecessary moves. - fprintf(out," %g inch %g inch moveto\n",x1,y1); - fprintf(out," %g inch %g inch lineto\n",x2,y2); - } - lx = x2; - ly = y2; - } - else - { - lx = NAN; - ly = NAN; - } - } - fprintf(out,"stroke\n"); - } - if(clipped) - { - fprintf(out," cliprestore\n"); - clipped=false; - } -} - -void Image_Printer::draw_colorbar() -{ - int cbimgx, cbimgy; - if (ipc->rotate_cbar->value()) - { - cbar_height = ipc->cbar_width->value(); - cbar_width = height*ipc->cbar_height_per->value()/100.0; - cbar_xoff = xoff + (width-cbar_width)/2; - cbar_yoff = yoff + height+0.3; - cbimgx = iw->colormap_length; - cbimgy = 1; - } - else - { - cbar_width = ipc->cbar_width->value(); - cbar_height = height*ipc->cbar_height_per->value()/100.0; - cbar_xoff = xoff + width + 0.3; - cbar_yoff = yoff + (height - cbar_height)/2; - cbimgx = 1; - cbimgy = iw->colormap_length; - } - - - - if (!ipc->linear_cmap->value()) - { - // Draw a colorbar with a non-linear color mapping but a linear tic spacing - - fprintf(out,"%% Draw the colorbar\n"); - fprintf(out,"/imgstr %d string def\n\n", 1); - fprintf(out,"gsave\n %g inch %g inch translate\n", cbar_xoff, cbar_yoff); - fprintf(out," %g inch %g inch scale\n",cbar_width, cbar_height); - fprintf(out," %d %d %% Columns and Rows\n", cbimgx, cbimgy); - fprintf(out," 8 %% bits per color channel\n"); - fprintf(out," [%d 0 0 %d 0 0]\n", cbimgx, cbimgy); // Map the unit square to our image - fprintf(out," { currentfile imgstr readhexstring pop } false 3 colorimage\n"); - - int tmp; - for(int i = 0; i < iw->colormap_length; i++) - { - unsigned char r,g,b; - tmp = iw->gammatable[i]; - r = iw->colormap[3*tmp]; - g = iw->colormap[3*tmp+1]; - b = iw->colormap[3*tmp+2]; - fprintf(out,"%02x%02x%02x",r,g,b); - fprintf(out,"\n "); - } - fprintf(out," grestore\n\n"); - - // Draw the colorbar box - - if (boxwidth > 0) - { - fprintf(out, "%% Draw the box around the colorbar\n"); - setColor(out,ipc->border_color); - fprintf(out," %g setlinewidth newpath\n",boxwidth); - box(out,cbar_xoff,cbar_yoff,cbar_width,cbar_height); - fprintf(out," stroke\n"); - } - - // Draw the tic marks on the colorbox - fprintf(out,"/%s findfont %g scalefont setfont\n",ipc->face->value(),fontsize); - fprintf(out," %g setlinewidth\n", tickwidth); - if(ipc->cticfmt->size() != 0) - { - double cs; - double cmin = iw->getz(iw->hmin)*zscale; - double cmax = iw->getz(iw->hmax)*zscale; - int tic_width; - - if(ipc->cspacing->value() != 0) - cs = fabs(ipc->cspacing->value()); - else - cs=autospace(cmin,cmax); - - if(cmin > cmax) - cs=-cs; - - // Tic marks should be on integers (1.0, 1.5,... not 1.37,1.87,...) and should not be outside the frame - double min = cs*ceil(cmin/cs); - double tic_offset, wrange; - if (ipc->precise_ticks->value()) - { - wrange=cbar_height*(iw->colormap_length-1)/(iw->colormap_length); // cmin is actually 1/2 picel from the left edge, xmax is 1/2 pixel from the right. - tic_offset = cbar_height*(0.5/(iw->colormap_length)); - } - else - { - wrange=cbar_height; - tic_offset=0; - } - // warn("min %g cmin %g cmax %g cs %g zero %g\n",min,cmin,cmax,cs,zero); - for(double c = min; c*cs <= cmax*cs + zero*cs*fabs(cs); c += cs) - { - // warn("%g %g %g %g\n",c,c*cs,cmax*cs,zero*cs*abs(cs)); - //if(x < xmin) - //continue; - char buf[128]; - buf[0] = 0; // a good default - if (ipc->cticfmt->value()[0] == 'e') - { - char *p = ipc->cticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(c, dig, 1), 128); - } - else if (ipc->cticfmt->value()[0] == 's') - { - char *p = ipc->cticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(c, dig, 0), 128); - } - else - { - if(fabs(c/cs) < zero) - snprintf(buf,sizeof(buf),ipc->cticfmt->value(),0.0); - else - snprintf(buf,sizeof(buf),ipc->cticfmt->value(),c); - } - info("cvalue %e label '%s'\n", c, buf); - tic_width = strlen(buf); - - if (tic_width > max_ctic_width) max_ctic_width = tic_width; - - double psx = cbar_xoff+cbar_width+0.25*fontsize/INCH; // - double psy = cbar_yoff + wrange * ((c-cmin)/(cmax-cmin)) + tic_offset; - setColor(out,ipc->text_color); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n",psx,psy-0.25*fontsize/INCH,buf); - - if(ipc->fancy_ticks->value()) - { - setColor(out,ipc->large_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth*2); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength+tickwidth/72.0); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength-tickwidth/72.0); - setColor(out,ipc->small_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength); - } - else - { - setColor(out,ipc->small_tick_color); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength); - } - } - } - } - else // Draw a colorbar with a linear color scale but with a non-linear tic mark scale - { - - // First draw the image for inside the colorbar - - int length = iw->colormap_length; - int start = ipc->cmin->value()*length; - int end = ipc->cmax->value()*length; - - fprintf(out,"%% Draw the colorbar\n"); - fprintf(out,"/imgstr %d string def\n\n", 1); - fprintf(out,"gsave\n %g inch %g inch translate\n", cbar_xoff, cbar_yoff); - fprintf(out," %g inch %g inch scale\n",cbar_width, cbar_height); - fprintf(out," %d %d %% Columns and Rows\n", 1, end-start); - fprintf(out," 8 %% bits per color channel\n"); - fprintf(out," [%d 0 0 %d 0 0]\n", 1, end-start); // Map the unit square to our image - fprintf(out," { currentfile imgstr readhexstring pop } false 3 colorimage\n"); - - for(int i = start; i < end; i++) - { - unsigned char r,g,b; - r = iw->colormap[3*i]; - g = iw->colormap[3*i+1]; - b = iw->colormap[3*i+2]; - fprintf(out,"%02x%02x%02x",r,g,b); - fprintf(out,"\n "); - } - fprintf(out," grestore\n\n"); - - // Draw the colorbar box - - if (boxwidth > 0) - { - setColor(out,ipc->border_color); - fprintf(out, "%% Draw the box around the colorbar\n"); - fprintf(out," %g setlinewidth newpath\n",boxwidth); - box(out,cbar_xoff,cbar_yoff,cbar_width,cbar_height); - fprintf(out," stroke\n"); - } - - // Now, we want to do something a bit tricky: map the colors on - // the "linear" color scale onto actual data values for tick - // marks. The first thing we need to do is make what I will call - // a "reverse map". Using this table, we can get a datapoint - // value based on it's color value - - // We have to be a bit careful with rounding, particularly for - // small gammas - int l = iw->colormap_length; - int reverse_map[l]; - for (int i=0; ihmin; ihmax; i++) - { - int index = 1.0*iw->imagehist[i]*(l-1)/LMAX; - if (reverse_map[index] == -1) reverse_map[index] = i; - } - reverse_map[0] = iw->hmin; - for (int i=0; icbegin->value(); // will leave this name unchanged to avoid having to rewrite settings code... - double c1=-1; - // Get the quantized value from the raw value - int val_quant = iw->id.raw_to_quant(definitive_label); - // Get the position in the un-gammed colormap (float between 0 and 1) - double cmap_position = iw->imagehist[val_quant]/LMAX; - info("estimated cmap position is %f\n", cmap_position); - if (c1 < ipc->cmin->value()) c1 = ipc->cmin->value(); - - // Draw the tic marks on the colorbox - fprintf(out,"/%s findfont %g scalefont setfont\n",ipc->face->value(),fontsize); - fprintf(out," %g setlinewidth\n", tickwidth); - char buf[256]; - if(ipc->cticfmt->size() != 0) - { - for (double c=c1; c < ipc->cmax->value(); c += ipc->clabelspacing->value()) - { - int i = (int) (c*(l-1)); - double val = iw->id.quant_to_raw(reverse_map[i]); - - buf[0] = 0; // a good default - if (ipc->cticfmt->value()[0] == 'e') - { - char *p = ipc->cticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(c, dig, 1), 128); - } - else if (ipc->cticfmt->value()[0] == 's') - { - char *p = ipc->cticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(c, dig, 0), 128); - } - else - snprintf(buf,sizeof(buf),ipc->cticfmt->value(),c); - info("cvalue %e label '%s'\n", c, buf); - int tic_width = strlen(buf); - - if (tic_width > max_ctic_width) max_ctic_width = tic_width; - - double psx = cbar_xoff + cbar_width + 0.25*fontsize/INCH; - double psy = cbar_yoff + cbar_height * ((c-ipc->cmin->value())/(ipc->cmax->value()-ipc->cmin->value())); - - // Draw the label - setColor(out,ipc->text_color); - fprintf(out," newpath %g inch %g inch moveto (%s) show\n",psx,psy-0.25*fontsize/INCH,buf); - - // Draw the tic lines - if(ipc->fancy_ticks->value()) - { - setColor(out,ipc->large_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth*2); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength+tickwidth/72.0); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength-tickwidth/72.0); - setColor(out,ipc->small_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength); - } - else - { - setColor(out,ipc->small_tick_color); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",cbar_xoff+cbar_width,psy,-ticklength); - } - } - } - } -} - -void Image_Printer::draw_axis_tics() -{ - - // ***************** - // Draw the xtics - // ***************** - - // Draw the tick marks - fprintf(out,"/%s findfont %g scalefont setfont\n",ipc->face->value(),fontsize); - fprintf(out," %g setlinewidth\n", tickwidth); - if(ipc->xticfmt->value()[0] != '\0') - { - double xs; - double xmin = iw->xunit(img_x1)*xscale; - double xmax = iw->xunit(img_x2)*xscale; - - if(xspacing != 0) - xs = fabs(xspacing); - else - xs=autospace(xmin,xmax); - - if(xmin > xmax) - xs=-xs; - - // Tic marks should be on integers (1.0, 1.5,... not 1.37,1.87,...) and should not be outside the frame - double min = xs*ceil(xmin/xs); - double tic_offset, wrange; - if (ipc->precise_ticks->value()) - { - wrange=width*(img_xsize-1)/(img_xsize); // xmin is actually 1/2 pixel from the left edge, xmax is 1/2 pixel from the right. - tic_offset = width*(0.5/(img_xsize)); - } - else - { - wrange=width; - tic_offset=0; - } - for(double x = min; x*xs <= xmax*xs + zero*xs*fabs(xs); x += xs) - { - //if(x < xmin) - //continue; - char buf[128]; - buf[0] = 0; // a good default - if (ipc->xticfmt->value()[0] == 'e') - { - char *p = ipc->xticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(x, dig, 1), 128); - } - else if (ipc->xticfmt->value()[0] == 's') - { - char *p = ipc->xticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(x, dig, 0), 128); - } - else - { - if(fabs(x/xs) < zero) - snprintf(buf,sizeof(buf),ipc->xticfmt->value(),0.0); - else - snprintf(buf,sizeof(buf),ipc->xticfmt->value(),x); - } - //info("xvalue %e label '%s'\n", x, buf); - - double psy = yoff-1.0*fontsize/INCH; // - double psx = xoff + wrange * ((x-xmin)/(xmax-xmin)) + tic_offset; - setColor(out,ipc->text_color); - fprintf(out," newpath %g inch %g inch moveto (%s) centershow\n",psx,psy,buf); - if(ipc->fancy_ticks->value()) - { - setColor(out,ipc->large_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth*2); - fprintf(out," newpath %g inch %g inch moveto 0 %g inch rlineto stroke\n",psx,yoff,ticklength+tickwidth/72.0); - fprintf(out," newpath %g inch %g inch moveto 0 %g inch rlineto stroke\n",psx,yoff+height,-ticklength-tickwidth/72.0); - setColor(out,ipc->small_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth); - fprintf(out," newpath %g inch %g inch moveto 0 %g inch rlineto stroke\n",psx,yoff,ticklength); - fprintf(out," newpath %g inch %g inch moveto 0 %g inch rlineto stroke\n",psx,yoff+height,-ticklength); - } - else - { - setColor(out,ipc->small_tick_color); - fprintf(out," newpath %g inch %g inch moveto 0 inch %g inch rlineto stroke\n",psx,yoff,ticklength); - fprintf(out," newpath %g inch %g inch moveto 0 inch %g inch rlineto stroke\n",psx,yoff+height,-ticklength); - } - } - - - } - - // ***************** - // Draw the ytics - // ***************** - - if(ipc->yticfmt->value()[0] != '\0') - { - double ys; - // we have some issues due to the fact that "y=0" for the fltk - // drawing routines is at the top of the screen...we must - // remember that ymax = y1 and ymin = y2... - double ymin = iw->yunit(img_y2)*yscale; - double ymax = iw->yunit(img_y1)*yscale; - - if(yspacing != 0) - ys = fabs(yspacing); - else - ys=autospace(ymin,ymax); - - if(ymin > ymax) - ys=-ys; - - int tic_width; - - // This is horrible; everything changes when ys and ymin change sign. - double min = ys*ceil(ymin/ys); - double hrange, tic_offset; - if (ipc->precise_ticks->value()) - { - hrange = height*(img_ysize-1)/(img_ysize); - tic_offset = height*(0.5/(img_ysize)); - } - else - { - hrange = height; - tic_offset = 0; - } - for(double y = min; y*ys <= ymax*ys + zero*ys*fabs(ys); y += ys) - { - // warn("%g\n",y); - char buf[128]; - buf[0] = 0; // a good default - if (ipc->yticfmt->value()[0] == 'e') - { - char *p = ipc->yticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(y, dig, 1), 128); - } - else if (ipc->yticfmt->value()[0] == 's') - { - char *p = ipc->yticfmt->value()+1; - long int dig = strtol(p, (char **)NULL, 10); // strtol returns zero if no digits are found - if (dig == 0) dig = 2; // a reasonable default? - strncpy(buf, eng(y, dig, 0), 128); - } - else - { - if(fabs(y/ys) < zero) - snprintf(buf,sizeof(buf),ipc->yticfmt->value(),0.0); - else - snprintf(buf,sizeof(buf),ipc->yticfmt->value(),y); - } - //info("yvalue %e label '%s'\n", y, buf); - tic_width = strlen(buf); - - if (tic_width > max_ytic_width) max_ytic_width = tic_width; - double psx = xoff-0.25*fontsize/INCH; // - double psy = yoff + hrange * ((y-ymin)/(ymax-ymin)) + tic_offset; - setColor(out,ipc->text_color); - fprintf(out," newpath %g inch %g inch moveto (%s) rightshow\n",psx,psy-0.25*fontsize/INCH,buf); - - if(ipc->fancy_ticks->value()) - { - setColor(out,ipc->large_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth*2); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff,psy,ticklength+tickwidth/72.0); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff+width,psy,-ticklength-tickwidth/72.0); - setColor(out,ipc->small_tick_color); - fprintf(out,"%g setlinewidth newpath\n",tickwidth); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff+width,psy,-ticklength); - } - else - { - setColor(out,ipc->small_tick_color); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff,psy,ticklength); - fprintf(out," newpath %g inch %g inch moveto %g inch 0 rlineto stroke\n",xoff+width,psy,-ticklength); - } - } - } -} - -void Image_Printer::draw_axis_labels() -{ - - // Draw the labels - - double label_x, label_y; - - setColor(out,ipc->text_color); - if (ipc->yaxis_label->value()) - { - // Notes: as a nasty hack, assume an average font aspect ration - // of 2:1. Also, offset us by an extra 3.5 font widths (note - // max_ytic_width includes terminating null) - - // Would probably be better to keep a copy of the longest ytic - // string and then have the postscript interpret the - // width for us...but this seems to work reasonably well. - - label_x = xoff - (max_ytic_width+2.5)*fontsize/2.0/INCH; - label_y = yoff + height/2; - fprintf(out, " newpath %g inch %g inch moveto (%s) 90 rotate centershow -90 rotate\n", label_x, label_y, iw->id.yname.c_str()); - } - - if (ipc->caxis_label->value() && ipc->colorbar->value()) - { - label_x = cbar_xoff + cbar_width + (max_ctic_width+3.5)*fontsize/2.0/INCH; - label_y = cbar_yoff + cbar_height/2; - fprintf(out, " newpath %g inch %g inch moveto (%s) 90 rotate centershow -90 rotate\n", label_x, label_y, iw->id.zname.c_str()); - } - - if (ipc->xaxis_label->value()) - { - label_x = xoff + width/2; - label_y = yoff - 2.5*fontsize/INCH; - fprintf(out, " newpath %g inch %g inch moveto (%s) centershow\n", label_x, label_y, iw->id.xname.c_str()); - } - - if (ipc->do_title->value()) - { - label_x = xoff + width/2; - label_y = yoff + height + 1.0*fontsize/INCH; - char buf[1024]; - char bn[1024]; - strncpy(bn, iw->output_basename, sizeof(bn)); - char *p = basename(bn); - info("%s -> %s\n", iw->output_basename, p); - snprintf(buf, 1024, ipc->title->value(), p, iw->id.zname.c_str()); - // Postscript needs to have double \\ to display properly - string name = buf; - string::size_type pos=0; - while ((pos = name.find("\\", pos+2)) != string::npos) - name.replace(pos, 1, "\\\\"); - fprintf(out, " newpath %g inch %g inch moveto (%s) centershow\n", label_x, label_y, name.c_str()); - } -} - -void Image_Printer::add_dirstamp() -{ - double label_x, label_y; - if (ipc->paper_eps->value()) - { - label_x = bb_ur_x/INCH - 0.25; - label_y = bb_ll_y/INCH - 0.25; - bb_ll_y -= 0.25*INCH + 5; - } - else - { - label_x = page_width - 0.25; - label_y = 0.25; - } - char buf[PATH_MAX]; - getcwd(buf, PATH_MAX); - string name = buf; - string::size_type pos=0; - while ((pos = name.find("\\", pos+2)) != string::npos) - name.replace(pos, 1, "\\\\"); - fprintf(out,"/%s findfont %g scalefont setfont\n",ipc->face->value(),10.0); - fprintf(out, " newpath %g inch %g inch moveto (%s) rightshow\n", label_x, label_y, name.c_str()); -} diff --git a/spyview/ImageWindow.C.~1.295.~ b/spyview/ImageWindow.C.~1.295.~ deleted file mode 100644 index 8b9fde6..0000000 --- a/spyview/ImageWindow.C.~1.295.~ +++ /dev/null @@ -1,2710 +0,0 @@ -#include -#include -#include -#include -#include "ImageWindow.H" -#include "ImagePrinter.H" -#include "math.h" -#include "message.h" -#include -#include -#include "throttle.H" -#include "ImageWindow_Module.H" -#include - -#ifdef WIN32 - -#include - -// For win32 gettimeofday(): -// Copied from http://www.cpp-programming.net/c-tidbits/gettimeofday-function-for-windows/ -#include -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif - -#endif - -// Bitwise if and only if -//#define iff(A,B) ((A & B) && !(A & !B)) -// not as useful as I thought since events also include numlock... - -#define ctrl(state) ( (state & FL_CTRL) && !(state & FL_SHIFT) && !(state & FL_ALT)) -#define shift(state) (!(state & FL_CTRL) && (state & FL_SHIFT) && !(state & FL_ALT)) -#define alt(state) (!(state & FL_CTRL) && !(state & FL_SHIFT) && (state & FL_ALT)) -#define none(state) (!(state & FL_CTRL) && !(state & FL_SHIFT) && !(state & FL_ALT)) - -using namespace std; - -FILE *fopenwarn(const char *name, const char *mode) -{ - FILE *fp = fopen(name, mode); - - if (fp == NULL) - warn("Could not open file %s in mode \"%s\": %s\n", name, mode, strerror(errno)); - return fp; -} - -static void nognuplot() -{ - static bool warned = false; - if(warned) - return; -#ifdef WIN32 - warn("Gnuplot is not available. Please install gnuplot for windows and put it on your path.\n"); -#else - warn("Unable to open gnuplot\n"); -#endif -} - - -void ImageWindow::make_tmpfiles() -{ - - // If we can, we will use local files xsection.dat, hist.dat and - // cmap.dat in the current directory, as a convenient way to give - // the user access to this data - // - // If we can't (ie. directory is read only), we will use files in /tmp. - - FILE *fp; - static int ntries; - - snprintf(xsection_fn, sizeof(xsection_fn), "%sxsection.%d.dat.%d", Gnuplot_Interface::tmpdir(), ntries, getpid()); - if ((fp = fopen(xsection_fn, "w")) == NULL) - { error("Failed to create tempfile %s: %s\n", xsection_fn, strerror(errno)); } - else fclose(fp); - - snprintf(xsection_tmp_fn, sizeof(xsection_fn), "%sxsection.%d.dat.tmp_%d", Gnuplot_Interface::tmpdir(), ntries, getpid()); - if ((fp = fopen(xsection_fn, "w")) == NULL) - { error("Failed to create tempfile %s: %s\n", xsection_tmp_fn, strerror(errno)); } - else fclose(fp); - - snprintf(cmap_fn, sizeof(cmap_fn), "%scmap.%d.dat.%d", Gnuplot_Interface::tmpdir(), ntries, getpid()); - if ((fp = fopen(cmap_fn, "w")) == NULL) - { error("Failed to create tempfile %s: %s\n", cmap_fn, strerror(errno)); } - else fclose(fp); - - snprintf(hist_fn, sizeof(hist_fn), "%shist.%d.dat.%d", Gnuplot_Interface::tmpdir(), ntries, getpid()); - if ((fp = fopen(hist_fn, "w")) == NULL) - { error("Failed to create tempfile %s: %s\n", hist_fn, strerror(errno)); } - else fclose(fp); - - info("Locations of temporary files:\n%s\n%s\n%s\n", xsection_fn, cmap_fn, hist_fn); -} - -ImageWindow::ImageWindow(int w, int h, const char *title) : - Fl_Overlay_Window(w,h) , ipc(this) , pfc(this) -{ - stupid_windows_focus = getenv("SPYVIEW_CLICKY") == NULL; - - gplinecut.bidirectional=true; - line_cut_limit = HORZLINE | VERTLINE | OTHERLINE | NOLINE; - //size_range(1,1); - zoomWindowDragging = ZOOM_NO; - statusCallback = NULL; - datamin = 0; datamax = LMAX; - hmin = 0; hmax = LMAX; - - xzoom = yzoom = 1; - swap_zoom_state=false; - square = 0; - line_cut_type = NOLINE; - line_cut_xauto = 1; - plot_hist = false; - plot_cmap = false; - bpercent = 0.1; wpercent = 0.1; - // plane_a = plane_b = plane_c = 0; - process_queue = NULL; - controls_window = NULL; - external_update = NULL; - drag_n_drop = NULL; - window_size_action = KEEPZOOM; - cmap_min = 0.0; - cmap_max = 1.0; - - sprintf(gp_using_string, "1:2"); - gp_with_string = "lp"; - - lc_axis = DISTANCE; - - make_tmpfiles(); - - // By default, install an 8 bit greyscale colormap. - colormap_length = 256; - colormap = new uchar[colormap_length*3]; - gammatable = new int[colormap_length]; - - for (int i=0; i<256; i++) - colormap[3*i] = colormap[3*i+1] = colormap[3*i+2] = i; - - gam = 1; - gcenter = 0.0; - for (int i=0; i<256; i++) - gammatable[i] = i; - - // Create the colormap window - colormap_window = new ColormapWindow(256,25); - colormap_window->img = this; - colormap_window->label("Colormap"); - // Colormap window is now controlled from UI. Don't show by default. - // colormap_window->show(); - - imageprinter = new Image_Printer(this, &ipc); - - // Note: pfc is initialized with the constructor of ImageWindow - pf = new PeakFinder(this, &pfc); -} - -void ImageWindow::resize(int x, int y, int wp, int hp) -{ - int target_xzoom, target_yzoom; - - // This is tricky... - - if (wp == w) target_xzoom = 1; // Zoom should be 1 - else if (wp*(-xzoom) == w) target_xzoom = -w/wp; // Requested size corresponds exactly to a negative zoom - else if (wp < w && wp*(-xzoom) != w) target_xzoom = -w/(wp+1)-1; //Negative zoom, need to trucate downwards (-1) and be careful of images with odd number of points (wp+1) - else target_xzoom = wp/w; // Positive zoom: truncation has desired effect, odd number of points not a problem. - - if (hp == h) target_yzoom = 1; - else if (hp < h && hp*(-yzoom) != h) target_yzoom = -h/(hp+1)-1; - else if (hp*(-yzoom) == h) target_yzoom = -h/hp; - else target_yzoom = hp/h; - - if (xzoom != target_xzoom || yzoom != target_yzoom) - { - xzoom = target_xzoom; - yzoom = target_yzoom; - allocateImage(); - } - - external_update(); - size_range(1,1); - Fl_Overlay_Window::resize(x,y,wp,hp); -} - -ImageWindow::~ImageWindow() -{ - if(imageprinter) - delete imageprinter; - unlink(xsection_fn); - unlink(cmap_fn); - unlink(hist_fn); - unlink(xsection_tmp_fn); - unlink("xsection.dat"); - unlink("cmap.dat"); - unlink("hist.dat"); -} - -void ImageWindow::draw() -{ - if (!id.data_loaded) return; - imageprinter->updatePreview(); - - // data = original data read from file - // - // databuf = copy of data[] to store grey data in after we've performed integer - // operations, like rescaling the contrast using the imagehist lookup - // table, appling the gamma scaling using the gammatable lookup - // table, and performing the plane subtraction. - // - // Data starts off in data[] in whatever range of values that is - // occupied in the input image. - // - // After plane subtraction, data may exceed LMAX or be less than 0, - // so we need to trucate these values. - // - // The data between hmin and hmax then gets mapped to 0 to LMAX by - // the imagehist lookup table. - // - // The gammatable lookup is then applied, and each pixel in the - // databuf array will then have a value that ranges from 0 to - // colormap_length-1. - // - // In the final step, the colormap lookup table is applied, which is - // used to map the data onto a 8x8x8 bit RGB image. - - // warn("Drawing %dx%d image, xzoom=%d, yzoom=%d, total=%dx%d (%d bytes)\n", - // w,h,xzoom,yzoom,w*xzoom,h*yzoom,3*(w*xzoom+h*yzoom)); - - // This next chunk of code centers the image. It should only matter if we're displaying an image bigger than - // 255x255, in which case by resizing the window manually, the user can make the window not be an intereger - // zoom of the original image. - // Zooming by using < and > will still always give an integer zoom. - int ox, oy; // X and Y offsets. - ox = Fl_Overlay_Window::w() - w*xzoom; - oy = Fl_Overlay_Window::h() - h*yzoom; - if(ox != 0 || oy != 0) - { - ox /= 2; // Center the image. We don't do this outside the if so if the image is only 1 pixel too small, - oy /= 2; // we still fill in the border in black. - fl_color(FL_BLACK); - fl_rectf(0,0,Fl_Overlay_Window::w(), Fl_Overlay_Window::h()); - } - ox=0; // Argh! Centering the image kills the line cuts! Too lazy to fix this right. - oy=0; - - // Ok, let's finally clean this up a bit. I will now make this - // compatible with "negative" zoom (ie. shrinking the image). To - // keep things simple at first, I will do this by just skipping - // points (a smarter thing to do would be to average). - - int row, col; // column and row in the data file - int imgcol, imgrow; // column and row in the image output file - int n, m; // repeat indices for col and row - int iw, ih; - - iw = dozoom(w,xzoom); - ih = dozoom(h,yzoom); - - row = 0; n = 0; - while (row ih-1) break; - - col = 0; m = 0; - while (col iw-1) break; - - // Now actually decide on a color for the pixel - - unsigned char r,g,b; - getrgb(row,col,r,g,b); - - image[3*imgrow*iw+3*imgcol] = r; - image[3*imgrow*iw+3*imgcol+1] = g; - image[3*imgrow*iw+3*imgcol+2] = b; - - if (3*imgrow*iw+3*imgcol+2 > dozoom(w,xzoom)*dozoom(h,yzoom)*3) - { - warn( "row %d col %d n %d m %d ir %d ic %d iw %d ih %d iw*ih*3 %d over bounds %d > %d\n", - row, col, n, m, imgrow, imgcol, iw, ih, iw*ih*3, 3*imgrow*iw+3*imgcol+2, - dozoom(w,xzoom)*dozoom(h,yzoom)*3); - exit(-1); - } - if (xzoom < 0 || m == xzoom-1) - { - m=0; col++; - if (col == w) break; - else continue; - } - else - { - m++; continue; - } - } - - if (yzoom < 0 || n == yzoom-1) - { - n=0; row++; - if (row == h) break; - else continue; - } - else - { - n++; continue; - } - } - - fl_draw_image(image, ox, oy, iw, ih, 3, 0); - if(zoom_window) - zoom_window->redraw(); -} - -void ImageWindow::draw_overlay() -{ - if (pfc.hide_data->value()) - fl_rectf(0,0,dozoom(w,xzoom),dozoom(h,yzoom),0,0,0); - - imageprinter->updatePreview(); - if (line_cut_type) - { - fl_color(FL_RED); - if (line_cut_type == HORZLINE) - fl_line(dozoom(w,xzoom),dozoom(line_cut_yp,yzoom)+dozoom(1,yzoom)/2, - 0,dozoom(line_cut_yp,yzoom)+dozoom(1,yzoom)/2); - else if (line_cut_type == VERTLINE) - fl_line(dozoom(line_cut_xp,xzoom)+dozoom(xzoom,1)/2,0, - dozoom(line_cut_xp,xzoom)+dozoom(xzoom,1)/2,dozoom(h,yzoom)); - else if (line_cut_type == OTHERLINE) - fl_line(dozoom(lcx1,xzoom)+dozoom(1,xzoom)/2, - dozoom(lcy1,yzoom)+dozoom(1,yzoom)/2, - dozoom(lcx2,xzoom)+dozoom(1,xzoom)/2, - dozoom(lcy2,yzoom)+dozoom(1,yzoom)/2); - } - - if((zoom_window && zoom_window->visible()) || (zoomWindowDragging)) - { - fl_color(FL_GREEN); - if(!zoomWindowDragging) - zoom_window->getSourceArea(zwd_x1,zwd_y1,zwd_x2,zwd_y2); - int x2off = (xzoom > 0) ? 1 : 0; - int y2off = (yzoom > 0) ? 1 : 0; - fl_line(dozoom(zwd_x1,xzoom), - dozoom(zwd_y1,yzoom), - dozoom(zwd_x2,xzoom)-x2off, - dozoom(zwd_y1,yzoom)); - fl_line(dozoom(zwd_x2,xzoom)-x2off, - dozoom(zwd_y1,yzoom), - dozoom(zwd_x2,xzoom)-x2off, - dozoom(zwd_y2,yzoom)-y2off); - fl_line(dozoom(zwd_x2,xzoom)-x2off, - dozoom(zwd_y2,yzoom)-y2off, - dozoom(zwd_x1,xzoom), - dozoom(zwd_y2,yzoom)-y2off); - fl_line(dozoom(zwd_x1,xzoom), - dozoom(zwd_y2,yzoom)-y2off, - dozoom(zwd_x1,xzoom), - dozoom(zwd_y1,yzoom)); - } - - if(pf->peaks != NULL && (pfc.plot_peaks->value() || pfc.plot_valleys->value())) - { - for (int j=0; j=pf->w || j>=pf->h) - // So that we can plot peaks from previous IP settings - // on top of current data without a segfault - continue; - if (pf->peaks[j*w+i] == 1 && pfc.plot_peaks->value()) - draw_overlay_pixel(i,j,pfc.peak_color_box->color()); - else if (pf->peaks[j*w+i] == -1 && pfc.plot_valleys->value()) - draw_overlay_pixel(i,j,pfc.valley_color_box->color()); - } - } - } - - for(modules_t::iterator i = modules.begin(); i != modules.end(); i++) - (*i)->overlay_callback(); -} - -void ImageWindow::draw_overlay_pixel(int i, int j, Fl_Color color) -{ - int rw = (xzoom < 0) ? 1 : xzoom; - int rh = (yzoom < 0) ? 1 : yzoom; - fl_color(color); - fl_rectf(dozoom(i,xzoom), dozoom(j,yzoom), rw, rh); -} - -void ImageWindow::draw_overlay_pixel(int i, int j, uchar r, uchar g, uchar b) -{ - int rw = (xzoom < 0) ? 1 : xzoom; - int rh = (yzoom < 0) ? 1 : yzoom; - fl_color(r,g,b); - fl_rectf(dozoom(i,xzoom), dozoom(j,yzoom), rw, rh); -} - -void ImageWindow::makeZoomWindow() -{ - if(zoom_window == NULL) - { - zoom_window = new ZoomWindow(dozoom(w,xzoom)/5,dozoom(h,yzoom)/5); // *.1 * 2 = /5, 10% of image size (default zoom is 2) - zoom_window->img = this; - zoom_window->size_range(1,1); - if (xzoom > 1) zoom_window->xscale *= xzoom; - if (yzoom > 1) zoom_window->yscale *= yzoom; - } -} -void ImageWindow::showZoomWindow(bool toggle) -{ - makeZoomWindow(); - if(zoom_window->visible() && toggle) - zoom_window->hide(); - else - zoom_window->show(); -} - -// Helper function for the middle-shift button below. -inline static double distance_squared(double x1, double y1, double x2, double y2) -{ - x1 -= x2; - y1 -= y2; - return x1*x1+y1*y1; -} - -// Check to see if (x1,y1) is closer to (x2,y2) than squared-distance distance. If it is, update -// distance to the distance between them, and set zoomWindowDragging to zw -// Helper function for the middle-shift button below. -void ImageWindow::tryZoomCorner(int x1, int y1, int x2, int y2, zoomWindowDragging_t zw, double &dist) -{ - double nd = distance_squared(x1,y1,x2,y2); - if(nd < dist) - { - dist = nd; - zoomWindowDragging = zw; - } -} - -// adapted from from http://www.cpp-programming.net/c-tidbits/gettimeofday-function-for-windows/ -double current_time() -{ - struct timeval stop; -#ifndef WIN32 - gettimeofday(&stop, NULL); -#else - FILETIME ft; - unsigned __int64 tmpres = 0; - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - /*converting file time to unix epoch*/ - tmpres /= 10; /*convert into microseconds*/ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - stop.tv_sec = (long)(tmpres / 1000000UL); - stop.tv_usec = (long)(tmpres % 1000000UL); -#endif - double time = (((double)(stop.tv_sec)) + ((double)(stop.tv_usec) * 1e-6)); - if (!isnormal(time)) - info("time %e sec %d usec %d\n", time, stop.tv_sec, stop.tv_usec); - return time; -} - -int ImageWindow::handle(int event) -{ - static double lastFocus = 0; // Time when we got the focus, or NAN if we don't have the focus. - static double t0Focus = current_time(); // Just a handy offset for debug messages - static bool hungryFocus = false; // If this is true, we're eating push/drag events because this was the click that focused the mouse. - static bool inFocus = false; // This is set to true when we get a focus event - //if (event == FL_ENTER) - // info("got FL_ENTER\n"); - //if (event == FL_MOVE) - // info("got FL_MOVE\n"); - //Fl_Window::handle() was stealing our FL_ENTER and FL_MOVE events - //if (Fl_Window::handle(event)) return 1; - - for(modules_t::iterator i = modules.begin(); i != modules.end(); i++) - { - int r = (*i)->event_callback(event); - if(r) - return r; - } - - int n; - int button = Fl::event_button(); - - if ((button == 3) && (Fl::event_state() & FL_ALT)) - button = 2; - - switch (event) - { - // Drag and drop - case FL_DND_ENTER: // return(1) for these events to 'accept' dnd - case FL_DND_DRAG: - case FL_DND_RELEASE: - return(1); - case FL_PASTE: // handle actual drop (paste) operation - (*drag_n_drop)(Fl::event_text()); - return(1); - case FL_SHOW: - // Use a cross cursor - cursor(FL_CURSOR_CROSS); - break; - case FL_KEYUP: - n = Fl::event_key(); - if(statusCallback) - statusCallback(n,false); - break; - case FL_KEYDOWN: - n = Fl::event_key(); - if(statusCallback) - statusCallback(n,true); - switch(n) - { -// case 'd': -// dumpColormap(); -// return 1; - case 's': - switch(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT)) - { - case FL_ALT: - // Snap the window size to the actual image size - size(dozoom(w,xzoom), dozoom(h,yzoom)); - return 1; - case FL_CTRL: - if(zoom_window) - { - zoom_window->autonormalize = !zoom_window->autonormalize; - return 1; - } - // Falling case - case FL_SHIFT: - normalizeOnZoom(); - return 1; - } - break; - case 'z': - if (Fl::event_state() & FL_CTRL) - exportMTX(false, true); - else - showZoomWindow(true); - return 1; - break; - case '.': - if (Fl::event_state() & FL_SHIFT) - { - setXZoom(xzoom+1); - damage(FL_DAMAGE_ALL); - } - else if (Fl::event_state() & FL_CTRL) - { - setYZoom(yzoom+1); - damage(FL_DAMAGE_ALL); - - } - else - { - setXZoom(xzoom+1); - setYZoom(yzoom+1); - damage(FL_DAMAGE_ALL); - } - return 1; - case ',': - if (Fl::event_state() & FL_SHIFT) - { - setXZoom(xzoom-1); - damage(FL_DAMAGE_ALL); - } - - else if (Fl::event_state() & FL_CTRL) - { - setYZoom(yzoom-1); - damage(FL_DAMAGE_ALL); - - } - else - { - setXZoom(xzoom-1); - setYZoom(yzoom-1); - damage(FL_DAMAGE_ALL); - } - return 1; - case '1': - if (Fl::event_state() & FL_SHIFT) - (xzoom > yzoom) ? setXZoom(yzoom) : setYZoom(xzoom); - else - (xzoom > yzoom) ? setYZoom(xzoom) : setXZoom(yzoom); - damage(FL_DAMAGE_ALL); - return 1; -// case 'i': -// invert = !invert; -// plotCmap(); -// redraw(); -// colormap_window->update(); -// if (external_update != NULL) -// (*external_update)(); -// return 1; -// case 'h': -// plot_hist = !plot_hist; -// plotHist(); -// if (external_update != NULL) -// (*external_update)(); -// return 1; - default: - if(isalpha(n)) - { - char buf[4096]; - const char *cmd = getenv("SPYVIEW_EXTERNAL"); - if(cmd == NULL) - break; - int ix = get_event_x(); - int iy = get_event_y(); - snprintf(buf,sizeof(buf),"%s %c %g %g %d %d", cmd, n, id.getX(ix), id.getY(iy),ix, iy); - int res = system(buf); - if(res == -1) - warn("Unable to run command: \"%s\": %s\n",buf, strerror(errno)); - if(res == 0) - { - info("Reloading: \"%s\"\n",filename.c_str()); - string s = filename; // We copy here because loadData nukes filename right away. - loadData(s.c_str()); - } - } - break; - - } - break; - - case FL_MOVE: - if(statusCallback) - statusCallback(-1,true); - break; - - case FL_FOCUS: - lastFocus = current_time(); - inFocus = true; - //info("focus event time %g\n", lastFocus); - //fprintf(stderr,"recieved focus %g time %g t0 %g\n",lastFocus-t0Focus, lastFocus, t0Focus); - return Fl_Overlay_Window::handle(event); - - case FL_UNFOCUS: - lastFocus = NAN; - inFocus = false; - //fprintf(stderr,"Defocus %g at time %g t0 %g\n",current_time()-t0Focus, current_time(), t0Focus); - return Fl_Overlay_Window::handle(event); - -/* Focus logic: - When we are focused, ignore the *FIRST* mouse click if it occurs within 50 ms of becoming focused. This way, if the user - focuses the window with a non-mouse click action (alt-tab), we're in good shape as long as they're not *really* fast. In - practice, I usually see the click event comes within a few microseconds (!) of the focus event (under wine) - If we ignored a click, ignore follow-up drag and release events, unless the user keeps the button down for at least - one second. If they do, assume they're frustrated and give in. - If we get a click when unfocused, assume it's an immediate prelude to being focused and treat it as a click within 50ms of - getting focused. This never seems to happen (under my WM in Linux and wine. Probably smart to leave the logic in) -*/ - - case FL_PUSH: - if(isnan(lastFocus) && stupid_windows_focus) - { - fprintf(stderr,"Ate unfocused click. This apparently never happens.\n"); - hungryFocus = true; - lastFocus = current_time(); - return Fl_Overlay_Window::handle(event); - } - // Warning: you can have an unfocused drag or release under linux; we shouldn't eat these! - // For this reason, we will only eat things if we are in focus - case FL_DRAG: // Falling case! - case FL_RELEASE: - - // For FL_DRAG, we cannot rely on Fl::event_button() (although - // it seems to work on unix) I don't know why I can't replace - // the Fl::event_buttion() above with this, but if I do, the - // zoom window stops working... - if (Fl::event_state() & FL_BUTTON1) - button = 1; - else if (Fl::event_state() & FL_BUTTON2) - button = 2; - else if (Fl::event_state() & FL_BUTTON3) - { - if (Fl::event_state() & FL_ALT) - button = 2; - else - button = 3; - } - // Let's only eat a non-modified button 1 click - if(stupid_windows_focus && (button == 1) && !(Fl::event_state() & FL_SHIFT) && !(Fl::event_state() & FL_CTRL)) - { - if (hungryFocus) - { - if (inFocus) - { - if(event == FL_RELEASE || (current_time() - lastFocus >= 0.1)) - { - //fprintf(stderr,"Focus eating is done (100 ms after initial click) %g\n",current_time()-lastFocus); - lastFocus = 0; - hungryFocus = false; - return Fl_Overlay_Window::handle(event); - } - else - { - fprintf(stderr,"Ate drag/release event, t<100 ms after focus click %g\n",current_time()-lastFocus); - return Fl_Overlay_Window::handle(event); - } - } - } - else if ((current_time() - lastFocus < 0.05)) - { - //fprintf(stderr,"Ate initial click (%g) last %g t0 %g\n",lastFocus-t0Focus, lastFocus, t0Focus); - hungryFocus = true; - return Fl_Overlay_Window::handle(event); - } - } - - if(statusCallback) - statusCallback(-1,true); - - int state = Fl::event_state(); - int tmp; - double d1,d2; - if (none(state) || alt(state)) // horz/vert LC - switch(button) - { - case 1: - tmp = get_event_y(); - if (tmp > h-1) - tmp = h-1; - if (line_cut_yp < 0) - tmp = 0; - if (line_cut_yp == tmp && line_cut_type == HORZLINE) - return 1; - if(!(line_cut_limit & HORZLINE)) - return 1; - line_cut_yp = tmp; - line_cut_type = HORZLINE; - plotLineCut(); - redraw_overlay(); - return 1; - case 3: - if(!alt(state)) - break; // Right-alt is vertical, but not right-unshifted. - case 2: - tmp = get_event_x(); - if (tmp > w-1) - tmp = w-1; - if (tmp < 0) - tmp = 0; - if (line_cut_xp == tmp && line_cut_type == VERTLINE) return 1; - if(!(line_cut_limit & VERTLINE)) - return 1; - line_cut_xp = tmp; - line_cut_type = VERTLINE; - plotLineCut(); - redraw_overlay(); - return 1; - default: - return Fl_Overlay_Window::handle(event); - } - else if (shift(state)) // zoom windows (this is a long one) - switch(button) - { - case 1: - switch(event) - { - case FL_PUSH: - zwd_x1 = get_event_x(); - zwd_y1 = get_event_y(); - zwd_x2 = zwd_x1; - zwd_y2 = zwd_y1; - zoomWindowDragging = ZOOM_DRAG; - break; - case FL_RELEASE: - zwd_x2 = get_event_x(); - zwd_y2 = get_event_y(); - makeZoomWindow(); - zoom_window->center_x = (zwd_x1+zwd_x2)/2; - zoom_window->center_y = (zwd_y1+zwd_y2)/2; - zoom_window->size((abs(zwd_x2-zwd_x1))*zoom_window->xscale, (abs(zwd_y2-zwd_y1))*zoom_window->yscale); - showZoomWindow(); - zoom_window->zoomMoved(); - zoomWindowDragging = ZOOM_NO; - break; - case FL_DRAG: - zwd_x2 = get_event_x(); - zwd_y2 = get_event_y(); - redraw_overlay(); - break; - } - break; - case 2: - if(zoom_window == NULL) - return 1; - switch(event) - { - case FL_PUSH: - { - int mx1 = get_event_x(); - int my1 = get_event_y(); - zoom_window->getSourceArea(zwd_x1,zwd_y1,zwd_x2,zwd_y2); - zoomWindowDragging = ZOOM_RESIZE_NW; - double distance = distance_squared(mx1,my1, zwd_x1,zwd_y1); - tryZoomCorner(mx1,my1,zwd_x1,zwd_y2,ZOOM_RESIZE_SW,distance); - tryZoomCorner(mx1,my1,zwd_x2,zwd_y1,ZOOM_RESIZE_NE,distance); - tryZoomCorner(mx1,my1,zwd_x2,zwd_y2,ZOOM_RESIZE_SE,distance); - } // Warning! Falling case! - case FL_DRAG: - { - switch(zoomWindowDragging) - { - case ZOOM_RESIZE_NW: zwd_x1 = get_event_x(); zwd_y1 = get_event_y(); break; - case ZOOM_RESIZE_SW: zwd_x1 = get_event_x(); zwd_y2 = get_event_y(); break; - case ZOOM_RESIZE_NE: zwd_x2 = get_event_x(); zwd_y1 = get_event_y(); break; - case ZOOM_RESIZE_SE: zwd_x2 = get_event_x(); zwd_y2 = get_event_y(); break; - case ZOOM_NO: case ZOOM_DRAG: info("Unusual event; hard to get here.\n"); break; - } - redraw_overlay(); - return 1; - } - case FL_RELEASE: - switch(zoomWindowDragging) - { - case ZOOM_RESIZE_NW: zwd_x1 = get_event_x(); zwd_y1 = get_event_y(); break; - case ZOOM_RESIZE_SW: zwd_x1 = get_event_x(); zwd_y2 = get_event_y(); break; - case ZOOM_RESIZE_NE: zwd_x2 = get_event_x(); zwd_y1 = get_event_y(); break; - case ZOOM_RESIZE_SE: zwd_x2 = get_event_x(); zwd_y2 = get_event_y(); break; - case ZOOM_NO: case ZOOM_DRAG: info("Unusual event; hard to get here.\n"); break; - } - zoom_window->center_x = (zwd_x1+zwd_x2)/2; - zoom_window->center_y = (zwd_y1+zwd_y2)/2; - zoom_window->size((abs(zwd_x2-zwd_x1))*zoom_window->xscale, (abs(zwd_y2-zwd_y1))*zoom_window->yscale); - showZoomWindow(); - zoomWindowDragging = ZOOM_NO; - zoom_window->zoomMoved(); - return 1; - } - break; - case 3: - showZoomWindow(); - zoom_window->center_x = get_event_x(); - zoom_window->center_y = get_event_y(); - zoom_window->zoomMoved(); - return 1; - default: - return Fl_Overlay_Window::handle(event); - } - else if (ctrl(state)) // arb LC - switch (button) - { - case 1: - if (event == FL_PUSH) - { - lcx1 = lcx2 = get_event_x(); - lcy1 = lcy2 = get_event_y(); - line_cut_type = OTHERLINE; - redraw_overlay(); - return 1; - } - else //if (event == FL_DRAG) // Button 1 + control + drag (arb line cut) - { - lcx2 = get_event_x(); - lcy2 = get_event_y(); - if (lcx2 < 0) lcx2 = 0; - if (lcy2 < 0) lcy2 = 0; - if (lcx2 > w-1) lcx2 = w-1; - if (lcy2 > h-1) lcy2 = h-1; - plotLineCut(); - redraw_overlay(); - return 1; - } - case 2: - static int pointnum = 0; - int nx, ny; - nx = get_event_x(); - ny = get_event_y(); - if (nx < 0) nx = 0; - if (ny < 0) ny = 0; - if (nx > w-1) nx = w-1; - if (ny > h-1) ny = h-1; - d1 = sqrt(static_cast((nx-lcx1)*(nx-lcx1)+(ny-lcy1)*(ny-lcy1))); - d2 = sqrt(static_cast((nx-lcx2)*(nx-lcx2)+(ny-lcy2)*(ny-lcy2))); - if (event == FL_PUSH) - { - if (d1 < d2) - { lcx1 = nx; lcy1 = ny; pointnum = 1;} - else - { lcx2 = nx; lcy2 = ny; pointnum = 2;} - } - else if (event == FL_DRAG) - { - if (pointnum == 1) - { lcx1 = nx; lcy1 = ny; } - else if (pointnum == 2) - { lcx2 = nx; lcy2 = ny; } - } - plotLineCut(); - redraw_overlay(); - return 1; - case 3: - static int x0, y0, x1, y1; // Mouse coord at push and then at drag - static int lcx1i, lcy1i, lcx2i, lcy2i; // Initial line endpoint on the push - int dx, dy; // displacments - if (event == FL_PUSH) // Pushing button 3 + control (arb line cut) - { - if(!(line_cut_limit & OTHERLINE)) - return 1; - x0 = get_event_x(); - y0 = get_event_y(); - lcx1i = lcx1; - lcx2i = lcx2; - lcy1i = lcy1; - lcy2i = lcy2; - line_cut_type = OTHERLINE; - return 1; - } - else if (event == FL_DRAG) // Dragging button 3 + control (arb line cut) - { - x1 = get_event_x(); - y1 = get_event_y(); - dx = x1-x0; - dy = y1-y0; - if (lcx1i+dx < 0) dx = -lcx1i; - if (lcx1i+dx > w-1) dx = w-1-lcx1i; - if (lcx2i+dx < 0) dx = -lcx2i; - if (lcx2i+dx > w-1) dx = w-1-lcx2i; - if (lcy1i+dy < 0) dy = -lcy1i; - if (lcy1i+dy > h-1) dy = h-1-lcy1i; - if (lcy2i+dy < 0) dy = -lcy2i; - if (lcy2i+dy > h-1) dy = h-1-lcy2i; - if (dx == 0 && dy == 0 && line_cut_type == OTHERLINE) return 1; - lcx1 = lcx1i + dx; lcx2 = lcx2i + dx; - lcy1 = lcy1i + dy; lcy2 = lcy2i + dy; - line_cut_type = OTHERLINE; - plotLineCut(); - redraw_overlay(); - return 1; - } - default: - return Fl_Overlay_Window::handle(event); - } - // no modifiers, or multiple modifiers... - if (button == 3 && controls_window != NULL && event == FL_PUSH) - { - if (controls_window->visible()) - controls_window->hide(); - else - controls_window->show(); - return 1; - } - break; - } - return 0; -} - -double ImageWindow::dataval(int x, int y) -{ - if (x>=0 && x=0 && y throttle(this,&ImageWindow::plotLineCut); - if(!(nothrottle || throttle.throttle())) - return; - - FILE *fp; - if (line_cut_type == NOLINE) - { - if (gplinecut.isopen()) - { - // set term x11 close doesn't work if the terminal type is not wxt. - // Newer versions of gnuplot default to wxt. - // Safer to kill gnuplot; of course, this "forgets" where the window was. - gplinecut.close(); - } - return; - } - - if (!gplinecut.isopen()) - { - gplinecut.open(); - if(!gplinecut.open()) - { - nognuplot(); - return; - } - gplinecut.cmd("set style data %s\n", gp_with_string.c_str()); - } - - if ((fp = fopen(xsection_fn, "w")) == NULL) - { - error("Error opening file \"%s\": %s\n", xsection_tmp_fn, strerror(errno)); - - return; - } - unlink("xsection.dat"); -#ifdef HAVE_SYMLINK -// just so that we always have a file in the current dir where we can easily access the data - if(symlink(xsection_fn, "xsection.dat") != 0) - fprintf(stderr,"Error creating xsection.dat symlink: %s\n",strerror(errno)); -#endif - - // OK, let's give this a real cleanup. - // We will plot the real, unquantized raw data, with as little permutation as possible. - - double xstep; - double ystep; - string axname; - int x1,x2,y1,y2; - double ax1, ax2; - - int npeaks = 0; - int nvalleys = 0; - double peak, valley; - - if (line_cut_type == HORZLINE) - { - int j = line_cut_yp; - for (int i=0; i < w; i++) - { - fprintf(fp, "%e %e ", id.getX(i), dataval(i,j)); - if (pf->peaks != NULL && pfc.plot_peaks->value() && pf->peaks[j*w+i] == 1) - { - npeaks++; - fprintf(fp, "%e ", dataval(i,j)); - } - else fprintf(fp, "none "); - if (pf->peaks != NULL && pfc.plot_valleys->value() && pf->peaks[j*w+i] == -1) - { - nvalleys++; - fprintf(fp, "%e\n", dataval(i,j)); - } - else fprintf(fp, "none\n"); - } - x1 = 0; x2 = w; - y1 = y2 = line_cut_yp; - axname = id.xname; - ax1 = id.getX(x1); - ax2 = id.getX(x2); - } - else if (line_cut_type == VERTLINE) - { - int i = line_cut_xp; - for (int j=0; j < h; j++) - { - fprintf(fp, "%e %e ", id.getY(j), dataval(i,j)); - if (pf->peaks != NULL && pfc.plot_peaks->value() && pf->peaks[j*w+i] == 1) - { - npeaks++; - fprintf(fp, "%e ", dataval(i,j)); - } - else fprintf(fp, "none "); - if (pf->peaks != NULL && pfc.plot_valleys->value() && pf->peaks[j*w+i] == -1) - { - nvalleys++; - fprintf(fp, "%e\n", dataval(i,j)); - } - else fprintf(fp, "none\n"); - } - x1 = x2 = line_cut_xp; - y1 = h; y2 = 0; - axname= id.yname; - ax1 = id.getY(y1); - ax2 = id.getY(y2); - } - else // otherwise, we'll use bilinear interpolation - { - int num_steps, n; - x1 = lcx1; x2 = lcx2; - y1 = lcy1; y2 = lcy2; - - if (x1 == x2 && y1 == y2) return; - - double i,j; - double i1,j1; - double i2,j2; - double d1,d2,d; - double x; - bool step_x; - - if (abs(x2-x1) > abs(y2-y1)) - { - step_x = true; - num_steps = abs(x2-x1); - xstep = 1.0*(x2-x1)/num_steps; - ystep = 1.0*(y2-y1)/num_steps; - } - else - { - step_x = false; - num_steps = abs(y2-y1); - ystep = 1.0*(y2-y1)/num_steps; - xstep = 1.0*(x2-x1)/num_steps; - } - - i = x1; j = y1; - for (n=0; nlinecut_callback(true); - - char buf[1024]; - gplinecut.cmd("set xlabel '%s';\n" - "set ylabel '%s';\n" - "set title \"%s \\n Line cut: %s %g to %g, %s %g to %g\";\n" - "plot '%s' u %s w %s t 'x %d %d y %d %d'", - axname.c_str(), - id.zname.c_str(), - Gnuplot_Interface::escape(filename).c_str(), - id.xname.c_str(), id.getX(x1), id.getX(x2), - id.yname.c_str(), id.getY(y1), id.getY(y2), - xsection_fn, gp_using_string, gp_with_string.c_str(), - x1, x2, y1, y2); - if (npeaks != 0) - gplinecut.cmd(", '' u 1:3 w p pt 5 t 'Peaks'"); - if (nvalleys != 0) - gplinecut.cmd(", '' u 1:4 w p pt 5 t 'Valleys'"); - - - for(modules_t::iterator i = modules.begin(); i != modules.end(); i++) - (*i)->linecut_callback(false); - - gplinecut.cmd("\n"); -} - -void ImageWindow::plotCmap() -{ - static Throttle throttle(this,&ImageWindow::plotCmap); - if(!throttle.throttle()) - return; - int i,j; - if (plot_cmap) - { - if (!gpcmap.isopen()) - { - if(!gpcmap.open()) - { - nognuplot(); - return; - } - } - FILE *fp = fopen(cmap_fn, "w"); - if (fp == NULL) - { - error("Error opening file \"%s\": %s\n", cmap_fn, strerror(errno)); - return; - } - unlink("cmap.dat"); -#ifdef HAVE_SYMLINK - symlink(cmap_fn, "cmap.dat"); -#endif - for (i = 0; i < colormap_length; i++) - { - j = gammatable[i]; - fprintf(fp, "%d %d %d %d\n", i ,colormap[3*j], colormap[3*j+1], colormap[3*j+2]); - } - fclose(fp); - gpcmap.cmd("set xrange [0:%d]; set yrange [0:255];" - "set data style linespoints; set nokey;\n", colormap_length); - gpcmap.cmd("plot '%s' u 1:2, '' u 1:3, '' u 1:4\n",cmap_fn); - } - else if (gpcmap.isopen()) - gpcmap.close(); -} - -void ImageWindow::plotHist() -{ - static Throttle throttle(this,&ImageWindow::plotHist); - if(!throttle.throttle()) - return; - int i, min, max, inc, bintotal; - if (plot_hist) - { - if(!gphist.isopen()) - { - if(!gphist.open()) - { - nognuplot(); - return; - } - } - FILE *fp = fopen(hist_fn, "w"); - if (fp == NULL) - { - error("Error opening file \"%s\": %s\n", hist_fn, strerror(errno)); - return; - } - unlink("hist.dat"); -#ifdef HAVE_SYMLINK - symlink(hist_fn, "hist.dat"); -#endif - min = (hmin < datamin) ? hmin : datamin; - max = (hmax > datamax) ? hmax : datamax; - inc = (datamax - datamin)/300; - if (inc < 1) inc = 1; - bintotal=0; - for (i = min ; i < max+inc && i < 65535 ; i++) - { - bintotal += datahist[i]; - if ( (i%inc) == 0) - { - fprintf(fp, "%d %e %d %d\n",i, id.quant_to_raw(i), bintotal, - ((hmax-inc>=i && hmax-inc<=(i+inc-1)) ? 1 : 0) + - ((hmin+inc>=i && hmin+inc<=(i+inc-1)) ? 1 : 0)); - bintotal = 0; - } - } - fclose(fp); - gphist.cmd("set x2range [%d:%d]; set xrange [%e:%e]; " - "set x2tics; set yrange [1e-1:*];" - "set style data boxes; set style fill solid;\n" - "set nokey; set title '%s';" - "set xlabel '%s'; set x2label 'Gray Value'\n", - min-3*inc, max+3*inc, id.quant_to_raw(min-3*inc), id.quant_to_raw(max+3*inc), hist_fn, id.zname.c_str()); - gphist.cmd("plot '%s' u 1:4 ax x2y2 lt 2, '' u 1:3 ax x2y1 lt 1\n", hist_fn); - } - else if (gphist.isopen()) - { - gphist.close(); - } -} - -void ImageWindow::setMin(int m) -{ - if (m > LMAX) m = LMAX; - if (m < 0) m = 0; - hmin = m; - if (hmax < hmin) - hmin = hmax; -} - -void ImageWindow::setMax(int m) -{ - if (m > LMAX) m = LMAX; - if (m < 0) m = 0; - hmax = m; - if (hmin > hmax) - hmax = hmin; -} - -void ImageWindow::allocateImage() -{ - int newsize=(dozoom(w,xzoom))*(dozoom(h,yzoom))*3; - zap(image); - image = new uchar [newsize]; -} - - -void ImageWindow::setXZoom(int xz) -{ - if (xz == 0 || xz == -1) - { - if (xzoom > xz) xzoom = -2; - else xzoom = 1; - } - else xzoom = xz; - - allocateImage(); - size(dozoom(w,xzoom), dozoom(h,yzoom)); -} - -void ImageWindow::setYZoom(int yz) -{ - if (yz == 0 || yz == -1) - { - if (yzoom > yz) yzoom = -2; - else yzoom = 1; - } - else yzoom = yz; - - allocateImage(); - size(dozoom(w,xzoom), dozoom(h,yzoom)); -} - -void ImageWindow::setColormap(uchar *cmap, int l) -{ - zap(colormap); - zap(gammatable); - colormap = new uchar[3*l]; - gammatable = new int[l]; - colormap_length = l; - - - int min_index = cmap_min * l; - int max_index = cmap_max * l; - //warn( "min %f max %f\n", cmap_min, cmap_max); - //warn( "min index %d max index %d\n", min_index, max_index); - - int i,j; - double r,g,b,h,s,v; - for (j=0; j < l; j++) - { - if (j < min_index) i = min_index; - else if (j > max_index) i = max_index; - else i = j; - - r = cmap[3*i]; - g = cmap[3*i+1]; - b = cmap[3*i+2]; - - // This was kindof fun, but not all that useful... - if(fabs(colormap_rotation_angle) > 1e-3) - { - Fl_Color_Chooser::rgb2hsv(r,g,b,h,s,v); - h = (h+(colormap_rotation_angle+0.001)/360.0*6.0); // avoid singularity at angles of 60 degrees (problem on win32) - h = h - 6.0*floor(h/6.0); - Fl_Color_Chooser::hsv2rgb(h,s,v,r,g,b); - } - - // Let's move all of this crap into the colormap loading routine, - // where it really belongs. This is really, really overdue. - if (negate) i = (colormap_length-1) - j; - else i = j; - - colormap[3*i] = (int) (invert) ? 255-r : r; - colormap[3*i+1] = (int) (invert) ? 255-g : g; - colormap[3*i+2] = (int) (invert) ? 255-b : b; - } - - setGamma(gam, gcenter); - adjustHistogram(); - plotCmap(); - colormap_window->update(); -} - -void ImageWindow::setGamma(double g, double gc) -{ - // Build a lookup table that maps our data - gam = g; - gcenter = gc; - - // problem near 1.0... in the end, for some reason this didn't - // always work (was still crashing in win32), so i configured the - // spyview gui so that you cannot set gc greater that 0.999 - //if (gc > 0.999) gc = 0.999; - - // function: - // f3(x,a,b) = b - (x<=b) * b * ((b-x)/b)**(a) + (x>=b) * (1-b) * ((x-b)/(1-b))**(a) - - double x,val; - for (int i = 0; i 1.0) val = 1.0; - if (val < 0.0) val = 0.0; - int index = round((val * (colormap_length-1))); - if (index < 0) index = 0; - if (index >= colormap_length) index = colormap_length-1; - gammatable[i] = index; - //if (i==0 || i == colormap_length-1) - //info( "%03d %.3f %07.3f %03d ", i,val, val*(colormap_length-1), gammatable[i]); - } - //info( "\n"); - - calculateHistogram(); - adjustHistogram(); - redraw(); - colormap_window->update(); -} - -// Calculate the data's histogram -void ImageWindow::calculateHistogram() -{ - int d; - - // Zero the histogram table - for (int i = 0; i <= LMAX; i++) - datahist[i] = 0; - - //warn( "data[2] = %d\n",data[2]); - for (int i=0; i LMAX) - d = LMAX; - if (d < 0) - d = 0; - ++datahist[d]; - } - for (datamin = 0; datamin <= LMAX; datamin++) - if (datahist[datamin]>0) break; - for (datamax = LMAX; datamax >= 0; datamax--) - if (datahist[datamax]>0) break; -} - -// Adjust the lookup table for the image histogram mapping -void ImageWindow::adjustHistogram() -{ - int i; - double s; // Scale factor that takes us from hmin-hmax to 0...1 - double w; // Width of output - for (i = 0; i < hmin; i++) - imagehist[i] = 0; - for (i = hmax+1; i <= LMAX; i++) - imagehist[i] = LMAX; - if (hmin == hmax) - { - if (hmin == 0) hmax++; - else hmin--; - external_update(); - } - s = 1.0/(hmax-hmin); - w = LMAX;; - - // I forgot that the gamma mapping is actually applied here on the 16 bit data!!! - - for (i = hmin; i <= hmax; i++) - { - double d = (i-hmin)*s + 1e-9; // Put ourselves in the range 0...1 - //d = pow(d,gam); // Apply our gamma correction - d = gcenter + ((d<=gcenter) ? - (-gcenter) * pow(((gcenter-d)/gcenter), gam) : - (1-gcenter) * pow((d-gcenter)/(1-gcenter), gam)); - imagehist[i] = static_cast(round(d*w)); - } - - // Drawing the window when it wasn't shown resulted in a flaky window manager placement problem! - if (shown()) - redraw(); -} - -void ImageWindow::normalize() -{ - int new_hmax, new_hmin; - int nwhite, nblack; - nblack = nwhite = 0; - calculateHistogram(); - for ( new_hmin = 0; new_hmin <= LMAX; new_hmin++) - { - nblack += datahist[new_hmin]; - if (nblack > bpercent*w*h/100) break; - } - for ( new_hmax = LMAX; new_hmax >= 0; new_hmax--) - { - nwhite += datahist[new_hmax]; - if (nwhite > wpercent*w*h/100) break; - } - //setGamma(1.0); - setMin(new_hmin); - setMax(new_hmax); - adjustHistogram(); -} - -void ImageWindow::normalizeOnZoom() -{ - if(!zoom_window) - return; - int new_hmax, new_hmin; - int nwhite, nblack; - int x1, y1, x2, y2; - zoom_window->getSourceArea(x1,y1,x2,y2); - int s = (x2-x1)*(y2-y1); - nblack = nwhite = 0; - zoom_window->calculateHistogram(); - for ( new_hmin = 0; new_hmin <= LMAX; new_hmin++) - { - nblack += zoom_window->histogram[new_hmin]; - if (nblack > bpercent*s/100) break; - } - for ( new_hmax = LMAX; new_hmax >= 0; new_hmax--) - { - nwhite += zoom_window->histogram[new_hmax]; - if (nwhite > wpercent*s/100) break; - } - //setGamma(1.0); - setMin(new_hmin); - setMax(new_hmax); - adjustHistogram(); -} - -void ImageWindow::runQueue() -{ - bool swap_zoom = 0; - - operations_string = "("; - - if (process_queue != NULL) - { - for (int i=1; i<=process_queue->size(); i++) - { - Image_Operation *op = (Image_Operation *) process_queue->data(i); - - assert(op); - - if(!op->enabled) - continue; - - if (i!=1) - operations_string += ";" ; - operations_string += op->name; - - for (int n=0; nnum_parameters; n++) - { - operations_string += "-"; - ostringstream os; - os << op->parameters[n].value; - operations_string += os.str(); - } - - if (op->name == "sub fitplane") - id.fitplane(op->parameters[0].value, op->parameters[1].value, op->parameters[3].value); - else if (op->name == "shift data") - id.shift_data(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "remove lines") - id.remove_lines(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "sub linecut") - id.sub_linecut(op->parameters[1].value, op->parameters[0].value); - else if (op->name == "outlier") - id.outlier_line(op->parameters[1].value, op->parameters[0].value); - else if (op->name == "scale axes") - id.scale_axes(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "offset axes") - id.offset_axes(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "sub plane") - id.plane(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "sub lbl") - id.lbl(op->parameters[0].value, op->parameters[1].value, 0, 1, op->parameters[2].value, op->parameters[3].value); - else if (op->name == "sub cbc") - id.cbc(op->parameters[0].value, op->parameters[1].value, 0, 1, op->parameters[2].value, op->parameters[3].value); - else if (op->name == "power") - id.gamma(op->parameters[0].value,op->parameters[1].value); - else if (op->name == "scale data") - id.scale(op->parameters[0].value); - else if (op->name == "even odd") - id.even_odd(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "rm switch") - id.switch_finder(op->parameters[0].value, op->parameters[1].value, false); - else if (op->name == "offset") - id.offset(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "norm lbl") - id.norm_lbl(); - //else if (op->name == "square") - //id.square(); - else if (op->name == "norm cbc") - id.norm_cbc(); - else if (op->name == "log") - id.log10(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "interp") - id.interpolate(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "scale img") - id.scale_image(op->parameters[0].value, op->parameters[1].value); - else if (op->name == "abs") - id.magnitude(); - else if (op->name == "neg") - id.neg(); - else if (op->name == "hist2d") - id.hist2d(op->parameters[0].value, op->parameters[1].value, op->parameters[2].value); - else if (op->name == "xderiv") - id.xderv(); - else if (op->name == "yderiv") - id.yderv(); - else if (op->name == "ederiv") - id.ederv(op->parameters[0].value,op->parameters[1].value); - else if (op->name == "dderiv") - id.dderv(op->parameters[0].value); - else if (op->name == "gradmag") - id.grad_mag(op->parameters[0].value); - else if (op->name == "lowpass") - id.lowpass(op->parameters[0].value, op->parameters[1].value,(ImageData::lowpass_kernel_t)op->parameters[2].value); - else if (op->name == "highpass") - id.highpass(op->parameters[0].value, op->parameters[1].value, op->parameters[2].value / 100.0, (ImageData::lowpass_kernel_t)op->parameters[3].value); - else if (op->name == "notch") - id.notch(op->parameters[0].value, op->parameters[1].value, op->parameters[2].value, op->parameters[3].value); - else if (op->name == "crop") - id.crop(op->parameters[0].value, op->parameters[1].value, op->parameters[3].value, op->parameters[2].value); - else if(op->name == "despeckle") - id.despeckle(op->parameters[0].value, op->parameters[1].value); - else if(op->name == "flip") - { - if(op->parameters[0].value) - id.xflip(); - if(op->parameters[1].value) - id.yflip(); - } - else if (op->name == "autoflip") - { - if (id.xmin > id.xmax) - id.xflip(); - if (id.ymin > id.ymax) - id.yflip(); - } - else if (op->name == "pixel avg") - id.pixel_average(op->parameters[0].value, op->parameters[1].value); - else if(op->name == "rotate cw") - { - id.rotate_cw(); - swap_zoom = !swap_zoom; - } - else if(op->name == "rotate ccw") - { - id.rotate_ccw(); - swap_zoom = !swap_zoom; - } - else if (op->name == "equalize") - id.equalize(); - else - warn("Warning: unknown operation \"%s\"\n",process_queue->text(i)); - } - } - - //info( "op string %s\n", operations_string.c_str()); - operations_string += ")"; - if (process_queue->size() == 0) - operations_string = ""; - - //info( "op string2 %s\n", operations_string.c_str()); - //warn( "swap_zoom %d zoom_is_swapped %d\n", swap_zoom, zoom_is_swapped); - - //info("op string2 %s\n", operations_string.c_str()); - //info("zname %s\n", id.zname.c_str()); - - // We used to do id.zname = id.zname + operation_string, but this - // didn't work for the MTX data derived from meta.txt files? I - // coudn't figure it out, so we'll just use old-fashioned c - // functions... - - char tmp[4096]; - snprintf(tmp, sizeof(tmp), "%s %s", id.zname.c_str(), operations_string.c_str()); - // info("sum test: %s\n", tmp); - id.zname = tmp; - //info( "zname %s\n", id.zname.c_str()); - - if (swap_zoom != swap_zoom_state) - { - int tmp = xzoom; - xzoom = yzoom; - yzoom = tmp; - } - swap_zoom_state = swap_zoom; - - // We also need to recalculate the peaks. If they're not displayed, it's no - // biggy, since it doesn't take too much time. - - // For some reason, this is reproducibly generating a segfault on - // win32? with some specific input files (actually, in particular, - // a really big input file of 600x3600) - - // However, I think the problem is deeper than this, since we were also - // getting random segfaults in win32 before peakfinder. - - // Running in gdb, it is segfaulting when calling iw->dataval - - // Actually, I just realized that pf calls iw->dataval, which is no - // good since if this function is called from loadData, we may not - // have updated the iw width and height properly yet. - - pf->calculate(); -} - -// a little procedure -void ImageWindow::adjust_window_size() -{ - if (window_size_action == KEEPSIZE) - { - xzoom = 0; yzoom = 0; - size(((Fl_Widget *) this)->w(), ((Fl_Widget *)this)->h()); - } - else if (window_size_action == KEEPZOOM) - setXZoom(xzoom); // call this to allocate the image array and set the window size. - else // if (window_size_action == RESETZOOM) - { - xzoom = 1; yzoom = 1; - setXZoom(xzoom); - } -} - -int ImageWindow::loadData(const char *name) -{ - // This is now completely rewritten! - filename = name; - if (id.load_file(name) == -1) return -1; - if (id.width == 0 || id.height == 0) return -1; - if ((id.width>id.height) && (id.width%id.height == 0) && square) - id.pixel_average(id.width/id.height, 1); - original_dataname = id.zname; - runQueue(); - id.quantize(); - data = id.quant_data; - - w = id.width; - h = id.height; - - zap(databuf); - databuf = new int [w*h]; - - adjust_window_size(); - - calculateHistogram(); - adjustHistogram(); - plotLineCut(); - plotHist(); - - // Set a nice basename - char *p; - strncpy(output_basename, filename.c_str(), 256); - if ((p = strstr(output_basename, ".pgm")) == 0) - if ((p = strstr(output_basename, ".Stm")) == 0) - if ((p = strstr(output_basename, ".mtx")) == 0) - if ((p = strstr(output_basename, ".dat")) == 0) - p = strchr(output_basename, 0); - *p = 0; - - external_update(); - return 0; -} - -void ImageWindow::loadData(int *newdata, int neww, int newh, const char *name, bool reset_units) -{ - filename = "imagedata"; - // Keep these around: if the image doesn't change size, we won't bother reallocating the arrays. - int oldw = w; - int oldh = h; - - w = neww; - h = newh; - - id.load_int(newdata, neww, newh); - if ((id.width>id.height) && (id.width%id.height == 0) && square) - id.pixel_average(w/h, 1); - runQueue(); - id.quantize(); - data = id.quant_data; - - w = neww = id.width; - h = newh = id.height; - - if ( oldw*oldh != neww*newh ) - { - zap(databuf); - databuf = new int [w*h]; - } - - adjust_window_size(); - - calculateHistogram(); - adjustHistogram(); - plotLineCut(); - plotHist(); - sprintf(output_basename, name); - external_update(); -} - -void ImageWindow::reRunQueue() -{ - int oldw = w; - int oldh = h; - - // This will copy the original data back into the raw data matrix - id.reset(); - if ((id.width>id.height) && (id.width%id.height == 0) && square) - id.pixel_average(id.width/id.height, 1); - runQueue(); - id.quantize(); - data = id.quant_data; - - w = id.width; - h = id.height; - - // since we will likely often be loading a dataset of the same dimesions - if ( oldw*oldh != w*h ) - { - zap(databuf); - databuf = new int [w*h]; - } - - setXZoom(xzoom); // this will allocate the image array - - calculateHistogram(); - adjustHistogram(); - plotLineCut(); - plotHist(); -} - -void ImageWindow::load_mtx_cut(int index, mtxcut_t type) -{ - int oldw = w; - int oldh = h; - - type = type %3; - - if (!id.data3d) - { - info( "3D data not loaded!\n"); - return; - } - - id.load_mtx_cut(index, type); - original_dataname = id.zname; - runQueue(); - id.quantize(); - data = id.quant_data; - - w = id.width; - h = id.height; - - // since we will likely often be loading a dataset of the same dimesions - if ( oldw*oldh != w*h ) - { - zap(databuf); - databuf = new int [w*h]; - } - - setXZoom(xzoom); // this will allocate the image array - - calculateHistogram(); - adjustHistogram(); - plotLineCut(); - plotHist(); - external_update(); -} - - -void ImageWindow::saveFile() -{ - char buf[256]; - snprintf(buf, 256, "%s.ppm", output_basename); - FILE *fp = fopen(buf, "wb"); - if(fp == NULL) - { - warn("Unable to open file \"%s\": %s\n", - buf, strerror(errno)); - return; - } - fprintf(fp, - "P6\n%d %d\n" - "#hmin %d %e %s\n" - "#hmax %d %e %s\n" - "#hwidth %d %e %s\n" - "#plane_a %e\n" - "#plane_b %e\n" - "#gamma %e\n" - "#Image processing: %s\n" - "255\n", w, h, - hmin, id.quant_to_raw(hmin), id.zname.c_str(), - hmax, id.quant_to_raw(hmax), id.zname.c_str(), - hmax-hmin, id.quant_to_raw(hmax-hmin), id.zname.c_str(), - plane_a, plane_b, gam, operations_string.c_str()); - - unsigned char r,g,b; - for (int i = 0; iname == str) - return i->value; - warn("Warning: unknown parameter \"%s\" on image operation \"%s\"\n", str, name.c_str()); - warn("Available parameters:\n"); - for(parameters_t::iterator i = parameters.begin(); i != parameters.end(); i++) - warn("\t%s\n",i->name.c_str()); - return 0.0; -} - -void ImageWindow::dumpColormap() -{ - string fn = output_basename; - fn += ".colormap.dat"; - info("dumping colormap to %s\n", fn.c_str()); - FILE *fp = fopen(fn.c_str(), "w"); - fprintf(fp, "# hmin %d hmax %d gamma %e\n", hmin, hmax, gam); - - unsigned char r,g,b; - int cmap_index; - for (int i=hmin; iupdateSettings(&ipc); - if (ipc.win->shown()) - ipc.win->hide(); - else - ipc.win->show(); -} - -char *ImageWindow::exportPS() -{ - //const char *extension = ipc.format->value() == Image_Printer::FORMAT_PDF ? "pdf" : "ps"; - struct stat s; - FILE *fp; - static char buf[1024]; - static char buf2[1024]; - - if (ipc.auto_inc->value()) - { - int number = 0; - snprintf(buf, sizeof(buf), "%s.%d", output_basename, number++); - while(stat(buf,&s) == 0) // Stat will return 0 if the file exists - { - snprintf(buf, sizeof(buf), "%s.%d", output_basename, number++); - if(number > 1000) - { - warn("Unable to come up with a suitable file name\n"); - return NULL; - } - } - if(errno != ENOENT) - { - warn("Problem stating output file name: %s\n",strerror(errno)); - return NULL; - } - ipc.incnum->value(number); - } - else if (ipc.do_number->value()) - { - int n = ipc.incnum->value(); - snprintf(buf, sizeof(buf), "%s.%d", output_basename, n); - if (ipc.increment->value()) - ipc.incnum->value(n+1); - } - else - snprintf(buf, sizeof(buf), "%s", output_basename); - - snprintf(buf2, sizeof(buf2), "%s.ps", buf); - info("outputting postscript file %s\n", buf2); - fp = fopen(buf2, "w"); - imageprinter->print(fp); - fflush(fp); - fclose(fp); - - // This will call ghostscript to do the extra conversions - imageprinter->do_extra_conversions(buf); - return buf2; -} - -void ImageWindow::exportMTX(bool save, bool zoom) -{ - FILE *fp; - - string name = output_basename; - - if (save) - name += ".mtx"; - else if (zoom) - name += ".zoom.mtx"; - else - name += ".export.mtx"; - - info("save %d name %s\n", save, name.c_str()); - - if ((fp = fopen(name.c_str(), "r")) != NULL && (save || zoom)) - { - if (fl_ask("Overwrite file %s", name.c_str()) == 1) - fclose(fp); - else - { - fclose(fp); - return; - } - } - - if ((fp = fopenwarn(name.c_str(), "wb")) == NULL) - return; - - int x1, y1, x2, y2; - double xmin, ymin, xmax, ymax; - - if (zoom) - { - zoom_window->getSourceArea(x1,y1,x2,y2); - x2--; - y2--; - } - else - { - x1 = 0; x2 = id.width-1; - y1 = 0; y2 = id.height-1; - } - - xmin = id.getX(x1); - xmax = id.getX(x2); - ymin = id.getY(y1); - ymax = id.getY(y2); - - int wid = x2-x1+1; - int hgt = y2-y1+1; - - string zname = search_replace(id.zname, ",", ";"); - string xname = search_replace(id.xname, ",", ";"); - string yname = search_replace(id.yname, ",", ";"); - - fprintf(fp, "Units, %s," - "%s, %e, %e," - "%s, %e, %e," - "Nothing, 0, 1\n", - zname.c_str(), - xname.c_str(), xmin, xmax, - yname.c_str(), ymin, ymax); - fprintf(fp, "%d %d 1 8\n", wid, hgt); - - //info("x1 %d x2 %d width %d\n", x1, x2, wid); - //info("y1 %d y2 %d height %d\n", y1, yq2, hgt); - - for (int i=x1; i<=x2; i++) - for (int j=y1; j<=y2; j++) - fwrite(&id.raw(i,j), sizeof(double), 1, fp); - - fclose(fp); -} - -void ImageWindow::exportPGM() -{ - FILE *fp; - char buf[256]; - int i,j; - - snprintf(buf, 256, "%s.export.pgm", output_basename); - - if ((fp = fopenwarn(buf, "wb")) == NULL) - return; - - fprintf(fp, "P5\n%d %d\n", w, h); - fprintf(fp, "#zmin %e\n" - "#zmax %e\n" - "#xmin %e\n" - "#xmax %e\n" - "#ymin %e\n" - "#ymax %e\n" - "#xunit %s\n" - "#yunit %s\n" - "#zunig %s\n" - "#Image Processing: %s\n" - "65535\n", id.qmin, id.qmax, id.xmin, id.xmax, id.ymin, id.ymax, - id.xname.c_str(), id.yname.c_str(), id.zname.c_str(), - operations_string.c_str()); - - char c; - int val; - for (j=0; j(w()*h()))) - { - if(image != NULL) - free(image); - image_size = w()*h(); - image = (unsigned char *)malloc(sizeof(unsigned char) * image_size * 3); - } -} -ZoomWindow::ZoomWindow(int w, int h, const char *title) : Fl_Double_Window(w,h,title), image(NULL), img(NULL), xscale(2),yscale(2), center_x(0), center_y(0) -{ - autonormalize = false; -} - -void ZoomWindow::calculateHistogram() -{ - int x1,y1,x2,y2; - getSourceArea(x1,y1,x2,y2); - for(unsigned i = 0; i < hist_len; i++) - histogram[i] = 0; - for(int x = x1; x < x2; x++) - for(int y = y1; y < y2; y++) - { - int d = img->id.quant(x,y); - if(d >= 0 && d < static_cast(hist_len)) - histogram[d]++; - } -} - -void ZoomWindow::draw() -{ - if(!img) - return; - realloc_image(); - int src_x1, src_y1, src_x2, src_y2; - getSourceArea(src_x1, src_y1, src_x2, src_y2); - int my = h(); - int mx = w(); - unsigned char *p = image; - for(int y = 0; y < my; y++) - for(int x = 0; x < mx; x++) - { - int sx = src_x1 + x/xscale; - int sy = src_y1 + y/yscale; - if(sx >= src_x2 || sy >= src_y2) - { - *p++=0; - *p++=0; - *p++=0; - continue; - } - else - { - unsigned char r,g,b; - img->getrgb(sy,sx,r,g,b); - *p++=r; - *p++=g; - *p++=b; - } - } - fl_draw_image(image,0,0,mx,my,3,0); - // This is sometimes getting out of sync: put in the redraw... - snprintf(window_label, 256, "Zoom of %s: (%dx,%dx)", img->filename.c_str(), xscale, yscale); - label(window_label); -} - -int ZoomWindow::handle(int event) -{ - switch (event) - { - case FL_PUSH: - push_mouse_x = Fl::event_x(); - push_mouse_y = Fl::event_y(); - push_center_x = center_x; - push_center_y = center_y; - break; - case FL_DRAG: - case FL_RELEASE: - center_x = push_center_x - (Fl::event_x()-push_mouse_x)/xscale; - center_y = push_center_y - (Fl::event_y()-push_mouse_y)/yscale; - zoomMoved(); - break; - case FL_HIDE: - if(img) - img->redraw_overlay(); - break; - case FL_SHOW: - if(img) - img->redraw_overlay(); - break; - case FL_KEYDOWN: - char c = Fl::event_key(); - //info("Key %c\n",c); - switch(c) - { - case '=': - case '+': - case '.': - case '>': - { - int oldw, oldh; - oldw = w()/xscale; - oldh = h()/yscale; - if (Fl::event_state() & FL_SHIFT) - xscale++; - else if (Fl::event_state() & FL_CTRL) - yscale++; - else - {xscale++; yscale++;} - size(oldw*xscale, oldh*yscale); - if(img) - img->redraw_overlay(); - redraw(); - return 1; - } - case '-': - case ',': - case '<': - { - int oldw, oldh; - oldw = w()/xscale; - oldh = h()/yscale; - if (Fl::event_state() & FL_SHIFT) - xscale--; - else if (Fl::event_state() & FL_CTRL) - yscale--; - else - {xscale--; yscale--;} - if(xscale < 1) - xscale = 1; - if(yscale < 1) - yscale = 1; - size(oldw*xscale, oldh*yscale); - if(img) - img->redraw_overlay(); - redraw(); - return 1; - } - case 'z': - if (!(Fl::event_state() & FL_CTRL)) - { - hide(); - return 1; - } - } - break; - } - return 0; -} - -void ZoomWindow::resize(int x, int y, int w, int h) -{ - snprintf(window_label, 256, "Zoom of %s: (%dx,%dx)", img->filename.c_str(), xscale, yscale); - label(window_label); - Fl_Double_Window::resize(x,y,w,h); - img->external_update(); - zoomMoved(); - size_range(1,1); -} - -void ZoomWindow::getSourceArea(int &x1, int &y1, int &x2, int &y2) -{ - int dx = w()/xscale; - int dy = h()/yscale; - - //warn( "xscale %d yscale %d\n", xscale, yscale); - - x1 = center_x - dx/2; // Find the ideal top-left - y1 = center_y - dy/2; - - if(x1 < 0) x1 = 0; // Clip to the window - if(y1 < 0) y1 = 0; - - x2 = x1 + dx; // Find the bottom right, including top-left clipping - y2 = y1 + dy; - - if(x2 >= img->w) // Clip the bottom right to the window - { - x2 = img->w; - if(x2-dx < 0) // Be careful if the source window isn't as wide as dx! - x1 = 0; - else - x1 = x2-dx; - } - if(y2 >= img->h) - { - y2 = img->h; - if(y2-dy < 0) - y1 = 0; - else - y1 = y2-dy; - } -} - -void ZoomWindow::zoomMoved() -{ - if(autonormalize && img) - img->normalizeOnZoom(); - redraw(); - if(img) - img->redraw_overlay(); -} - -ColormapWindow::ColormapWindow(int wp, int hp, const char *title) : Fl_Window(wp,hp,title), image(NULL) -{ - // You shouldn't call functions from a constructor! - //resize(x(),y(),w(),h()); - //size_range(1,1,0,0); -} - -void ColormapWindow::resize(int x, int y, int w, int h) -{ - Fl_Window::resize(x,y,w,h); - - if(image) - delete[] image; - image = NULL; - - if(h < w) - { - vertical = false; - xmult = w/wid; - //warn( "xmult %d\n", xmult); - if(xmult == 0) - return; - ih = h; - iw = w - (w % wid); - } - else - { - vertical = true; - xmult = h/wid; - //warn( "xmult %d\n", xmult); - if(xmult == 0) - return; - ih = w; - iw = h - (h % wid); - } - if(iw <= 0 || ih <= 0) - return; - image = new uchar[3*iw*ih]; - assert(image); - update(); - redraw(); -} - -ColormapWindow::~ColormapWindow() -{ - delete[] image; -} - -void ColormapWindow::update() -{ - if(!img || !image) - return; - - double foo = 1.0 * (img->colormap_length-1)/(iw-1); - int tmp, tmp2; - int i; - for (int y = 0; y < ih; y++) - for (int x = 0; x < iw; x++) - { - tmp2 = (int) round(x*foo); - tmp = img->gammatable[tmp2]; - if (vertical) - i = iw-1-x; - else - i = x; - -// if (x == iw/2 && y == 0) -// { -// warn( "iw %d cmapl %d foo %g x %d tmp2 %d tmp %d\n", -// iw, img->colormap_length, foo, x, tmp2, tmp); -// } - if(tmp > img->colormap_length-1) - tmp = img->colormap_length-1; - if(tmp < 0) - tmp = 0; - image[3*(i+y*iw)] = img->colormap[3*tmp]; - image[3*(i+y*iw)+1] = img->colormap[3*tmp+1]; - image[3*(i+y*iw)+2] = img->colormap[3*tmp+2]; - } - redraw(); -} -void ColormapWindow::draw() -{ - if(image) - if(vertical) - fl_draw_image(image,0,(h()-iw)/2,ih,iw,iw*3,3); - else - fl_draw_image(image,(w()-iw)/2,0,iw,ih,3,0); -} - -void ColormapWindow::saveFile(const char *name) -{ - static const int height=32; - warn( "saving colormap to %s", name); - FILE *fp = fopen(name, "wb"); - if(fp == NULL) - { - warn("Unable to open file \"%s\": %s\n", - name, strerror(errno)); - return; - } - fprintf(fp, - "P6\n%d %d\n" - "#zmin %f\n" - "#zmax %f\n" - "255\n", wid, height, - img->zunit(img->hmin), - img->zunit(img->hmax)); - - for(int j = 0; j < height; j++) - for (int i = 0; i< wid; i++) - { - int tmp = img->gammatable[i]; - fwrite(&(img->colormap[3*tmp]),sizeof(char),3,fp); - } - - fclose(fp); -} - diff --git a/spyview/bisector.H.~1.3.~ b/spyview/bisector.H.~1.3.~ deleted file mode 100644 index 9b696ef..0000000 --- a/spyview/bisector.H.~1.3.~ +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __bisector_h__ -#define __bisector_h__ -#include -#include - -class bisector -{ -public: - static const double factor=0.5; - double x1, x2, fx1, fx2; - double acc; - int iter; - bisector(double x1p, double fx1p, double x2p, double fx2p, double acct=1e-6) : x1(x1p), x2(x2p), fx1(fx1p), fx2(fx2p), acc(acct*fabs(x1p-x2p)) - { - iter =0; - }; - - bool x(double &xp) // Return next x coordinate to evaluate. Return true if we've converged. - { - if(fx1*fx2 > 0) - { - if(fabs(fx1) < fabs(fx2)) - { - xp = x1; - return true; - } - else - { - xp = x2; - return true; - } - } - if(fabs(x2-x1) < acc) - { - xp = (x1+x2)/2.0; - return true; - } - if(iter++ > 100) - { - fprintf(stderr,"x1=%g, x2=%g, acc=%g; bailing\n", - x1,x2,acc); - xp=(x1+x2)/2.0; - return true; - } - xp = x1+factor*(x2-x1); - return false; - }; - - inline void o(double x, double fx) // Add an observation. - { - if(fx*fx1 <= 0.0) - { - x2 = x; - fx2 = fx; - } - else - { - assert(fx*fx2 <= 0.0); - x1 = x; - fx1 = fx; - } - }; -}; - -/* Newton step until we bracket, then bisect */ -class magic_bisector -{ -public: - static const double factor=0.5; - bool bisection; - double nx, nfx; - double x1, fx1, x2, fx2, mest; - double acc; - int iter; - magic_bisector(double x_start, double m_est_p, double acc_p=1e-6) : nx(x_start), mest(m_est_p), acc(acc_p) - { - x1 = NAN; - x2 = NAN; - nfx = 10*acc_p; - bisection = false; - iter = 0; - }; - bool x(double &xp) - { - xp = nx; - return (fabs(nfx) < acc) || (iter++ > 32); - } - - void o(double xp, double fxp) - { - nfx = fxp; - if(bisection) - { - if(fxp < 0) - { - x1 = xp; - fx1 = fxp; - } - else - { - x2 = xp; - fx2 = fxp; - } - } - else - { - if(fxp < 0 && (isnan(x1) || (fxp > fx1))) - { - x1 = xp; - fx1 = fxp; - } - else if(fxp > 0 && (isnan(x2) || (fxp < fx2))) - { - x2 = xp; - fx2 = fxp; - } - } - bisection = !(isnan(x1) || isnan(x2)); - if(bisection) - { - // printf("Bisection step: [%g,%g] {%g,%g}\n", x1,x2,fx1,fx2); - nx = (x1+x2)/2.0; - } - else - { - nx -= nfx/mest; - // printf("Newton step to %g (%g/%g)\n",nx,nfx,mest); - } - } -}; -#endif diff --git a/spyview/spypal_import.C.~1.6.~ b/spyview/spypal_import.C.~1.6.~ deleted file mode 100644 index e1b75f1..0000000 --- a/spyview/spypal_import.C.~1.6.~ +++ /dev/null @@ -1,176 +0,0 @@ -#include "spypal_import.H" -#include -#include - -double sqr(double x) { return x*x; }; -static int worst_point; -static double worst_error; -double spypal_worst_error() { return worst_error; }; -static double fidelity(unsigned char *c1, unsigned char *c2, unsigned l) -{ - double e = 0; - worst_error = 0; - worst_point = -1; - for(unsigned i = 0; i < l; i++) - { - double se = sqr(c2[3*i]-c1[3*i])+sqr(c2[3*i+1]-c1[3*i+1])+sqr(c2[3*i+2]-c1[3*i+2]); - if(se > worst_error) - { - worst_point = i; - worst_error = se; - } - e += se; - } - return e; -} - -static void color_waypoints(std::vector &wps, unsigned char *c1, unsigned l) -{ - for(unsigned i = 0 ; i < wps.size(); i++) - { - double r,g,b; - r = c1[3*wps[i].ind+0]/255.0; - g = c1[3*wps[i].ind+1]/255.0; - b = c1[3*wps[i].ind+2]/255.0; - // printf("%d %g %g %g %d %d %d\n",wps[i].ind,r,g,b,c1[3*wps[i].ind+0],c1[3*wps[i].ind+1],c1[3*wps[i].ind+2]); - cc_sRGB.set(wps[i].c,r,g,b); - } -} -static double try_colormap(std::vector &wps, const ccspace *cs, unsigned char *c1, unsigned l) -{ - sort(wps.begin(),wps.end()); - - generate_go(wps,OPTS_STRAIGHT,true,cs,cs,l); - if(cmap.size() != l) - return NAN; - dump_colormap_memory(); - return fidelity(c1,spypal_colormap,l); -} - -// Try to adjust the waypoints by starting from three waypoints, then building -// up, adding the additional waypoint at the point where the error is largest -// each time. -double spypal_bisect_anneal(SpypalWaypoints_t &wps_out, const ccspace *cs, unsigned char *c1, unsigned l) -{ - size_t size = wps_out.size(); - assert(size >= 2); - - if(size == 2) - return spypal_anneal(wps_out,cs,c1,l); - - double err; - SpypalWaypoints_t wps(3); - - // Initialize the guess. - for(unsigned i = 0; i < wps.size(); i++) - { - wps[i].loc = ((double)i)/(wps.size()-1); - wps[i].ind = wps[i].loc * (l-1); - wps[i].locked = true; - } - color_waypoints(wps,c1,l); - err = spypal_anneal(wps,cs,c1,l,false); - - // Add a waypoint at the worst point and anneal until we reach the right size - while(wps.size() < size) - { - SpypalWaypoint w; - if(worst_point >= 0) - w.ind = worst_point; - else - w.ind = l/2; - w.loc = ((double)w.ind) / (l-1); - w.locked = true; - wps.push_back(w); - color_waypoints(wps,c1,l); - err = spypal_anneal(wps,cs,c1,l,false); - } - wps_out = wps; - return try_colormap(wps,cs,c1,l); -} - -// Try to adjust the waypoints in waypoints to maximize the fidelity. -// Return the fidelity. -double spypal_anneal(SpypalWaypoints_t &wps, const ccspace *cs, unsigned char *c1, unsigned l, bool init) -{ - double best; - SpypalWaypoints_t wps_best; - - if(init) - { - // Initialize the guess. - for(unsigned i = 0; i < wps.size(); i++) - { - wps[i].loc = ((double)i)/(wps.size()-1); - wps[i].ind = wps[i].loc * (l-1); - wps[i].locked = true; - } - color_waypoints(wps,c1,l); - } - - // Get an initial fidelity - best = try_colormap(wps,cs,c1,l); - if(isnan(best)) - return best; - wps_best = wps; - - // Anneal; try sliding each waypoint left then right. - bool improved; - int iter = 1000; - int stepsize = l/(2.0*wps.size()); - if(stepsize < 1) - stepsize = 1; - do - { - improved = false; - for(unsigned i = 1; i < wps.size()-1; i++) - { - if(wps[i].ind > stepsize) - { - SpypalWaypoints_t wpst = wps; - wpst[i].ind -= stepsize; - wpst[i].loc = wpst[i].ind / (l - 1.0); - color_waypoints(wpst,c1,l); - double f = try_colormap(wpst,cs,c1,l); - if(f < best) - { - best = f; - wps_best = wpst; - improved = true; - wps = wpst; - break; - } - } - if(((int)wps[i].ind) < (l-stepsize)) - { - SpypalWaypoints_t wpst = wps; - wpst[i].ind += stepsize; - wpst[i].loc = wpst[i].ind / (l - 1.0); - color_waypoints(wpst,c1,l); - double f = try_colormap(wpst,cs,c1,l); - if(f < best) - { - best = f; - wps_best = wpst; - improved = true; - wps = wpst; - break; - } - } - } - if(best == 0.0) - break; - if(!improved) - { - if(stepsize == 1) - break; - else - stepsize /= 2.0; - } - // printf("%5d %3d %g\n",iter,stepsize,best); - } - while(iter--); - wps = wps_best; - // One extra calc cycle to get worst_error right. - return best; -} diff --git a/spyview/spyview.C.~1.272.~ b/spyview/spyview.C.~1.272.~ deleted file mode 100644 index 8daac38..0000000 --- a/spyview/spyview.C.~1.272.~ +++ /dev/null @@ -1,2156 +0,0 @@ -#include -#include -#include -#include "../config.h" -#include -#include "spyview.H" -#include "ImageWindow.H" -#include "spyview_ui.h" -#include "ImageWindow_LineDraw.H" -#include "ImageWindow_Fitting.H" -#include "ThresholdDisplay.H" -#include "message.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Fiddle.H" -#include "mypam.h" -#include "misc.h" -#include "spypal.h" -#include "spypal_interface.H" -#include "spypal_import.H" -#include - -using namespace std; - -//How's this for lazy...? -char **arg_values; -int arg_count; -int opt_index; - -vector filenames; -vector cmapfiles; -string default_file; -string current_filename; - - -bool no_files_given; - -// Keep track of what directory we started in -string original_dir(""); - -// On unix, this will be $HOME/.spyview -// On win32, default will be $APPDATA/spyview -// If SPYVIEW_PREF_DIR exist, it will use $SPYVIEW_PREF_DIR/spyview -string userdir(""); - -// On unix, default to /usr/share -// On windows, if called using file associations, we can find the full -// path to the spyview.exe. If called from the command line, the user -// should set the SPYVIEW_DIR environment variable. -string sharedir(""); - -int check_loaded() -{ - return filenames.size(); -} - -void clear_files() -{ - filech->clear(); - filenames.clear(); -} - -void spyview_exit() -{ - // Will the iw destructor get called automatically on hide? - // However, it is important not to delete it before hiding all of - // the windows, as if the zoom window is open, then it will crash on - // win32 when it tries to call the draw_overlay() of iw after it's - // been deleted. - - //delete iw; - - // Just calling exit(0) will rely on the OS to clear all of the - // memory. While this seems to work fine on UNIX, on win32, this - // results in intermittent and unpredictable crashes. According to - // this reference, http://www3.telus.net/public/robark/, it is - // better to hide all of the windows, which will call Fl::run() to - // return more safely (?) - - while( Fl::first_window() ) - Fl::first_window()->hide(); -} - -void close_window_callback(Fl_Widget*) -{ - //if (fl_ask("Juriaan, do you really want to close spyview?")) // Who is Juriaan? - spyview_exit(); - - // I had never clicked on the "close" button of the image window - // before, and so I had never noticed the bug that if you close the - // ImageWindow, the program doesn't close, but then it is impossible - // to get the window to appear again. - - // This bug was found by one of my earlier Windows-based spyview - // adopters, Juriaan. My initial answer was "why would you ever - // click on the close button of the window?", but I eventually caved - // and added this exit handler, and the warning message... - -} - -// Find all the colormaps in a path, using "pretty_path" for the browser -// hierarchy. -void find_cmaps(std::string path, std::string pretty_path) -{ - typedef vector subdirs_t; - subdirs_t subdirs; - info("Checking \"%s\" for cmaps (%s)\n", path.c_str(),pretty_path.c_str()); - struct dirent **namelist; - string fn; - int n = fl_filename_list(path.c_str(), &namelist, fl_casealphasort); - int count = 0; - for (int i = 0; id_name, ".ppm") != NULL) || (strstr(namelist[i]->d_name,".spp") != NULL)) - { - fn = namelist[i]->d_name; - std::string pretty_fn(fn); - pretty_fn.erase(pretty_fn.find_last_of('.')); - cmapfiles.push_back(path + fn); - int ind = cmapch->add((pretty_path + pretty_fn).c_str(), 0, 0, reinterpret_cast(cmapfiles.size()-1)); - if(strstr(namelist[i]->d_name,".ppm") != NULL) - cmapch->menu()[ind].labelfont(FL_HELVETICA_ITALIC); - else - cmapch->menu()[ind].labelfont(FL_HELVETICA); - count++; - } - else if (fl_filename_isdir((path+namelist[i]->d_name).c_str())) - subdirs.push_back(namelist[i]->d_name); - if ((count != 0) && (count%30 == 0)) - pretty_path += "More/"; - } - for(subdirs_t::iterator i = subdirs.begin(); i != subdirs.end(); i++) - { - if(*i == "./" || *i == "../" || *i == "") - continue; - find_cmaps(path+*i,pretty_path+*i); - } -} - -int add_file(const char *name) -{ - // We store the actual filenames in a STL vector of strings - // called "filenames" - - // In "filech", we put a "user friendly" filename in, and we - // store the index location of the real filename in the - // userdata. - - string menu_text; - int fd; - int n; - if ( (fd = open(name, O_RDONLY)) != -1) - { - filenames.push_back(name); - n=filech->add("foo", 0, filech_cb, reinterpret_cast(filenames.size()-1)); - filech->replace(n, name); - close(fd); - return n; - } - else - { - warn("Unable to open file \"%s\": %s\n", name, strerror(errno)); - return -1; - } -} - - -// breaks apart a string into substrings separated by a character string -// does not use a strtok() style list of separator characters -// returns a vector of std::strings - -std::vector Explode (const std::string &inString, const std::string &separator) -{ - std::vector returnVector; - std::string::size_type start = 0; - std::string::size_type end = 0; - - while ((end = inString.find (separator, start)) != std::string::npos) - { - returnVector.push_back (inString.substr (start, end-start)); - start = end + separator.size(); - } - - returnVector.push_back(inString.substr(start, inString.size())); - return returnVector; -} - -// A drag-n-drop handler -void load_filech(const char *text) -{ - info("test is:\n_%s_", text); - vector files = Explode(text, "\n"); - info("found %d files\n", files.size()); - - int n; - for (unsigned i=0; ivalue(n); - filech->do_callback(); -} - -int load_orig_files() -{ - filenames.clear(); - filech->clear(); - for (int i=opt_index; i < arg_count; i++) - add_file(arg_values[i]); - no_files_given = false; - if (filenames.size() == 0) - { - no_files_given = true; - add_file(default_file.c_str()); - if (check_loaded() == 0) - error("Could not find default image!"); - } - return 0; -} - -/* Callbacks for image operations */ -// Callbacks for crop -void cb_crop_to_zoom(Fl_Widget *w, void *p) -{ - int x1,y1,x2,y2; - if(!iw->zoom_window) - return; - iw->zoom_window->getSourceArea(x1,y1,x2,y2); - char buf[1024]; - snprintf(buf,sizeof(buf),"%d",x1); - proc_parameters[0]->value(buf); - snprintf(buf,sizeof(buf),"%d",x2); - proc_parameters[1]->value(buf); - snprintf(buf,sizeof(buf),"%d",y1); - proc_parameters[2]->value(buf); - snprintf(buf,sizeof(buf),"%d",y2); - proc_parameters[3]->value(buf); - proc_parameters[3]->do_callback(); -} - -void cb_reset_zoom(Fl_Widget *w, void *p) -{ - proc_parameters[0]->value("0"); - proc_parameters[1]->value("0"); - proc_parameters[2]->value("0"); - proc_parameters[3]->value("0"); - proc_parameters[3]->do_callback(); -} - -// Callbacks for line subtraction -void cb_sub_current_line(Fl_Widget *w, void *p) -{ - int line; - if(proc_bool_parameters[1]->value()) - line = iw->line_cut_yp; - else - line = iw->line_cut_xp; - char buf[1024]; - snprintf(buf,sizeof(buf),"%d",line); - proc_parameters[0]->value(buf); - proc_parameters[0]->do_callback(); -} - -void cb_hist2d_autorange(Fl_Widget *w, void *p) -{ - double tmp; - char buf[1024]; - - tmp = iw->id.quant_to_raw(iw->hmin); - snprintf(buf,sizeof(buf),"%e",tmp); - proc_parameters[0]->value(buf); - - tmp = iw->id.quant_to_raw(iw->hmax); - snprintf(buf,sizeof(buf),"%e",tmp); - proc_parameters[1]->value(buf); - - snprintf(buf,sizeof(buf),"%d",iw->id.height); - proc_parameters[2]->value(buf); - - proc_parameters[0]->do_callback(); -} - -void usage() -{ - printf("%s\n",Fl::help); -} - - -void Update_Status_Bar(int n, bool down); -void embed_colormap(); -void showUsedFiles(bool leak); // For debugging -int main(int argc, char **argv) -{ - char c; - Fl::visual(FL_RGB8|FL_DOUBLE); - Fl::get_system_colors(); - info("Welcome to spyview\n"); - info("Build stamp: %s\n", BUILDSTAMP); - - char buf[1024]; - original_dir = getcwd(buf, sizeof(buf)); - -#ifdef WIN32 - - // This is tricky. Look first for an environment variable. If not - // found, try to guess from program name, which if we've been - // launched using file associations, will contain the full - // executable path. This should make things work without having to - // do and "install" - - if (getenv("SPYVIEW_DIR") != NULL) // otherwise get a windows crash? - sharedir = getenv("SPYVIEW_DIR"); - else - { - // Under windows, argv[0] (seems) to get the full program path - // (when launched by explorer.exe, but not when called from the - // cmd.exe command line) So we try to split out the path to the - // executable here. - sharedir = argv[0]; - int c2 = sharedir.find_last_of("\\"); - if(c2 >= 0) - sharedir.replace(c2,string::npos, ""); - info("SPYVIEW_DIR not found: guessing %s from argv[0]\n", sharedir.c_str()); - } - if (sharedir.size() == 0) - { - warn("Could not find good sharedir: reverting to '.'\n"); - sharedir = "."; - } - info("sharedir is %s\n", sharedir.c_str()); - - // For win32, we have a couple of options to get the user's - // Application Data directory: APPDATA, USERPROFILE, or HOMEDRIVE + - // HOMEPATH + "Application Data\". For local users, these are all - // the same. For network users, they can be different: for example, - // - // HOMEPATH=\ HOMEDRIVE=H: - - // USERPROFILE=C:\Documents and Settings\gsteele - // APPDATA=\\tudelft.net\staff-homes\S\gsteele\Application Data - // - // Ideally, we should store it on the network drive H: - // (\\tudelft.net\staff-homes\S\gsteele\). However, if we just use - // APPDATA, it will not work since mingw32 does not support DFS UNC - // paths. (It does support regular UNC paths, such as - // \\myserver\gsteele, although forward slashes are not interpreted - // as directory separators, as they are for local dirctories on - // WinXP). - // - // In the end, it seems to be safest to take HOMEDRIVE + HOMEPATH + "Application Data" - - // Update: 3 Dec 09 - // - // Due to popular demand, I will now change the default behaviour so - // that spyview uses the settings files that are in the SHAREDIR, - // unless there is a SPYVIEW_PREF_DIR set. Note that from the - // command line, you will need to set SPYVIEW_PREF_DIR. - - if(getenv("SPYVIEW_PREF_DIR") != NULL) - userdir = getenv("SPYVIEW_PREF_DIR"); - //else if((getenv("HOMEDRIVE") != NULL) && (getenv("HOMEPATH") != NULL)) - //{ - // userdir = getenv("HOMEDRIVE"); - // userdir = userdir + getenv("HOMEPATH") + "\\Application Data"; - // userdir += "\\spyview"; - //} - else - userdir=sharedir; - info("userdir is %s\n", userdir.c_str()); - -#else - if(getenv("HOME")) - userdir = getenv("HOME"); - else - userdir = "."; - userdir += "/.spyview"; - sharedir = SPYVIEW_DATADIR; -#endif - default_file = sharedir + DIRECTORY_SEPARATOR + "default_image.pgm"; - - info("def file is %s\n", default_file.c_str()); - - string settings_file(""); - - int firstarg; - Fl::args(argc,argv,firstarg); - - init_spypal(); - colormap_callback = spypal_cb; - spypal_sharedir = sharedir; - while ((c = getopt(argc, argv, "s:")) != -1) - { - switch (c) - { - case 's': - info("found settings file %s\n", optarg); - settings_file = userdir + DIRECTORY_SEPARATOR + "settings" + DIRECTORY_SEPARATOR + optarg; - break; - } - } - - //info("settings file %s\n", settings_file.c_str()); - //getchar(); - - make_window(); - - // Initialize the optional "modules"; these insert themselves into spyview callbacks to grab - // keystrokes and draw things. - - LineDraw iwld(iw); - Fitting iwf(iw); - ThresholdDisplay iwtd(iw); - Fiddle iwfiddle(iw); - - // Set the pointers to the controls window and the process_queue in the image window class - iw->controls_window = control; - iw->process_queue = pqueue; - iw->external_update = update_widgets; - iw->drag_n_drop = load_filech; - - embed_colormap(); - - iw->setGamma(1.0,0.0); - wpbox->value(iw->wpercent); - bpbox->value(iw->bpercent); - - //add_image_operations(); // why doesn't this work? must be something funny with the macros... - - Define_Image_Operation(new Image_Operation("neg","Negate numerical data")); - Define_Image_Operation(new Image_Operation("square","Average pixels to make a square image")); - Define_Image_Operation(new Image_Operation("autoflip","Flip axes so that more neg end is on left/bottom")); - - Image_Operation sub_fitplane("sub fitplane","Subtract a fitted plane with outlier rejection"); - sub_fitplane.addParameter("Low ", 20.0); - sub_fitplane.addParameter("High ", 20.0); - sub_fitplane.addParameter("!Percentiles?", 1); - Define_Image_Operation(&sub_fitplane); - - Image_Operation sub_plane("sub plane","Subtract a plane with a specified slope"); - sub_plane.addParameter("Vert %", 0.0); - sub_plane.addParameter("Horiz %", 0.0); - Define_Image_Operation(&sub_plane); - - Image_Operation scale_axes("scale axes","Scale the ranges of the X & Y axes"); - scale_axes.addParameter("X scale", 1.0); - scale_axes.addParameter("Y scale", 1.0); - Define_Image_Operation(&scale_axes); - - Image_Operation offset_axes("offset axes","Offset the ranges of the X & Y axes"); - offset_axes.addParameter("X offset", 0.0); - offset_axes.addParameter("Y offset", 0.0); - Define_Image_Operation(&offset_axes); - - Image_Operation interp("interp","Interpolate the data onto a new grid (bilinear)"); - interp.addParameter("New x size", 200); - interp.addParameter("New y size", 200); - Define_Image_Operation(&interp); - - Image_Operation scale_img("scale img","Scale the image data using bilinear interpolation"); - scale_img.addParameter("X scaling", 2.5); - scale_img.addParameter("Y scaling", 2.5); - Define_Image_Operation(&scale_img); - - Image_Operation sub_lbl("sub lbl", "Subtract the mean of each image line with outlier rejection"); - sub_lbl.addParameter("Low %", 2.0); - sub_lbl.addParameter("High %", 90.0); - sub_lbl.addParameter("Low limit", -1e99); - sub_lbl.addParameter("High limit", 1e99); - //sub_lbl.addParameter("!Whole image thr?", 0); - //sub_lbl.addParameter("!Percentiles?", 1); - Define_Image_Operation(&sub_lbl); - - Image_Operation sub_cbc("sub cbc","Subtract the mean of each image column with outlier rejection"); - sub_cbc.addParameter("Low ", 2.0); - sub_cbc.addParameter("High ", 90.0); - sub_cbc.addParameter("Low limit", -1e99); - sub_cbc.addParameter("High limit", 1e99); - //sub_cbc.addParameter("!Whole image thr?", 0); - //sub_cbc.addParameter("!Percentiles?", 1); - Define_Image_Operation(&sub_cbc); - - Image_Operation sub_line("sub linecut","Subtract a linecut from every line"); - sub_line.addParameter("Line Num",0); - sub_line.addParameter("!Horizontal",1); - sub_line.addParameter(".Current Line",0,cb_sub_current_line); - Define_Image_Operation(&sub_line); - - Image_Operation outlier_line("outlier","Remove an outlier line from the data"); - outlier_line.addParameter("Line Num",0); - outlier_line.addParameter("!Horizontal",1); - outlier_line.addParameter(".Current Line",0,cb_sub_current_line); - Define_Image_Operation(&outlier_line); - - Define_Image_Operation(new Image_Operation("xderiv","Take an x derivative of the image data")); - Define_Image_Operation(new Image_Operation("yderiv","Take a y derivative of the image data")); - Image_Operation ederiv("ederiv","Take an energy derivative of the image data"); - ederiv.addParameter("Negative Scale",1.0); - ederiv.addParameter("Positive Scale",1.0); - Define_Image_Operation(&ederiv); - - Image_Operation dderiv("dderiv", "Take a derivative along an arbitrary axis"); - dderiv.addParameter("Theta",0.0); - Define_Image_Operation(&dderiv); - Image_Operation gradmag("gradmag", "Take the magnitude of the gradient"); - gradmag.addParameter("Axis Bias [0-1.0]",0.5); - Define_Image_Operation(&gradmag); - - Image_Operation gamma("power","y = x^p, p<0 & abs(x) truncate x, y<0 & p not int => set y=0"); // a better name - gamma.addParameter("Power", 0.5); - gamma.addParameter("Epsilon", 1e-20); - Define_Image_Operation(&gamma); - - Define_Image_Operation(new Image_Operation("norm lbl","Stretch the contrast of each line to full scale")); - Define_Image_Operation(new Image_Operation("norm cbc","Stretch the contrast of each column to full scale")); - - Image_Operation lp("lowpass","Low pass filter the image; 0 for no filtering"); - lp.addParameter("X Width",3.0); - lp.addParameter("Y Width",3.0); - lp.addParameter("?Type 0,Gaussian 1,Lorentzian 2,Exponential 3,Thermal",0.0); - Define_Image_Operation(&lp); - - Image_Operation hp("highpass","High pass filter the image; 0 for no filtering"); - hp.addParameter("X Width",3.0); - hp.addParameter("Y Width",3.0); - hp.addParameter("Pass. %",0.0); - hp.addParameter("?Type 0,Gaussian 1,Lorentzian 2,Exponential",0.0); - Define_Image_Operation(&hp); - - Image_Operation notch("notch","Notch filter the image; 0 for no filtering"); - notch.addParameter("X Low",2.0); - notch.addParameter("X High",2.0); - notch.addParameter("Y Low",2.0); - notch.addParameter("Y High",3.0); - Define_Image_Operation(¬ch); - - Image_Operation despeckle("despeckle","Despeckle Image Using Median Filter"); - despeckle.addParameter("!X Despeckle",1); - despeckle.addParameter("!Y Despeckle",0); - Define_Image_Operation(&despeckle); - - Image_Operation flip("flip","Flip the Image"); - flip.addParameter("!Flip X Axis",0); - flip.addParameter("!Flip Y Axis",0); - Define_Image_Operation(&flip); - - Image_Operation crop("crop","Crop the Image (0 to keep current, negative possible for lower/right)"); - crop.addParameter("left col #", 0); - crop.addParameter("right col #", 0); - crop.addParameter("upper row #", 0); - crop.addParameter("lower row #", 0); - crop.addParameter(".Copy Zoom",-1,cb_crop_to_zoom); - crop.addParameter(".Reset Zoom",-1,cb_reset_zoom); - Define_Image_Operation(&crop); - - Image_Operation pixel_avg("pixel avg","Down sample image by averaging pixels"); - pixel_avg.addParameter("X pixels", 2); - pixel_avg.addParameter("Y pixels", 2); - Define_Image_Operation(&pixel_avg); - - Image_Operation scale("scale data","Scale and center the data (change dynamic range)"); - scale.addParameter("Factor",0.5); - Define_Image_Operation(&scale); - - Image_Operation offset("offset","Add an offset to the data"); - offset.addParameter("Offset by",0); - offset.addParameter("!Auto (sub min first)", 1); - Define_Image_Operation(&offset); - - Image_Operation log("log","Take logarithm (base 10) of intensities"); - log.addParameter("!Auto subtract offset", 0); - log.addParameter("New min",1e-4); - Define_Image_Operation(&log); - - Image_Operation sw_find("rm switch", "Remove switches (1 pixel jumps) in the data"); - sw_find.addParameter("Threshold", 300); - sw_find.addParameter("Avg win",10); - Define_Image_Operation(&sw_find); - - Image_Operation even_odd("even odd","Extract even or odd rows, optionally flipping odd rows"); - even_odd.addParameter("!Even", 1); - even_odd.addParameter("!Flip odd rows", 1); - Define_Image_Operation(&even_odd); - - Image_Operation hist2d("hist2d", "Convert y-axis into a histogram of each column"); - hist2d.addParameter("ymax", -100); - hist2d.addParameter("ymax", +100); - hist2d.addParameter("Num bins", 100); - hist2d.addParameter(".Autorange", -1, cb_hist2d_autorange); - //hist2d.addParameter("!Flip odd rows", 1); - Define_Image_Operation(&hist2d); - - - Image_Operation shift_data("shift data","Horizontally shift data after a given row"); - shift_data.addParameter("After row", 0); - shift_data.addParameter("Shift (pix)", 0); - Define_Image_Operation(&shift_data); - - Image_Operation remove_lines("remove lines","Remove lines, shifting data vertically"); - remove_lines.addParameter("Start row", 0); - remove_lines.addParameter("# lines", 0); - Define_Image_Operation(&remove_lines); - - Define_Image_Operation(new Image_Operation("rotate cw","Rotate the image by 90 degrees clockwise")); - Define_Image_Operation(new Image_Operation("rotate ccw","Rotate the image by 90 degrees counter clockwise")); - Define_Image_Operation(new Image_Operation("abs","Take the absolute value of the intensities")); - Define_Image_Operation(new Image_Operation("equalize","Perform a histogramic equalization on the image")); - - // Now sort image operations alphabetically - - - // Works on unix, but segfaults on win32? - -// Fl_Browser *b = options; -// for ( int t=1; t<=b->size(); t++ ) { -// for ( int r=t+1; r<=b->size(); r++ ) { -// if ( strcmp(b->text(t), b->text(r)) > 0 ) { -// b->swap(t,r); -// } -// } -// } - - Fl_Browser *b = options; - for ( int t=1; t<=b->size(); t++ ) - { - for ( int r=t+1; r<=b->size(); r++ ) - { - if ( strcmp(b->text(t), b->text(r)) > 0 ) - { - //b->swap(t,r); - string tmp = b->text(t); - void *ptr = b->data(t); - b->text(t, b->text(r)); - b->data(t, b->data(r)); - b->text(r, tmp.c_str()); - b->data(r, ptr); - } - } - } - - - - // Check if these swapped properly -// Image_Operation *op = (Image_Operation *) b->data(1); -// info("text %s\n", options->text(1)); -// info("name %s\n", op->name.c_str()); - - // Now it works fine? I don't know why it wasn't working? - - arg_values = argv; - arg_count = argc; - opt_index = optind; - - load_orig_files(); - - info("Found "_STF" files\n", filenames.size()); - - // Construct a list of colormap files - // First scan them from /usr/share/spyview/cmaps, then ~/cmaps/ under unix - // Look in current directory, then location of .exe / cmaps under windows. - - string user_path = userdir + DIRECTORY_SEPARATOR + "cmaps" + DIRECTORY_SEPARATOR; - string share_path = sharedir + DIRECTORY_SEPARATOR + "cmaps" + DIRECTORY_SEPARATOR; - find_cmaps(share_path, ""); - info("Loaded "_STF" color maps from %s.\n",cmapfiles.size(),share_path.c_str()); - - if(share_path != user_path) - { - find_cmaps(user_path, "~/"); - info("Loaded "_STF" color maps from %s.\n",cmapfiles.size(),user_path.c_str()); - } - - int ind = cmapch->add("Custom",0,0,-1); - cmapch->menu()[ind].labelfont(FL_HELVETICA_BOLD); // Make spypal stand out as it's different. - - // Update some of the widgets with the default values from the ImageWindow class - gpusing->value(iw->gp_using_string); - gpwith->value(iw->gp_with_string.c_str()); - location_fmt->value("%.1f"); - -#ifdef WIN32 - Gnuplot_Interface::gnuplot_cmd = "\"" + sharedir + "\\pgnuplot.exe\""; -#endif - - // Load the first file - filech->value(0); - - // Find the first valid cmap - for(int n = 0; true; n++) - { - assert(n <= cmapch->size()); - cmapch->value(n); - if (!cmapch->mvalue()->submenu() && cmapch->text(n) != NULL) // null entry at end of submenu - break; - } - - //filech->do_callback(filech, (void *)argv[1]); - //normb->do_callback(); - Fl::add_handler(keyhandler); - //control->show(); - iw->statusCallback = Update_Status_Bar; - // load the colormap - loadsettings(settings_file.c_str()); - // Both of these are now called by loadsettings so we don't load the file twice at startup - //cmapch->do_callback(); - //filech->do_callback(); // load the file before we call show - Fl_Text_Buffer *helpbuf = new Fl_Text_Buffer(); - help_text->buffer(helpbuf); - string help_file = sharedir + DIRECTORY_SEPARATOR + "help.txt"; - info("loading help from file %s\n", help_file.c_str()); - helpbuf->loadfile(help_file.c_str()); - helpbuf->append("\nBuild stamp:\n\n"); - helpbuf->append(BUILDSTAMP); - iw->callback(close_window_callback); - iw->show(argc,argv); - - Fl::run(); - - delete iw; // Make sure we clean up the gnuplot nicely. -} - -int keyhandler(int event) -{ - int key; - int n; - - switch (event) - { - case FL_SHORTCUT: - key = Fl::event_key(); - switch(key) - { - case 'd': - if (Fl::event_state() & FL_SHIFT) - loadImageProcessing(); - else if (Fl::event_state() & FL_CTRL) - loadColors(); - else - { - loadImageProcessing(); - loadColors(); - } - return 1; - case 'e': - filech->do_callback(); - return 1; - case 'u': - if (unitswin->shown()) - unitswin->hide(); - else - unitswin->show(); - return 1; - case 'c': - if (Fl::event_state() & FL_CTRL) - { - if (location_window->shown()) - location_window->hide(); - else - location_window->show(); - return 1; - } - // note falling case!!! - case FL_Escape: - //also for 'c' with no shift - if(!(iw->line_cut_limit & NOLINE)) - return 1; - iw->line_cut_type = NOLINE; - iw->plotLineCut(); - iw->redraw(); - return 1; - case FL_Right: - case ' ': - n = filech->value(); - while (true) - { - n++; - if (n == filech->size() - 1) - n=0; - if (filech->text(n) != NULL && strcmp(filech->text(n), "More") != 0) - break; - } - filech->value(n); - filech->do_callback(); - return 1; - case FL_Left: - case FL_BackSpace: - n = filech->value(); - while (true) - { - n--; - if (n<0) - n = filech->size()-1; - if (filech->text(n) != NULL && strcmp(filech->text(n), "More") != 0) - break; - } - filech->value(n); - filech->do_callback(); - return 1; - case FL_Down: - case 'j': - n = cmapch->value(); - while (true) - { - n++; - if (n == cmapch->size()-1) - n=0; - cmapch->value(n); - if (!cmapch->mvalue()->submenu() && cmapch->text(n) != NULL) // null entry at end of submenu - break; - } - cmapch->do_callback(); - return 1; - case FL_Up: - case 'k': - n = cmapch->value(); - while (true) - { - n--; - if (n<0) - n= cmapch->size()-1; - cmapch->value(n); - if (!cmapch->mvalue()->submenu() && cmapch->text(n) != NULL) - break; - } - cmapch->do_callback(); - return 1; - case 't': - showUsedFiles(Fl::event_state() & FL_SHIFT); - break; - case 'n': - if (Fl::event_state() & FL_SHIFT) - { - Add_Image_Operation(new Image_Operation("neg", "Negate numerical data")); - reload_data(); - pqueue->select(pqueue->size()); - pqueue->do_callback(); - return 1; - } - else - { - normb->do_callback(); - return 1; - } - case 'q': - spyview_exit(); - return 1; // note that this is required if we're exiting by hiding all the windows!!!! - case 's': - iw->exportMTX(true); - return 1; - case 'v': - if (control->visible()) - control->hide(); - else - control->show(); - return 1; - case 'h': - if (helpwin->visible()) - helpwin->hide(); - else - helpwin->show(); - return 1; - case 'o': - if (normwin->visible()) - normwin->hide(); - else - normwin->show(); - return 1; - case 'x': - xsecb->do_callback(); - return 1; - case 'f': - if (!(Fl::event_state() & FL_CTRL) && - !(Fl::event_state() & FL_SHIFT)) - { - if (iw->pfc.win->visible()) - iw->pfc.win->hide(); - else - iw->pfc.win->show(); - return 1; - } - case 'l': - if (Fl::event_state() & FL_CTRL) - { - if (reload_window->shown()) - reload_window->hide(); - else - reload_window->show(); - return 1; - } - case 'r': - iw->setXZoom(1); - iw->setYZoom(1); - return 1; - case 'p': - if (Fl::event_state() & FL_CTRL) - { - iw->setupPS(); - return 1; - } - else if (Fl::event_state() & FL_ALT) - { - info("exporting postscript\n"); - iw->exportPS(); - return 1; - } - else if (Fl::event_state() & FL_SHIFT) - { - iw->imageprinter->ipc->preview_button->do_callback(); - return 1; - } - else - { - if (procwin->shown()) - procwin->hide(); - else - procwin->show(); - } - return 1; - } - } - return 0; -} - -void save_cmap_cb(Fl_Button *o, void*) -{ - iw->colormap_window->saveFile(); -} - -// Called by spypal to indicate the colormap has changed. -void spypal_cb() -{ - int index = reinterpret_cast(cmapch->mvalue()->user_data()); - if(index != -1) - cmapch->value(cmapch->find_item("Custom")); - iw->setColormap(spypal_colormap,spypal_colormap_size); -} - -static bool cmap_is_ppm; // Is the current cmap a ppm file? -void cmapedit_cb(Fl_Button *, void *) -{ - assert(spypal); assert(spypal->win); - if(cmap_is_ppm) - { - printf("CMap is a .ppm; launching import window\n"); - spypal->copy_cmap(iw->getColormap(), iw->getColormapLength()); - spypal->import_controls->show(); - spypal->import_update(); - cmap_is_ppm = false; - } - if(spypal->win->visible()) - spypal->win->hide(); - else - spypal->win->show(); - colormap_callback(); -} - -void cmapch_cb(Fl_Widget *o, void*) -{ - FILE *fp; - int index; - - index = reinterpret_cast(cmapch->mvalue()->user_data()); - - static char label[1024]; - snprintf(label, 1024, "%s - %s", filech->text(), cmapch->text()); - iw->label(label); - snprintf(label, 1024, "Colormap %s", cmapch->text()); - (iw->colormap_window)->label(label); - - if(index == -1) // spypal mode! - { // Don't show the spypal win; that's what the edit button's for. - // spypal->win->show(); - spypal_cb(); - cmap_is_ppm = false; - return; - } - - assert(index >= 0); - assert((unsigned)index < cmapfiles.size()); - - //info("userdata for %s is %d\n", cmapch->value(), index); - const char *filename = cmapfiles[index].c_str(); - //info("loading file _%s_ from index %d, text _%s_\n", cmapfiles[index].c_str(), index, cmapch->text(cmapch->value())); - spypal->import_controls->hide(); - - // File is a spypal colormap - if(strstr(filename,".spp") != NULL) - { - // Don't call spypal_cb; it'll reset the chooser. Hack. - colormap_callback = NULL; - spypal->load(filename); - - colormap_callback = spypal_cb; - - iw->setColormap(spypal_colormap,spypal_colormap_size); - cmap_is_ppm = false; - return; - } - - cmap_is_ppm = true; - spypal->win->hide(); - pixel **image; - pixval maxval; - int rows, cols; - - fp = fopen(filename, "rb"); - if (fp == NULL) - { - perror(filename); - exit(-1); - } - -#ifndef debug_read //debug a binary read problen in windows. implemented some nice ppm read/write code, will leave it in here. - image = ppm_readppm(fp, &cols, &rows, &maxval); - fclose(fp); - - uchar newcmap[3*rows]; - - if (cols > 1) - error("Invalid colormap %s: must contain only one column!\n", filename); - - if (maxval != 255) - error("Invalid colormap %s: color depth must be 8 bit (255 maxval)\n", filename); - - for (int i=0; i 1) - error("PPM fils should be only 1 pixel wide: %s", filename); - fgets(buf, 256, fp); - if (sscanf(buf, "%d", &maxval) != 1) - error("Invalid maxval in PPM file: %s", filename); - if (maxval != 255) - error("Only 8 bit (255 maxval) ppm files supported: %s", filename); - - info("reading file %d rows from file %s, raw file %d\n", rows, filename, raw_file); - uchar newcmap[3*rows]; - int n; - - if (raw_file) - { - if ((n=fread(newcmap, 1, rows*3, fp)) != rows*3) - { - info("feof %d ferror %d\n", feof(fp), ferror(fp)); - error("Short read on PPM file (error after %d bytes of %d, offset %x)\n" - "last read values %x %x %x %x: %s", - n, rows*3, n, - newcmap[n-4], newcmap[n-3], newcmap[n-2], newcmap[n-1], - filename); - } - } - else - { - for (int i=0; isetColormap(newcmap, rows); -} - -void filech_cb(Fl_Widget *, void *) -{ - int index = reinterpret_cast(filech->mvalue()->user_data()); - const char *filename = filenames[index].c_str(); - //info("loading file _%s_ from index %d, text _%s_\n", filename, index, filech->text(filech->value())); - int old_w, old_h; - - // Fixme; this leaks memory. - char *dir = strdup(filename); - dir = dirname(dir); - filename = basename(filename); - current_filename = filename; - if (strcmp(dir, ".") == 0) - dir=strdup(original_dir.c_str()); - info("Changing Directory to: %s\n", dir); - info("Filename: %s\n", filename); - chdir(dir); - - //info("Qmin/max: %e %e\n", iw->id.qmin, iw->id.qmax); - - // This is a bit awkward due to my naming of the w and h variables - // representing the data size, which conflict with the fltk w() and - // h() functions returning the window size... - old_w = ((Fl_Widget*) iw)->w(); - old_h = ((Fl_Widget*) iw)->h(); - - // All file loading is now handled inside ImageWindow (including mtx). - if (iw->loadData(filename) == -1) - { - warn("Error with file %s: reverting to default image\n", filename); - iw->loadData(default_file.c_str()); - } - - update_widgets(); - - // Normalize the data if we've been asked - if (norm_on_load->value()) - iw->normalize(); - - // Give us a nice label - //string label = filename; - //label = label + " - " + cmapch->text(); - //set_units(); - update_title(); -} - -void embed_colormap() -{ - control->add(iw->colormap_window); - - iw->colormap_window->resize(colormap_placeholder->x() + Fl::box_dx(colormap_placeholder->box()), - colormap_placeholder->y() + Fl::box_dy(colormap_placeholder->box()), - colormap_placeholder->w() - Fl::box_dw(colormap_placeholder->box()), - colormap_placeholder->h() - Fl::box_dh(colormap_placeholder->box())); - - if(control->visible()) - iw->show(); - else - iw->colormap_window->set_visible(); -} - -void update_title() -{ - char buf[256]; - if (iw->id.data3d) - snprintf(buf, 256, "%s %.0f (%.3g to %.3g), (%.3g to %.3g)", - current_filename.c_str(), - indexbox->value(), - xmin->value(), xmax->value(), - ymin->value(), ymax->value()); - else - snprintf(buf, 256, "%s (%.3g to %.3g), (%.3g to %.3g)", - current_filename.c_str(), - xmin->value(), xmax->value(), - ymin->value(), ymax->value()); - iw->copy_label(buf); -} - -void set_units() -{ - // First update image data class - iw->id.xmin = xmin->value(); - iw->id.xmax = xmax->value(); - iw->id.ymin = ymin->value(); - iw->id.ymax = ymax->value(); - iw->id.xname = xunitname->value(); - iw->id.yname = yunitname->value(); - iw->id.zname = zunitname->value(); - - // Note: changing these doesn't make any sense! - // These should now be manipulated through imageprocessing operations - // that act on the image data matrix - //iw->id.zmin = zmin->value(); - //iw->id.zmax = zmax->value(); - - // Now update the mtx data class if we have data loaded - - int x,y; - if (iw->id.data3d) - { - switch (dim->value()) - { - case 0: // YZ - x = 1; - y = 2; - break; - case 1: // ZX - x = 2; - y = 0; - break; - case 2: // XY - x = 0; - y = 1; - break; - } - iw->id.mtx.axismin[x] = xmin->value(); - iw->id.mtx.axismax[x] = xmax->value(); - iw->id.mtx.axismin[y] = ymin->value(); - iw->id.mtx.axismax[y] = ymax->value(); - iw->id.mtx.axisname[x] = xunitname->value(); - iw->id.mtx.axisname[y] = yunitname->value(); - iw->id.mtx.dataname = zunitname->value(); - } - - update_widgets(); - iw->plotLineCut(); - update_title(); -} - -void set_3d_units() -{ - iw->id.mtx.axismin[0] = mtx_xmin->value(); - iw->id.mtx.axismin[1] = mtx_ymin->value(); - iw->id.mtx.axismin[2] = mtx_zmin->value(); - iw->id.mtx.axismax[0] = mtx_xmax->value(); - iw->id.mtx.axismax[1] = mtx_ymax->value(); - iw->id.mtx.axismax[2] = mtx_zmax->value(); - iw->id.mtx.axisname[0] = mtx_xname->value(); - iw->id.mtx.axisname[1] = mtx_yname->value(); - iw->id.mtx.axisname[2] = mtx_zname->value(); - - // We also have to update the image window class - - int x,y; - switch (dim->value()) - { - case 0: // YZ - x = 1; - y = 2; - break; - case 1: // ZX - x = 2; - y = 0; - break; - case 2: // XY - x = 0; - y = 1; - break; - } - - iw->id.xmin = iw->id.mtx.axismin[x]; - iw->id.xmax = iw->id.mtx.axismax[x]; - iw->id.ymin = iw->id.mtx.axismin[y]; - iw->id.ymax = iw->id.mtx.axismax[y]; - iw->id.xname = iw->id.mtx.axisname[x]; - iw->id.yname = iw->id.mtx.axisname[y]; - - update_widgets(); - iw->plotLineCut(); -} - - -void saveb_cb(Fl_Widget *, void *) -{ - iw->saveFile(); - //fl_message("File was saved to %s", savebox->value()); - fl_beep(FL_BEEP_MESSAGE); -} - -void update_widgets() -{ - int min, max, width, center; - min = iw->hmin; - max = iw->hmax; - width = (max - min); - center = (max + min)/2; - - minv->value(min); - minslider->value(min); - minroller->value(min); - minv_units->value(iw->id.quant_to_raw(min)); - - maxv->value(max); - maxslider->value(max); - maxroller->value(max); - maxv_units->value(iw->id.quant_to_raw(max)); - - centerv->value(center); - centerslider->value(center); - centerroller->value(center); - centerv_units->value(iw->id.quant_to_raw(center)); - - widthv->value(width); - widthslider->value(width); - widthroller->value(width); - widthv_units->value(iw->id.quant_to_raw(width)-iw->id.quant_to_raw(0)); - - gammav->value(iw->gam); - gammaroller->value(log(iw->gam)); - gammaslider->value(log(iw->gam)); - gcenterv->value(iw->gcenter); - gcenterroller->value(iw->gcenter); - gcenterslider->value(iw->gcenter); - iw->adjustHistogram(); - plothistb->do_callback(); - plotcmapb->do_callback(); - - plotcmapb->value(iw->plot_cmap); - plothistb->value(iw->plot_hist); - invertb->value(iw->invert); - negateb->value(iw->negate); - savebox->value(iw->output_basename); - - plane_a->value(iw->plane_a*((double)iw->h/65535.0)); - plane_aroller->value(iw->plane_a*((double)iw->h/65535.0)); - plane_aslider->value(iw->plane_a*((double)iw->h/65535.0)); - plane_b->value(iw->plane_b*((double)iw->w/65535.0)); - plane_broller->value(iw->plane_b*(double)iw->w/65535.0); - plane_bslider->value(iw->plane_b*((double)iw->w/65535.0)); - - cmap_min->value(iw->cmap_min); - cmap_max->value(iw->cmap_max); - - xzoom_value->value(iw->xzoom); - yzoom_value->value(iw->yzoom); - - xsize->value(iw->w); - ysize->value(iw->h); - - // Update the units window - - xunitname->value(iw->id.xname.c_str()); - yunitname->value(iw->id.yname.c_str()); - zunitname->value(iw->id.zname.c_str()); - - //qinfo("zname update: %s\nq", iw->id.zname.c_str()); - - xmin->value(iw->id.xmin); - ymin->value(iw->id.ymin); - zmin->value(iw->id.qmin); - - xmax->value(iw->id.xmax); - ymax->value(iw->id.ymax); - zmax->value(iw->id.qmax); - - gpusing->value(iw->gp_using_string); - gpwith->value(iw->gp_with_string.c_str()); - - axis_type->value(iw->lc_axis); - - // Update the load settings window - - gp_parse_txt->value(iw->id.mtx.parse_txt); - gp_delft_raw->value(iw->id.mtx.delft_raw_units); - gp_delft_set->value(iw->id.mtx.delft_settings); - gp_col->value(iw->id.gp_column+1); - a_quant_percent->value(iw->id.auto_quant_percent); - - qmin->value(iw->id.qmin); - qmax->value(iw->id.qmax); - - if (iw->id.data3d) - { - controls3d->activate(); - units3d->activate(); - } - else - { - controls3d->deactivate(); - units3d->deactivate(); - } - - if (iw->id.datfile_type == MATRIX) - dat_type_mat->setonly(); - else if (iw->id.datfile_type == GNUPLOT) - dat_type_gp->setonly(); - else if (iw->id.datfile_type == DELFT_LEGACY) - dat_type_delft->setonly(); - else if (iw->id.datfile_type == DAT_META) - dat_type_meta->setonly(); - - //info("update: type is %d\n", iw->id.gpload_type); - if (iw->id.gpload_type == COLUMNS) - gp_type_col->setonly(); - else if (iw->id.gpload_type == INDEX) - gp_type_index->setonly(); - - if (iw->window_size_action == KEEPZOOM) - keep_zoom->setonly(); - else if (iw->window_size_action == KEEPSIZE) - keep_size->setonly(); - else // if (iw->window)_size_action == RESETZOOM) - reset_zoom->setonly(); - - if (iw->id.auto_quant) - a_quant->setonly(); - else - man_quant->setonly(); - - // Update MTX dialog boxes - - indexbox->value(iw->id.mtx_index); - indexslider->value(iw->id.mtx_index); - indexroller->value(iw->id.mtx_index); - - indexbox->maximum(iw->id.mtx.size[iw->id.mtx_cut_type]-1); - indexslider->maximum(iw->id.mtx.size[iw->id.mtx_cut_type]-1); - indexroller->maximum(iw->id.mtx.size[iw->id.mtx_cut_type]-1); - - index_value->value(iw->id.mtx.get_coordinate(iw->id.mtx_cut_type, - iw->id.mtx_index)); - - dim->value((int)iw->id.mtx_cut_type); - mtx_label->value(iw->id.do_mtx_cut_title); - - mtx_x->value(iw->id.mtx.size[0]); - mtx_y->value(iw->id.mtx.size[1]); - mtx_z->value(iw->id.mtx.size[2]); - - mtx_xmin->value(iw->id.mtx.axismin[0]); - mtx_ymin->value(iw->id.mtx.axismin[1]); - mtx_zmin->value(iw->id.mtx.axismin[2]); - - mtx_xmax->value(iw->id.mtx.axismax[0]); - mtx_ymax->value(iw->id.mtx.axismax[1]); - mtx_zmax->value(iw->id.mtx.axismax[2]); - - mtx_xname->value(iw->id.mtx.axisname[0].c_str()); - mtx_yname->value(iw->id.mtx.axisname[1].c_str()); - mtx_zname->value(iw->id.mtx.axisname[2].c_str()); - - xrange->value(iw->line_cut_xauto); - -} - -void Fetch_ProcWindow_Settings(Image_Operation *op) -{ - for(unsigned i = 0; i < op->parameters.size(); i++) - { - Image_Operation::Parameter *p = &(op->parameters[i]); - if(i > proc_bool_parameters.size()) // All buttons must be at end. - { - assert(p->name.c_str()[0] == '.'); - break; - } - - Fl_Check_Button *b = proc_bool_parameters[i]; - Fl_Input *in = proc_parameters[i]; - Fl_Choice *ch = proc_choice_parameters[i]; - switch(p->name.c_str()[0]) - { - case '!': - p->value = b->value(); - break; - case '?': - p->value = reinterpret_cast(ch->mvalue()->user_data_); - break; - case '.': - p->value = 0; - break; - default: - p->value = atof(in->value()); - break; - } - } - if(last_proc_side == pqueue) - op->enabled = enable_filter->value(); -} - -void Set_ProcWindow_Settings(Image_Operation *op) -{ - bool redraw_window = false; - int bcount = 0; // Number of buttons so far. - assert(proc_bool_parameters.size() == proc_parameters.size()); - assert(proc_choice_parameters.size() == proc_parameters.size()); - - for(unsigned i = 0; i < proc_button_parameters.size(); i++) - { - Fl_Button *but = proc_button_parameters[i]; - but->hide(); - but->callback( (Fl_Callback *) NULL,NULL); - } - for(unsigned i = 0; i < op->parameters.size(); i++) - { - Image_Operation::Parameter *p = &(op->parameters[i]); - if(p->name.c_str()[0] == '.') // Button - { - assert(bcount < proc_button_parameters.size()); - Fl_Button *but = proc_button_parameters[bcount++]; - but->label(p->name.c_str()+1); - but->value(static_cast(p->value)); - if(p->cb) - but->callback(p->cb,NULL); - but->show(); - continue; - } - - assert(op->parameters.size() > i-bcount); - Fl_Check_Button *b = proc_bool_parameters[i-bcount]; - Fl_Input *in = proc_parameters[i-bcount]; - Fl_Choice *ch = proc_choice_parameters[i-bcount]; - switch(p->name.c_str()[0]) - { - case '.': - assert(0); - case '!': // Boolean - { - if(strcmp(p->name.c_str()+1,b->label()) != 0) - redraw_window = true; - b->label(p->name.c_str()+1); - b->value(static_cast(p->value)); - b->show(); - in->hide(); - ch->hide(); - break; - } - case '?': // Choice - { - redraw_window = true; // Lazy lazy lazy - char *tmp = strdup(p->name.c_str()); - char *s1 = strchr(tmp,' '); - assert(s1 != NULL); - *s1++ = 0; // tmp+1 is now the choice name - if(strcmp(tmp+1,ch->label()) != 0) - redraw_window = true; - ch->copy_label(tmp+1); - ch->clear(); - while(isspace(*s1)) - s1++; - while(1) - { - char *s2 = strchr(s1,' '); - if(s2 != NULL) - *s2 = 0; - char buf[1024]; - int val; - if(sscanf(s1," %d,%s ",&val,buf) != 2) - { - fprintf(stderr,"Error parsing format string \"%s\" from %s\n",s1,p->name.c_str()); - exit(1); - } - int idx = ch->add(buf,(const char *)NULL,NULL,(void *)val); - if(val == p->value) - ch->value(idx); - if(s2 == NULL) - break; - else - s1 = s2+1; - } - b->hide(); - in->hide(); - ch->show(); - free(tmp); - break; - } - default: - { - if(p->name != in->label()) - redraw_window = true; - in->label(p->name.c_str()); - char buf[1024]; - snprintf(buf,sizeof(buf),"%g",p->value); - in->value(buf); - in->show(); - b->hide(); - ch->hide(); - break; - } - } - } - for(unsigned i = op->parameters.size()-bcount; i < proc_parameters.size(); i++) - { - proc_parameters[i]->hide(); - proc_bool_parameters[i]->hide(); - proc_choice_parameters[i]->hide(); - } - proc_description->value(op->description.c_str()); - if(last_proc_side == pqueue) - { - enable_filter->value(op->enabled); - enable_filter->activate(); - } - else - enable_filter->deactivate(); - if(redraw_window) // Sometimes, if the labels get longer, we get dead characters in the background. - procwin->redraw(); -} - -void Define_Image_Operation(Image_Operation *op) -{ - options->add(op->name.c_str(), op); -} - -void Add_Image_Operation(Image_Operation *op) -{ - info("Adding operation: %s\n", op->name.c_str()); - Image_Operation *new_op = new Image_Operation(*op); // Copy so we don't share settings. - pqueue->add(op->name.c_str(), new_op); -} - -void Update_Status_Bar(int key, bool down) -{ - static double ox, oy; - - int i = iw->dounzoom(Fl::event_x(),iw->xzoom); - int j = iw->dounzoom(Fl::event_y(),iw->yzoom); - - double x = iw->id.getX(i); - double y = iw->id.getY(j); - - if(ox != x || oy != y) - { - static char locbuf[1024]; - static char tmpbuf[1024]; - static char fmt_string[1024]; - static char fmt[1024]; - - // Format is set in the Cursor Position window - snprintf(fmt, sizeof(fmt), "%s", location_fmt->value()); - - // Update the location bar at the bottom of the controls window - sprintf(fmt_string, "%s,%s = %s %%s", fmt, fmt, fmt); - snprintf(locbuf,sizeof(locbuf),fmt_string, - x,y,iw->dataval(i,j), iw->id.zname.c_str()); - location_bar->label(locbuf); - - // Update the "Cursor Postion" window as well - snprintf(tmpbuf, sizeof(tmpbuf), fmt, x); - location_x->value(tmpbuf); - location_x->label(xunitname->value()); - x_col->value(i); - - snprintf(tmpbuf, sizeof(tmpbuf), fmt, y); - location_y->value(tmpbuf); - location_y->label(yunitname->value()); - y_row->value(j); - - snprintf(tmpbuf, sizeof(tmpbuf), fmt, iw->dataval(i,j)); - location_data->value(tmpbuf); - data_name->value(zunitname->value()); - - // Update the zoom window information in the Cursor window - - if (iw->zoom_window) - { - zoom_group->activate(); - int x1,y1,x2,y2; - iw->zoom_window->getSourceArea(x1,y1,x2,y2); - - zx1->value(x1); - snprintf(tmpbuf, sizeof(tmpbuf), fmt, iw->id.getX(x1)); - zx1v->value(tmpbuf); - - zx2->value(x2); - snprintf(tmpbuf, sizeof(tmpbuf), fmt, iw->id.getX(x2)); - zx2v->value(tmpbuf); - - zy1->value(y1); - snprintf(tmpbuf, sizeof(tmpbuf), fmt, iw->id.getY(y1)); - zy1v->value(tmpbuf); - - zy2->value(y2); - snprintf(tmpbuf, sizeof(tmpbuf), fmt, iw->id.getY(y2)); - zy2v->value(tmpbuf); - } - else - zoom_group->deactivate(); - - ox = x; - oy = y; - - } - - static const int event_mask=FL_CTRL|FL_SHIFT; - static std::map h; -// This is where the status bar help goes -// Add entries as needed. - if(h.size() == 0) - { - h[0] = "B1: X Linecut; B2: Y Linecut; B3: Control Win"; - h[FL_CTRL] = "B1: Arb Linecut; B2: Move Endpt; B3: Drag Linecut"; - h[FL_SHIFT] = "B1: Drag Zoom; B3: Move Zoom Window"; - } - static int last_state = -1; - - int state = Fl::event_state() & event_mask; - // Horrible hack to handle XWindows shift state bug - if(key == FL_Shift_L || key == FL_Shift_R) - { - if(down) - state = state | FL_SHIFT; - else - state = state & ~FL_SHIFT; - } - if(key == FL_Control_L || key == FL_Control_R) - { - if(down) - state = state | FL_CTRL; - else - state = state & ~FL_CTRL; - } - - if(last_state != state) - { - // This will automagically make an empty entry if event_state - // is not in the help database - const char *help = h[state].c_str(); - help_bar->value(help); - last_state = state; - } -} - -void reload_cb(Fl_Widget *, void *) -{ - dirent **dirlist; - int n; - - n = fl_filename_list(".", &dirlist); - if (replaceb->value()) clear_files(); - - for (int i = 0; id_name, reload_text->value())) - add_file(dirlist[i]->d_name); - - if (filenames.size() == 0) - { - fl_alert("No files found!! Reverting to the list of files given on command line."); - load_orig_files(); - } - - filech->value(0); - filech->do_callback(); - - for (int i = n; i > 0;) - free((void*)(dirlist[--i])); - free((void*)dirlist); - -} - - -/* - =============== Serialization Code ========================== - boost stores class versions, not archive versions. In order to maintain backwards compatability - for the "top level" objects (of which there are probably too many, because the FLTK widgets aren't - encapsulated in a class), we introduce a helper class here. */ -const char * spyviewSettingsDir; // Ugly ugly ugly -- this belongs in the class, but spyview_ui.C wants it as well. - // Maybe the class shouldn't be static... - -class Spyview_Serializer_t -{ -public: - typedef boost::archive::text_iarchive input_archive; - typedef boost::archive::text_oarchive output_archive; - -// Directory setup functions. - std::string settingsDir; - - void maybe_mkdir(const char *name) - { -#ifdef WIN32 - if(mkdir(name) == 0) -#else - if(mkdir(name,0777) == 0) -#endif - return; - - switch(errno) - { - case EEXIST: - return; - default: - warn("Unable to create directory \"%s\": %s\n",name,strerror(errno)); - return; - } - } - - void initSettingsDir() // Use the system dependent userdir - { - string buf = userdir; - maybe_mkdir(buf.c_str()); - buf = buf + DIRECTORY_SEPARATOR + "settings"; // note += won't work because the cast is wrong... - settingsDir = buf; - maybe_mkdir(buf.c_str()); - spyviewSettingsDir = settingsDir.c_str(); - } - -// Save/load functions - void save(std::string &name) - { - initSettingsDir(); - if(name.empty()) - { - name = settingsDir + DIRECTORY_SEPARATOR + "default.svs"; - } - const char *fname = name.c_str(); - try - { - std::ofstream ofs(fname, std::ios::binary); - if(!ofs.good()) - throw(1); - output_archive oa(ofs); //doesn't work under win32? - oa & (*this); - } - catch (boost::archive::archive_exception &e) - { - warn("Error saving spyview settings: %s\n",e.what()); - } - catch (std::exception &e) - { - warn("Error saving settings file \"%s\": %s (%s)\n",fname,e.what(),strerror(errno)); - } - catch (...) - { - error("Unknown error from settings file\n"); - } - }; - - void load(std::string &name) - { - initSettingsDir(); - if(name.empty()) - { - - name = settingsDir + DIRECTORY_SEPARATOR + "default.svs"; - } - - const char *fname = name.c_str(); - info("loading settings from %s\n", fname); - try - { - std::ifstream ifs(fname, std::ios::binary); - if(!ifs.good()) - { - warn("IFS is not good!\n"); - throw(1); - } - input_archive ia(ifs); - ia & (*this); - } - catch (boost::archive::archive_exception &e) - { - warn("Error loading settings %s\nTry overwriting the default settings file to get rid of this error.\n",e.what()); - } - catch (std::exception &e) - { - warn("Spyview serialization error; did not load settings: %s (%s)\nTry overwriting the default settings file to get rid of this error.\n",e.what(),typeid(e).name()); - } - catch (...) - { - warn("Unable to load settings file \"%s\": %s\nTry overwriting the default settings file to get rid of this error.\n",fname,strerror(errno)); - } - }; - - template - void serialize(Archive & ar, const unsigned int version) - { - ar & (*iw); - - // Newer versions of spyview hide the extensions on the colormaps. - // This causes the chooser serialization to ignore extensions so old - // save files still work. - push_chooser_equality(chooser_equality_noextension); - ar & flcast(cmapch); - pop_chooser_equality(); - - ar & flcast(norm_on_load); - ar & flcast(squareb); - ar & flcast(dim); - - if (version >= 1) - ar & flcast(gpwith); - if (version >= 2) - { - ar & iw->id.datfile_type; - ar & iw->id.gpload_type; - ar & iw->id.gp_column; - //ar & iw->id.mtx_cut_type; // This one is quite annoying, actually... - } - if (version >= 3) - { - ar & iw->id.mtx.parse_txt; - Fl_Input tmp(0,0,0,0,""); // This used to be ipc.preview_cmd - //ar & flcast(iw->ipc.preview_cmd); - ar & flcast(&tmp); - } - if (version >= 4) - { - ar & iw->id.mtx.delft_raw_units; - } - if (version >= 5) - { - ar & iw->id.mtx.delft_settings; - } - if(version == 6) - { - warn("Version 6 archives were bad.. Spypal settings ignored\n"); - } - if(version >= 7) - { - ar & (*spypal); - } - if(Archive::is_loading::value) - { - wpbox->value(iw->wpercent); - bpbox->value(iw->bpercent); - cmrot->value(iw->colormap_rotation_angle); - cmrot_roller->value(iw->colormap_rotation_angle); - if (version >= 1) - iw->gp_with_string = gpwith->value(); - iw->setXZoom(iw->xzoom); // make sure to call this after updating class variables as it calls update_widgets() - if(reinterpret_cast(cmapch->mvalue()->user_data()) == -1) // Custom - { - cmap_is_ppm = false; - spypal->recalculate(true); - } - } - }; -}; -static Spyview_Serializer_t Spyview_Serializer; - -BOOST_CLASS_VERSION(Spyview_Serializer_t, 7); // Increment this if the archive format changes. - -void savesettings(std::string name) -{ - Spyview_Serializer.save(name); -} - -void loadsettings(std::string name) -{ - Spyview_Serializer.load(name); - cmapch->do_callback(); - filech->do_callback(); -} - -/* Motivation: open *always* returns the lowest numbered file descriptor. So by mapping which ones - it returs, we can figure out which are in use. */ -void showUsedFiles(bool leak) // Simulate a file descriptor leak if leak is true -{ - std::vector desc; - size_t ulen=80; - int cnt = 0; - int used[ulen]; - - while(1) - { - int f = open(filenames[0].c_str(), O_RDONLY); // A file that should be available in both windows and unix. - if(f < 0) - { - warn("Unable to check file descriptors! First .pgm file \"%s\": %s\n", - filenames[0].c_str(), strerror(errno)); - goto cleanup; - } - if(f > ulen) - { - close(f); - break; - } - else - desc.push_back(f); - } - - for(int i = 0; i < ulen; i++) - used[i] = 1; - for(int i = 0; i < desc.size(); i++) - { - if(desc[i] < ulen) - used[desc[i]] = 0; - } - printf("Leak map: "); - for(int i = 0; i < ulen; i++) - { - printf("%d", used[i]); - if(used[i]) - cnt++; - } - printf("\n"); - printf("%d Total descriptors in use\n",cnt); - cleanup: - while(desc.size() > leak ? 1 : 0) - { - close(desc.back()); - desc.pop_back(); - } -} -//#endif - -void loadColors(char *fn) -{ - // Automatically pick filename - string filename; - if (fn == NULL) - { - filename = iw->output_basename; - filename += ".colors"; - } - else - filename = fn; - info("loading colors to file %s\n", filename.c_str()); - std::ifstream ifs(filename.c_str()); - if (!ifs.good()) - { - info("Error opening colors file: %s\n", filename.c_str()); - return; - } - boost::archive::text_iarchive ar(ifs); - - // Version 1: stuff to archive: - // - // hmin - // hmax - // gamma - // gamma_center - // quant_min - // quant_max - // colormap - // - - int version; - ar & version; - ar & iw->hmin; - ar & iw->hmax; - ar & iw->gam; - ar & iw->gcenter; - ar & iw->id.qmin; - ar & iw->id.qmax; - ar & flcast(cmapch); - - // After loading, we will: - // - // - call update_widgets() - // - turn off autonormalize (spyview gui widget) - // - turn off autoquantize (in ImageData) - // - requantize the data - // - set the min and max - - norm_on_load->value(0); - iw->id.auto_quant = false; - iw->id.quantize(); - cmapch->do_callback(); - iw->adjustHistogram(); // this should remap and replot the data - update_widgets(); -} - - -void saveColors(char *fn) -{ - // Automatically pick filename - string filename; - if (fn == NULL) - { - filename = iw->output_basename; - filename += ".colors"; - } - else - filename = fn; - info("saving colors to file %s\n", filename.c_str()); - std::ofstream ofs(filename.c_str()); - if (!ofs.good()) - { - info("Error saving to colors file: %s\n", filename.c_str()); - return; - } - boost::archive::text_oarchive ar(ofs); - - // Note -- we need to set the version for the save direction, - // otherwise it'll be random. - int version = 1; - ar & version; - // All this stuff is in version 1 - ar & iw->hmin; - ar & iw->hmax; - ar & iw->gam; - ar & iw->gcenter; - ar & iw->id.qmin; - ar & iw->id.qmax; - ar & flcast(cmapch); -} - -void saveImageProcessing(char *fn) -{ - // Automatically pick filename - string filename; - if (fn == NULL) - { - filename = iw->output_basename; - filename += ".img_proc"; - } - else - filename = fn; - info("saving image processing to file %s\n", filename.c_str()); - std::ofstream ofs(filename.c_str()); - if (!ofs.good()) - { - warn("Error saving to image processing file: %s\n", filename.c_str()); - return; - } - boost::archive::text_oarchive ar(ofs); - - int tmp = pqueue->size(); - ar & tmp; - fprintf(stderr,"Saving %d process entries\n",tmp); - for(int i = 1; i <= pqueue->size(); i++) - { - std::string tmp = pqueue->text(i); - ar & tmp; - Image_Operation * t = reinterpret_cast(pqueue->data(i)); - ar & t; - } -} - -void loadImageProcessing(char *fn) -{ - // Automatically pick filename - string filename; - if (fn == NULL) - { - filename = iw->output_basename; - filename += ".img_proc"; - } - else - filename = fn; - info("loading image_processing from file %s\n", filename.c_str()); - std::ifstream ifs(filename.c_str()); - if (!ifs.good()) - { - info("Error opening image processing file: %s\n", filename.c_str()); - return; - } - boost::archive::text_iarchive ar(ifs); - - for(int i = 1 ; i <= pqueue->size(); i++) - delete reinterpret_cast(pqueue->data(i)); - int len; - pqueue->clear(); - ar & len; // This has the size of the expected queue - fprintf(stderr,"Loading %d process entries\n",len); - for(int i = 1; i <= len; i++) - { - std::string tmp; - ar & tmp; - Image_Operation *op; - ar & op; - pqueue->add(tmp.c_str(),op); - } - reload_data(); -} - diff --git a/spyview/static_link_notes.txt~ b/spyview/static_link_notes.txt~ deleted file mode 100644 index 0f0d35e..0000000 --- a/spyview/static_link_notes.txt~ +++ /dev/null @@ -1,3 +0,0 @@ -otool -L - -list the libraries a program is linked against diff --git a/spyview/update_exe.sh~ b/spyview/update_exe.sh~ deleted file mode 100755 index b481f20..0000000 --- a/spyview/update_exe.sh~ +++ /dev/null @@ -1,3 +0,0 @@ -set -x -exe="spybrowse.exe dat2mtx.exe spyview.exe spyview_console.exe spybrowse_console.exe mtxdiff.exe huettel2mtx.exe toeno2mtx.exe *.bat help.txt" -scp $exe kavli:public_html/spyview/windows_exe diff --git a/spyview/update_webpage.sh~ b/spyview/update_webpage.sh~ deleted file mode 100755 index ccca614..0000000 --- a/spyview/update_webpage.sh~ +++ /dev/null @@ -1,21 +0,0 @@ -set -x -# remote=qt.tn.tudelft.nl -# exe="spybrowse.exe dat2mtx.exe spyview.exe spyview_console.exe spybrowse_console.exe mtxdiff.exe huettel2mtx.exe toeno2mtx.exe *.bat pgnuplot.exe wgnuplot.exe gilles2mtx.exe help.txt updates_page.url ns2pgm.exe" -# cp $exe spyview_windows -# scp $exe $remote:public_html/spyview/windows_exe -# rm spyview_windows.zip -# zip -r spyview_windows.zip spyview_windows -# #(cd spyview_windows; zip -r ../spyview_windows.zip .) -# scp spyview_windows.zip $remote:public_html/spyview/ -# scp spyview_console.exe help.txt $remote:public_html/spyview/ - -# Now we're building on the local machine -exe="spybrowse.exe dat2mtx.exe spyview.exe spyview_console.exe spybrowse_console.exe mtxdiff.exe huettel2mtx.exe toeno2mtx.exe *.bat pgnuplot.exe wgnuplot.exe gilles2mtx.exe help.txt updates_page.url ns2pgm.exe" -cp $exe spyview_windows -cp ~/public_html/spyview/windows_exe -rm spyview_windows.zip -zip -r spyview_windows.zip spyview_windows -#(cd spyview_windows; zip -r ../spyview_windows.zip .) -cp spyview_windows.zip ~/public_html/spyview/ -cp spyview_console.exe help.txt ~/public_html/spyview/ -date > ~/public_html/spyview/update.html