casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
GLPixelCanvasColorTable.h
Go to the documentation of this file.
00001 //# GLPixelCanvasColorTable.h: color table provision for X11 devices
00002 //# Copyright (C) 2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //# 
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //# 
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //# 
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //# 
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //# 
00026 //# $Id$
00027 
00028 #ifndef TRIALDISPLAY_GLPIXELCANVASCOLORTABLE_H
00029 #define TRIALDISPLAY_GLPIXELCANVASCOLORTABLE_H
00030 
00031 #include <casa/aips.h>
00032 #include <graphics/X11/X11Util.h>
00033 
00034 #include <graphics/X11/X_enter.h>
00035 #include <X11/Xlib.h>
00036 #include <X11/Xutil.h>
00037 #include <graphics/X11/X_exit.h>
00038 
00039 #include <casa/Arrays/Vector.h>
00040 #include <display/Display/DisplayEnums.h>
00041 #include <display/Display/PixelCanvasColorTable.h>
00042 
00043 
00044 namespace casa { //# NAMESPACE CASA - BEGIN
00045 
00046 // <summary>
00047 // Implementation of PixelCanvasColorTable for OpenGL.
00048 // </summary>
00049 // <synopsis>
00050 // GLPixelCanvasColorTable is an X11PixelCanvasColorTable that has been
00051 // modified to work within the constraints of the GLPixelCanvas. (e.g. Not
00052 // assuming the default visual).
00053 //
00054 // Colormap values are written to a virtual colortable (an internal array).
00055 // For Indexed (PseudoColor) windows, the values are sent to the hardware
00056 // colormap. For RGB (TrueColor) windows, the virtual colortable is used
00057 // to emulate a hardware lookup table.
00058 // </synopsis>
00059 //
00060 // <prerequisite>
00061 // <li> <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00062 // <li> How to get the X Screen pointer.
00063 // </prerequisite>
00064 //
00065 // <etymology>
00066 // </etymology>
00067 //
00068 // <thrown>
00069 //    AipsError
00070 // </thrown>
00071 // <use visibility=export>
00072 
00073 // Colormap entry for the virtual colormap.
00074 class GLVColorTableEntry {
00075   public:
00076         GLVColorTableEntry();
00077 
00078         void operator=(const GLVColorTableEntry &);
00079 
00080         // Store/get the values.
00081         void put(const float red, const float green, const float blue)
00082         {       red_ = red; green_ = green; blue_ = blue;
00083         }
00084 
00085         void get(float &red, float &green, float &blue)const
00086         {       red = red_; green = green_; blue = blue_;
00087         }
00088 
00089         uInt    getIndex()const{return index_;}
00090         void    setIndex(const uInt i){index_ = i;}
00091 
00092         uLong getPixel()const{return pixel_;}
00093         void setPixel(const unsigned long p){pixel_ = p;}
00094 
00095         friend ostream &operator<<(ostream &s, const GLVColorTableEntry &x);
00096 
00097   private:
00098         uInt    index_;                 // Index into map for this entry.
00099         uLong   pixel_;                 // Real index or color value.
00100         float   red_, green_, blue_;    // Color component values. (0..1).
00101 };
00102 
00103 class GLPixelCanvasColorTable : public PixelCanvasColorTable
00104 {
00105 public:
00106 
00107   // <group>
00108   GLPixelCanvasColorTable();
00109 
00110   ~GLPixelCanvasColorTable();
00111 
00112   GLPixelCanvasColorTable(::XDisplay *dpy,
00113                           Display::ColorModel mapType = Display::RGB,
00114                           Float percent=90.0,
00115                           XVisualInfo *visInfo=NULL);
00116   // </group>
00117 
00118   // allocate cells for colormaps
00119   Bool allocCells(uInt nCells);
00120 
00121   // deallocate cells for colormaps
00122   Bool deallocCells();
00123 
00124   // Allocate the best color cube given the map
00125   Bool allocColorCube();
00126   // Allocate a color cube of a specific size
00127   Bool allocColorCube(uInt n1, uInt n2, uInt n3);
00128   // Allocate a color cube within the ranges of sizes
00129   Bool allocColorCubeMinMax(uInt n1min, uInt n2min, uInt n3min,
00130                             uInt n1max, uInt n2max, uInt n3max);
00131   // Copy color cube info from the mapRef
00132   void copyColorCube(const GLPixelCanvasColorTable & mapRef);
00133   // Fill a color cube with an RGB spectrum
00134   void fillColorCubeRGB();
00135   enum FILLMODE{FILLRGB, FILLRBG, FILLGRB, FILLGBR, FILLBRG, FILLBGR};
00136   static void colorFillRGB(
00137                         Vector<Float> &r, Vector<Float> &g, Vector<Float> &b,
00138                         uInt nr, uInt ng, uInt nb,
00139                         FILLMODE mode = FILLRGB);
00140 
00141   static void colorFillRGB(
00142                         Vector<Float> &r, Vector<Float> &g, Vector<Float> &b,
00143                         uInt ncolors, FILLMODE mode= FILLRGB);
00144   // Fill a color cube with an HSV spectrum
00145   void fillColorCubeHSV();
00146 
00147   // Merge separate channel data into an output image.
00148   // This function maps floating values between 0 and 1
00149   // into a output image suitable for PixelCanvas::drawImage().
00150   // <group>
00151   void mapToColor3(Array<uLong> & out,
00152                    const Array<Float> & chan1in,
00153                    const Array<Float> & chan2in,
00154                    const Array<Float> & chan3in);
00155   void mapToColor3(Array<uLong> & out,
00156                    const Array<Double> & chan1in,
00157                    const Array<Double> & chan2in,
00158                    const Array<Double> & chan3in);
00159   // </group>
00160 
00161   // This one maps values between 0 and the integer
00162   // maximum value for each channel into a single
00163   // output image suitable for PixelCanvas::drawImage().
00164   // <group>
00165   void mapToColor3(Array<uLong> & out,
00166                    const Array<uShort> & chan1in,
00167                    const Array<uShort> & chan2in,
00168                    const Array<uShort> & chan3in);
00169   void mapToColor3(Array<uLong> & out,
00170                    const Array<uInt> & chan1in,
00171                    const Array<uInt> & chan2in,
00172                    const Array<uInt> & chan3in);
00173   // </group>  
00174 
00175   // (Multichannel Color)
00176   // Transform arrays from the passed color model into
00177   // the colormodel of the XPCCT.
00178   // Does nothing if colorModel is Display::Index.
00179   // It is assumed that input arrays are in the range of [0,1]
00180   Bool colorSpaceMap(Display::ColorModel, 
00181                      const Array<Float> & chan1in, 
00182                      const Array<Float> & chan2in, 
00183                      const Array<Float> & chan3in, 
00184                      Array<Float> & chan1out, 
00185                      Array<Float> & chan2out, 
00186                      Array<Float> & chan3out);  
00187 
00188   // map [0,N-1] into colorpixels, where N is the current colormap size
00189   // The values are returned as unsigned integers in their respective 
00190   // array.  
00191   // <note role="warning">uChar type may not have enough bits
00192   // to hold the pixel index on some high-end graphics systems </note>
00193   // <note role="warning">uShort type may not have enough bits
00194   // to hold the pixel index on some high-end graphics systems </note>
00195   // <group>
00196   void mapToColor(const Colormap * map, Array<uChar> & outArray, 
00197                   const Array<uChar> & inArray, Bool rangeCheck = True) const;
00198   void mapToColor(const Colormap * map, Array<uShort> & outArray, 
00199                   const Array<uShort> & inArray, Bool rangeCheck = True) const;
00200   void mapToColor(const Colormap * map, Array<uInt> & outArray, 
00201                   const Array<uInt> & inArray, Bool rangeCheck = True) const;
00202   void mapToColor(const Colormap * map, Array<uLong> & outArray, 
00203                   const Array<uLong> & inArray, Bool rangeCheck = True) const;
00204   // </group>
00205 
00206   // same as above except the matrix is operated on in place.  Only unsigned
00207   // values make sense here.
00208   // <group>
00209   void mapToColor(const Colormap * map, Array<uChar> & inOutArray, 
00210                   Bool rangeCheck = True) const;
00211   void mapToColor(const Colormap * map, Array<uShort> & inOutArray, 
00212                   Bool rangeCheck = True) const;
00213   void mapToColor(const Colormap * map, Array<uInt> & inOutArray, 
00214                   Bool rangeCheck = True) const;
00215   void mapToColor(const Colormap * map, Array<uLong> & inOutArray, 
00216                   Bool rangeCheck = True) const;
00217   // </group>
00218   
00219   // print details of class to ostream
00220   friend ostream & operator << (ostream & os, const GLPixelCanvasColorTable & pcc);
00221 
00222   // Is the hardware colormap resizeable?  ie. is it write-only?
00223   virtual Bool staticSize() 
00224     { return (readOnly_ && decomposedIndex_); }
00225 
00226   // resize the map if allowed.  Returns True if resize was accepted
00227   // <group>
00228   Bool resize(uInt newSize);
00229   Bool resize(uInt nReds, uInt nGreens, uInt nBlues);
00230   // </group>
00231 
00232   // Install colors into the color table. Offset is zero-based. Colors
00233   // are installed into the PixelCanvasColorTable until the Arrays run out
00234   // or until the end of the colortable is reached.  This only has an
00235   // effect if the ColorModel is Index.  Values are clamped to [0.0,1.0].
00236   Bool installRGBColors(const Vector<Float> & r, const Vector<Float> & g, 
00237                         const Vector<Float> & b, uInt offset = 0);
00238 
00239   // Return the total number of RW colors currently in use.
00240   uInt nColors() const;
00241 
00242   // Return the number of colors per component in the map.  Throws
00243   // an exception if this is not an HSV or RGB ColorTable.
00244   virtual void nColors(uInt &n1, uInt &n2, uInt &n3) const;
00245 
00246   // Return the depth in bits of the colors
00247   uInt depth() const;
00248   
00249   // Return the number of colors that are still unallocated
00250   uInt nSpareColors() const;
00251 
00252   // Return pointer to display that is being used
00253   ::XDisplay * display() const;
00254   // Return pointer to screen that is being used
00255   Screen * screen() const;
00256   // Return pointer to visual that is being used
00257   Visual * visual() const;
00258   // Return pointer to visual info that is being used
00259   XVisualInfo *visualInfo() const{ return visualInfo_;}
00260   // Return XID of X "virtual colormap" being used
00261   XColormap xcmap() const;
00262   
00263   // Return True if the table is in colorIndex mode
00264   Bool indexMode() const { return (colorModel_ == Display::Index); }
00265   // Return True if the table is in RGB mode
00266   Bool rgbMode() const { return (colorModel_ == Display::RGB); }
00267   // Return True if the table is in HSV mode
00268   Bool hsvMode() const { return (colorModel_ == Display::HSV); }
00269 
00270   // Return True if the colortable can be resized.
00271   Bool rigid() const { return rigid_; }
00272 
00273   // Return the color model for multichannel color
00274   Display::ColorModel colorModel() const { return colorModel_; }
00275   Bool readOnly()const{return readOnly_;}
00276   Bool decomposedIndex()const{return decomposedIndex_;}
00277   // Return the number of currently unallocated cells that can be allocated RW.
00278   uInt QueryColorsAvailable(const Bool contig)const;
00279   virtual uInt QueryHWColorsAvailable(const Bool contig)const;
00280   // Convert a virtual index to a physical pixel.
00281   Bool virtualToPhysical(const unsigned long vindex,
00282                          unsigned long &pindex)const;
00283   // Store an RGB value at index. For RGV visuals, only the virtual colormap
00284   // is updated.
00285   void storeColor(const uInt index,
00286                   const float r, const float g, const float b);
00287   // Convert a pixel to color components. If decomposed index (eg TC),
00288   // the pixel contains the color information. Otherwise, (eg. PseudoColor),
00289   // The information is looked up in the virtual colormap.
00290   void pixelToComponents(const uLong pixel, Float &r, Float &g, Float &b);
00291   // Return a GL capable visual that supports the colormodel or NULL.
00292   static XVisualInfo *getVisualInfo(::XDisplay *dpy,
00293                                     const Display::ColorModel colormodel);
00294   // Returns the color values for the index. (Inverse of installRGBColors()).
00295   void indexToRGB(const uInt index, float &r, float &g, float &b);
00296 private:
00297 
00298   // Return the log power 2 of n and return True if n is
00299   // a power of two.  Otherwise return false.
00300   Bool isPow2(uInt n, uInt & log2n);
00301 
00302   // (Multi-Channel)
00303   void setupColorCube(uLong n1, uLong n2, uLong n3,
00304                       uLong n1m, uLong n2m, uLong n3m);
00305   // (Multi-Channel)
00306   void setupStandardMapping(const XStandardColormap * mapInfo);
00307 
00308   Bool initVisual(XVisualInfo *vi=NULL);
00309   // A pointer to the XDisplay 
00310   ::XDisplay * display_;
00311   // A pointer the the X Screen
00312   Screen * screen_;
00313   // A pointer to the X Visual
00314   Visual * visual_;
00315   XVisualInfo *visualInfo_;
00316   // A pointer to the XColormap (X Hardware colormap)
00317   XColormap xcmap_;
00318 
00319   // (Valid Always) number of bits of depth
00320   uInt depth_;
00321   // (Valid Always) number of total colors available for RW.
00322   uInt nColors_;
00323   // (Valid only when implementation uses a PseudoColor or a
00324   // StaticColor visual).  Table of color indices available.
00325   uLong * colors_;      // converts pixel index into vcmap index. Always valid.
00326   uShort vcmapLength_;  // Length of virtual colormap.
00327                         // (& HW map if it exists)
00328   GLVColorTableEntry *vcmap_;
00329   // (Valid Always)
00330   // True if the table may not be resized, such as when a
00331   // standard XColormap is used.  Generally this is set to True
00332   // unless the visual is PseudoColor/StaticColor and the color
00333   // model is Display::Index.
00334   Bool rigid_;
00336   // True if the colormap is read only.
00337   Bool  readOnly_;
00338   // True if TrueColor or DirectColor.
00339   Bool  decomposedIndex_;
00340   void checkVisual();
00341   // Write an RGB value to hardware colormap at physical index.
00342   // (Called by storeColor()).
00343   virtual void storeHWColor(const uLong pindex,
00344                             const float r, const float g, const float b);
00345   // Shift counts, masks, and max values used to build pixels for
00346   // decomposed index colormaps.
00347   unsigned short red_shift_, green_shift_, blue_shift_;
00348   unsigned short red_max_, green_max_, blue_max_;
00349   unsigned long red_mask_, green_mask_, blue_mask_;
00350   // Convert from integer HSV components to RGB pixel components.
00351   void HSV2RGB(const uLong H, const uLong S, const uLong V,
00352                uLong &R, uLong &G, uLong &B);
00353   uInt HSV2Index(float h, float s, float v);
00354 
00356   // (Valid only for multi-channel color modes (RGB, HSV, etc))
00357   // If true, then the color cube's sides are powers of two,
00358   // making indexing possible with shift/add using the values of
00359   // <nBits1_, nBits2_, nBits3_>.  If not true, indexing
00360   // using <n1_,n2_,n3_> and multiplication is required. 
00361   Bool pow2Mapping_;
00362 
00363   // (Valid Always)
00364   // The colormodel that this GLPixelCanvasColorTable has been 
00365   // configured as.
00366   Display::ColorModel colorModel_;
00367 
00368   // (Valid only for multi-channel color modes (RGB, HSV, etc))
00369   // Represents the first cell used for the color cube.
00370   // baseColor_ is zero for PseudoColor/StaticColor implementations
00371   // because they use a table.
00372   uLong baseColor_;
00373 
00374   // (Valid only for multi-channel color modes (RGB, HSV, etc))
00375   // Specifies the color resolution for each side of the
00376   // color cube.
00377   // index = n1Mult_*R + n2Mult_*G + n3Mult_*B for RGB in
00378   // the range of <[0,n1_-1],[0,n2_-1],[0,n3_-1]>
00379   // <group>
00380   uInt n1_;
00381   uInt n2_;
00382   uInt n3_;
00383 
00384   uInt n1Mult_;
00385   uInt n2Mult_;
00386   uInt n3Mult_;
00387   // </group>
00388 
00389   // (Valid only for multi-channel color modes (RGB, HSV, etc))
00390   // and when pow2Mapping is true.
00391   // index = (R << n1Shift_) | (G << n2Shift_) | (B << n3Shift_)
00392   // for RGB the range of <[0,n1_-1],[0,n2_-1],[0,n3_-1]>
00393   // <group>
00394   uInt n1Shift_;
00395   uInt n2Shift_;
00396   uInt n3Shift_;
00397   // </group>
00398 };
00399 
00400 
00401 } //# NAMESPACE CASA - END
00402 #ifndef AIPS_NO_TEMPLATE_SRC
00403 #include <display/Display/GLPCColTblTemplates.tcc>
00404 #endif
00405 #endif