// Copyright (C) 1996 Eleftherios Gkioulekas // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include #include #include #include #include #include "qx.h" // // Color conversion functions // // Specify the color in (r,g,b) variables in the 0..1 range. // You are returned an Xlib XColor structure XColor QxColor(double r,double g,double b) { XColor col; col.red = (unsigned short int) (65535.*r); col.green = (unsigned short int) (65535.*g); col.blue = (unsigned short int) (65535.*b); return col; } double QxLum(double r,double g,double b) { return 0.299*r+0.587*g+0.114*b; } // Red the red,green,blue fields of an Xlib XColor. // Values returned in the 0..1 range int QxColorRed (XColor col) { return int(col.red)/256; } int QxColorGreen(XColor col) { return int(col.green)/256; } int QxColorBlue (XColor col) { return int(col.blue)/256; } // Abort in case of error void QxError(char *error) { cerr << "qx: " << error; abort(); } //////////////////// // Our colormaps! // //////////////////// // How to make your own colormap: // If you intend to use the PutDataOnWindow methods then your colormaps // should follow the following conventions: // col[0] = black (i.e (0,0,0) ) // col[1] = "white" (ex. (1,1,1) ) // col[2..N+2] = your colormap // Note that white can be other color if your colormap includes white. // For example in the grey-scale colormap, white is red+blue // In general white should be a color well-contrasted by your colormap. // You may want to draw axises or boundary on top of your colored image. // How to use: // XColor *colormap = QxMakeGreyscaleColormap(200); // server.ColorRequest(200,colormap); // Here is a greyscale colormap XColor *QxMakeGreyscaleColormap(int N,double cor) { XColor *col = new XColor[N]; col[0] = QxColor(0,0,0); col[1] = QxColor(0,1,0); double lum; for (int i=2;i 0) { if (ColorRequest(N)) break; } return N; } // Set the color for a colorcell QxServer* QxServer::SetColor(int pxl,XColor col) { assert(pxl >= 0 && pxl < Ncols); cols[pxl] = col; cols[pxl].pixel = pixels[pxl]; cols[pxl].flags = DoRed | DoGreen | DoBlue; return this; } // This function will take an array of 'n' colors 'col' and set consecutive // colorcells with these colors, starting from 'start' QxServer* QxServer::SetColor(int start,XColor *col,int n) { assert(start+n-1 < Ncols); for (int i=0;i0 ? 1 : (dx<0 ? -1:0)); sy = (dy>0 ? 1 : (dy<0 ? -1:0)); dx = abs(dx); dy = abs(dy); ax = dx*2; ay = dy*2; if (dy= 0) { dec -= ax; y0 += sy; } x0 += sx; dec += ay; } } else { dec = ax-dy; while(1) { SetPixel(x0,y0,color); if (y0==y1) break; if (dec >= 0) { dec -= ay; x0 += sx; } y0 += sy; dec += ax; } } return this; } QxImageWindow* QxImageWindow::DrawLine (QxCoords c,double dx0,double dy0,double dx1,double dy1,int color) { DrawLine(c.ox + int(dx0*c.scale), c.oy + int(dy0*c.scale), c.ox + int(dx1*c.scale), c.oy + int(dy1*c.scale), color); return this; } // You probably want to use this to clear the window QxImageWindow* QxImageWindow::FillWindow(int color) { for (int x=0;x Index mapping int mapping[256]; for (int i=0;i<256;i++) mapping[i] = 0; for (int i=0;i=Ncols) col=Ncols-1; // Clip if needed SetPixel(i,j,col); } return this; } // This function takes a data value 'data' located at (i,j) and places // it on our window. The pixel color used is scaled from the range (min,max) // to our colormap. QxImageWindow* QxImageWindow::PutDataOnWindow (int i,int j,double data,double min,double max) { double val = (data-min)/(max-min); int col = 2+int((Ncols-2)*val); if (col<2) col=2; if (col>=Ncols) col=Ncols-1; SetPixel(i,j,col); } // This function takes a data value 'data' located at (i,j) and places // it on our window. The pixel color used is scaled from the range (min,max) // to our colormap. However a big part of the colormap is blacked out. // As a result, we will obtain a contour plot. The variable 'b' // determines how much to black out. Can take values from 1 to 100 QxImageWindow* QxImageWindow::PutDataOnWindow (int i,int j,double data,double min,double max,int b) { double val = (data-min)/(max-min); double dcol = 2+(Ncols-2)*val; double ddcol = dcol-int(dcol); int col = (0.5-b/200. < ddcol && ddcol < 0.5+b/200.) ? int(dcol) : 0; if (col<2) col=2; if (col>=Ncols) col=Ncols-1; SetPixel(i,j,col); } // This function does the same as the previous one, but it is meant to // be used for these cases where the array 'data' is very small and we // want to magnify it. We assume that the scaling of the array is // the same as the scaling of the window and that "ratio" is the size of // an array cell in pixel by pixel. QxImageWindow* QxImageWindow::PutDataOnWindow (double **data,int ratio,double min,double max) { int col; double val; for (int i=0;i=Ncols) col=Ncols-1; // Clip if needed for (int x=0;x