casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
PSPixelCanvasColorTable.h
Go to the documentation of this file.
00001 //# PSPixelCanvasColorTable.cc: PostScript version of PixelCanvasColorTable
00002 //# Copyright (C) 1999,2000
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_PSPIXELCANVASCOLORTABLE_H
00029 #define TRIALDISPLAY_PSPIXELCANVASCOLORTABLE_H
00030 
00031 
00032 
00033 
00034 #include <casa/aips.h>
00035 
00036 #include <casa/Arrays/Vector.h>
00037 #include <display/Display/DisplayEnums.h>
00038 #include <display/Display/PixelCanvasColorTable.h>
00039 #include <display/Display/PSDriver.h>
00040 
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 // <summary>
00045 // Implementation of PixelCanvasColorTable for PostScript device.
00046 // </summary>
00047 //
00048 // <prerequisite>
00049 // <li> <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00050 // <li> <linkto class="PSDriver">PSDriver</linkto>
00051 // </prerequisite>
00052 //
00053 // <etymology>
00054 // </etymology>
00055 //
00056 // <synopsis>
00057 // To create a PSPixelCanvasColorTable, just pass the constructor a pointer
00058 // to a
00059 // <linkto class="PSDriver">PSDriver</linkto> and, optionally,
00060 // supplying a color model. (The default is Index).
00061 //<note role=tip> Unlike the <em>X11PixelCanvasColorTable</em>,
00062 // PSPixelCanvasColorTable allows changing the color model on the fly.
00063 //</note>
00064 // PSPixelCanvasColorTable is not likely to be explicitly used by other
00065 // than Display Library developers, particularly those creating
00066 // "WorldCanvasApp"s. One exception is using PSPixelCanvasColorTable in non
00067 // Index mode. Since
00068 // <linkto class="PSWorldCanvasApp">PSWorldCanvasApp</linkto>
00069 //  creates its PSPixelCanvasColorTable in
00070 // Index mode, it will be necessary to get a pointer to the object and
00071 // explicitly change to different color modes.
00072 //<example>
00073 //<srcblock>
00074 // psapp = new PSWorldCanvasApp(psdriver);
00075 // wCanvas = psapp->worldCanvas();
00076 // pCanvas = (PSPixelCanvas *)wCanvas->pixelCanvas();
00077 // PSPixelCanvasColorTable *psctbl = pCanvas->PSpcctbl();
00078 // psctbl->setColorModel(Display::RGB);
00079 //</srcblock>
00080 // See Display/test/dMultichannelRaster.cc for an example.
00081 //</example>
00082 // </synopsis>
00083 //
00084 //<note role=tip> PostScript supports a 4096 entry color table for
00085 // indexed color. PSPixelCanvasColorTable logically breaks this into two
00086 // parts. One part is used for the changable colors. The other part is
00087 // reserved for read only colors. (Those allocated by name). The number
00088 // of read only colors is 512.
00089 //</note>
00090 //
00091 // <motivation>
00092 // </motivation>
00093 //
00094 // <todo>
00095 // </todo>
00096 //<use visibility=local>
00097 
00098 class PSPixelCanvasColorTable : public PixelCanvasColorTable
00099 {
00100 public:
00101 
00102         //# PostScript Level 2 definition allows 12 bits/component, we
00103         //# use 10 in RGB mode due to limitations in the DL spec.
00104         enum {  INDEXBPC = 12, RGBBPC=10, INDEXCOLORS = (1<<INDEXBPC),
00105                 RGBCOLORS = (1<<RGBBPC)};
00106         // The last NUMROCOLORS of the table are reserved for RO values.
00107 //#     NUMROCOLORS could be changed as long as enough RO slots remained.
00108         enum { NUMROCOLORS=512, NUMRWCOLORS=INDEXCOLORS-NUMROCOLORS};
00109         enum {  BMASK = 0xff, RGBMASK= (RGBCOLORS-1) ,
00110                 INDEXMASK = (INDEXCOLORS -1) };
00111         // Amount to shift components when mapping RGB.
00112         enum { RSHIFT=RGBBPC*2, GSHIFT=RGBBPC, BSHIFT=0};
00113   // <group>
00114   PSPixelCanvasColorTable(PSDriver *ps,
00115                           const Display::ColorModel = Display::Index);
00116   // </group>
00117   virtual ~PSPixelCanvasColorTable();
00118 
00119   // Resize the map if allowed.  Returns True if resize was accepted
00120   // <group>
00121   virtual Bool resize(uInt newSize);
00122   virtual Bool resize(uInt nReds, uInt nGreens, uInt nBlues);
00123   // </group>
00124 
00125   // Install colors into the color table.  Offset is zero-based.  Colors
00126   // are installed into the PixelCanvasColorTable until the Arrays run out
00127   // or until the end of the colortable is reached. Can be called in any
00128   // mode, but only affects graphics drawn in Index mode.
00129   // Values are clamped to [0.0,1.0].
00130 //<thrown><li> AipsError </thrown>
00131   virtual Bool installRGBColors(const Vector<Float> & r,
00132                                 const Vector<Float> & g, 
00133                                 const Vector<Float> & b, uInt offset = 0);
00134 
00135   // Return the number of RW colors in the colormap.
00136   virtual uInt nColors() const;
00137 
00138   // Return the number of colors per component.
00139   // For RGB/HSV, returns the number of colors/component supported by PostScript.
00140   // For Index, returns the number of colors/component for the lookup table.
00141   //  (Limited by D.L. spec).
00142   virtual void nColors(uInt &n1, uInt &n2, uInt &n3) const;
00143 
00144   // Maximum number of colors in color table.
00145   uInt maxColors()const;
00146   // Return the depth in bits of the colors.
00147   virtual uInt depth() const;
00148 
00149   // Return the number of colors that are still unallocated.
00150   virtual uInt nSpareColors() const;
00151 
00152   // map [0,N-1] into colorpixels, where N is the current colormap size
00153   // The values are returned as unsigned integers in their respective 
00154   // array.  
00155   //
00156   // <note role="Warning">uChar type doesn't have enough bits
00157   // to hold the pixel index. </note>
00158   // <note role="Warning">uChar and uShort don't have enough bits to
00159   // hold RGB or HSV values.</note>
00160   // <group>
00161   virtual void mapToColor(const Colormap * map, Array<uChar> & outArray, 
00162                   const Array<uChar> & inArray, Bool rangeCheck = True) const;
00163   virtual void mapToColor(const Colormap * map, Array<uShort> & outArray, 
00164                 const Array<uShort> & inArray, Bool rangeCheck = True) const;
00165   virtual void mapToColor(const Colormap * map, Array<uInt> & outArray, 
00166                   const Array<uInt> & inArray, Bool rangeCheck = True) const;
00167   virtual void mapToColor(const Colormap * map, Array<uLong> & outArray, 
00168                   const Array<uLong> & inArray, Bool rangeCheck = True) const;
00169   // </group>
00170 
00171   // Same as above except the matrix is operated on in place. Only unsigned
00172   // values make sense here.
00173   // <group>
00174   virtual void mapToColor(const Colormap * map, Array<uChar> & inOutArray, 
00175                   Bool rangeCheck = True) const;
00176   virtual void mapToColor(const Colormap * map, Array<uShort> & inOutArray, 
00177                   Bool rangeCheck = True) const;
00178   virtual void mapToColor(const Colormap * map, Array<uInt> & inOutArray, 
00179                   Bool rangeCheck = True) const;
00180   virtual void mapToColor(const Colormap * map, Array<uLong> & inOutArray, 
00181                   Bool rangeCheck = True) const;
00182   // </group>
00183 
00184   // (Multichannel Color)
00185   // Merge separate channel data into an output image.
00186   // This function maps floating values between 0 and 1
00187   // into a output image suitable for PixelCanvas::drawImage().
00188   // <group>
00189   virtual void mapToColor3(Array<uLong> & out,
00190                    const Array<Float> & chan1in,
00191                    const Array<Float> & chan2in,
00192                    const Array<Float> & chan3in);
00193   virtual void mapToColor3(Array<uLong> & out,
00194                    const Array<Double> & chan1in,
00195                    const Array<Double> & chan2in,
00196                    const Array<Double> & chan3in);
00197   // </group>
00198 
00199   // This one maps values between 0 and the integer
00200   // maximum value for each channel into a single
00201   // output image suitable for PixelCanvas::drawImage().
00202   // <group>
00203   virtual void mapToColor3(Array<uLong> & out,
00204                            const Array<uShort> & chan1in,
00205                            const Array<uShort> & chan2in,
00206                            const Array<uShort> & chan3in);
00207   virtual void mapToColor3(Array<uLong> & out,
00208                            const Array<uInt> & chan1in,
00209                            const Array<uInt> & chan2in,
00210                            const Array<uInt> & chan3in);
00211   // </group>
00212   
00213   // Convert from a packed array of RGB triples to an array of color values.
00214   // The output array needs to be 3 times as long as the input array.
00215   // Used by PSPixelCanvas to convert from D.L. RGB format to an array
00216   // the PostScript driver can use.
00217   void mapFromColor3(const Array<uLong> & inArray, 
00218                      Array<uShort> & outArray) const;
00219 
00220   // (Multichannel Color)
00221   // Transform arrays from the passed color model into
00222   // the colormodel of the PSPCCT.
00223   // Does nothing if colorModel is Display::Index.
00224   // It is assumed that input arrays are in the range of [0,1]
00225   virtual Bool colorSpaceMap(Display::ColorModel, 
00226                      const Array<Float> & chan1in, 
00227                      const Array<Float> & chan2in, 
00228                      const Array<Float> & chan3in, 
00229                      Array<Float> & chan1out, 
00230                      Array<Float> & chan2out, 
00231                      Array<Float> & chan3out);  
00232 
00233 
00234   // Return the color model for multichannel color
00235   Display::ColorModel colorModel() const;
00236   // Returns the current # of color components (1 for Indexed, 3 for RGB/HSV).
00237   uInt numComponents()const;
00238   // Changeable at any time.
00239   virtual void setColorModel(const Display::ColorModel);
00240   
00241   PSDriver *getPSDriver()const{return ps;}
00242 
00243 //#  ////////////////////////////////////////////////////////////////
00244 //                      X11 emulation routines
00245 //#  ////////////////////////////////////////////////////////////////
00246 //<srcblock>
00247   // Convert a colorname to a color triple. Returns True for success,
00248   // False if name can't be found. The color spec can also be in the form:
00249   //  "#xxxxxx"          A '#' character followed by exactly 6 hex digits.
00250   //                    (This form is considered obsolete and is not
00251   //                     completely implemented here).
00252   //  "rgb:<red>/<green>/<blue>"        Where <red>, <green> and <blue> are
00253   //                    Each 1 to 4 hex digits. Each value is divided
00254   //                    by 1.0/(2^n -1) where n is the # of hex chars in
00255   //                    the term. The result is 3 floating point numbers in
00256   //                    the range 0..1.
00257   // "rgbi:<red>/<green>/<blue>"        Where <red>, <green> and <blue> are
00258   //                                    floating point #s in the range 0..1.
00259 //</srcblock>
00260   // See <em>XParseColor</em> for more information.
00261 
00262 //<group>
00263   static Bool parseColor(const char *name,
00264                          float &red, float &green, float &blue);
00265   static Bool parseColor(const String &name,
00266                          float &red, float &green, float &blue);
00267 //</group>
00268 
00269   // Return contents of colormap at the given index. Returns False if
00270   // the index is out of range. The valid range of index is 0..4095.
00271   Bool queryColor(const int index, float &r, float &g, float &b);
00272   // Sets the contents of colormap at the given index. Returns False if
00273   // the index is out of range. The valid range of index is 0..nColors().
00274   // ( Can't change read only values).
00275   Bool storeColor(const int index,
00276                   const float r, const float g, const float b);
00277   // Allocate the color value in the color table. index is set to the
00278   // index allocated. Returns True for success, else False.
00279   Bool allocColor(const float r, const float g, const float b, int &index);
00280   Bool allocColor(const String &name, int &index);
00281   Bool allocColor(const char *name, int &index);
00282 
00283   // Whether to put tracing comments in the output. This may be helpful
00284   // when trying to decipher the PostScript file.
00285   Bool annotate()const{return annotate_;}
00286   void annotate(const Bool a){ annotate_ = a;}
00287 
00288   // print details of class to ostream
00289   friend ostream & operator << (ostream & os,
00290                                 const PSPixelCanvasColorTable & pcc);
00291 
00292   // Convert a packed pixel (from mapToColor3) to three color components.
00293   static inline void pixelToComponents( const uLong pixel,
00294                                         uShort &r, uShort &g, uShort &b)
00295   {     r =  (pixel >> RSHIFT) & RGBMASK;
00296         g = (pixel >> GSHIFT) & RGBMASK;
00297         b = (pixel >> BSHIFT) & RGBMASK;
00298   }
00299   // Pack RGB or HSV color components into a single unsigned long.
00300   static inline void componentsToPixel( const uShort r, const uShort g,
00301                                         uShort &b, uLong &pixel)
00302   {     pixel = ((r & RGBMASK) << RSHIFT) | ((g & RGBMASK) << GSHIFT)
00303                 | ((b & RGBMASK) << BSHIFT);
00304   }
00305 
00306 private:
00307   PSPixelCanvasColorTable();
00308   void pspcinit(PSDriver *ps, const Display::ColorModel);
00309   // Finds the index of a color triple coming 'close' to the RGB args.
00310   // Returns: True if a match is found, else False.
00311   // If lookROColor finds a match with a deallocated cell, it reallocates it.
00312   Bool lookupROColor(const float r, const float g, const float b, int &index);
00313   Bool lookupRWColor(const float r, const float g, const float b, int &index);
00314   int allocColor_(const float r, const float g, const float b, int &index);
00315 
00316   // Mark a RO color as unallocated.
00317   void deallocate(uLong index);
00318 
00319   // (Valid Always) number of total colors available. Changed by resize.
00320   uInt nColors_;
00321   // Number of bits/per component. Determined by colorModel_.
00322   uInt bpc_;
00323 
00324   // (Valid Always)
00325   // The colormodel that this PSPixelCanvasColorTable is currently
00326   // configured as.
00327   Display::ColorModel colorModel_;
00328 
00329         // PS
00330   PSDriver      *ps;
00331   // Copies of the color table.
00332   float red_[INDEXCOLORS],
00333         blue_[INDEXCOLORS],
00334         green_[INDEXCOLORS];
00335   // True if index has been allocated.
00336   Bool  allocated_[NUMROCOLORS];
00337   Bool  annotate_;
00338 };
00339 
00340 
00341 } //# NAMESPACE CASA - END
00342 
00343 #endif