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 public: 00100 00101 //# PostScript Level 2 definition allows 12 bits/component, we 00102 //# use 10 in RGB mode due to limitations in the DL spec. 00103 enum { INDEXBPC = 12, RGBBPC=10, INDEXCOLORS = (1<<INDEXBPC), 00104 RGBCOLORS = (1<<RGBBPC) 00105 }; 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 }; 00112 // Amount to shift components when mapping RGB. 00113 enum { RSHIFT=RGBBPC*2, GSHIFT=RGBBPC, BSHIFT=0}; 00114 // <group> 00115 PSPixelCanvasColorTable(PSDriver *ps, 00116 const Display::ColorModel = Display::Index); 00117 // </group> 00118 virtual ~PSPixelCanvasColorTable(); 00119 00120 // Resize the map if allowed. Returns True if resize was accepted 00121 // <group> 00122 virtual Bool resize(uInt newSize); 00123 virtual Bool resize(uInt nReds, uInt nGreens, uInt nBlues); 00124 // </group> 00125 00126 // Install colors into the color table. Offset is zero-based. Colors 00127 // are installed into the PixelCanvasColorTable until the Arrays run out 00128 // or until the end of the colortable is reached. Can be called in any 00129 // mode, but only affects graphics drawn in Index mode. 00130 // Values are clamped to [0.0,1.0]. 00131 //<thrown><li> AipsError </thrown> 00132 virtual Bool installRGBColors(const Vector<Float> & r, 00133 const Vector<Float> & g, 00134 const Vector<Float> & b, 00135 const Vector<Float> & alpha, 00136 uInt offset = 0); 00137 00138 // Return the number of RW colors in the colormap. 00139 virtual uInt nColors() const; 00140 00141 // Return the number of colors per component. 00142 // For RGB/HSV, returns the number of colors/component supported by PostScript. 00143 // For Index, returns the number of colors/component for the lookup table. 00144 // (Limited by D.L. spec). 00145 virtual void nColors(uInt &n1, uInt &n2, uInt &n3) const; 00146 00147 // Maximum number of colors in color table. 00148 uInt maxColors()const; 00149 // Return the depth in bits of the colors. 00150 virtual uInt depth() const; 00151 00152 // Return the number of colors that are still unallocated. 00153 virtual uInt nSpareColors() const; 00154 00155 // map [0,N-1] into colorpixels, where N is the current colormap size 00156 // The values are returned as unsigned integers in their respective 00157 // array. 00158 // 00159 // <note role="Warning">uChar type doesn't have enough bits 00160 // to hold the pixel index. </note> 00161 // <note role="Warning">uChar and uShort don't have enough bits to 00162 // hold RGB or HSV values.</note> 00163 // <group> 00164 virtual void mapToColor(const Colormap * map, Array<uChar> & outArray, 00165 const Array<uChar> & inArray, Bool rangeCheck = True) const; 00166 virtual void mapToColor(const Colormap * map, Array<uShort> & outArray, 00167 const Array<uShort> & inArray, Bool rangeCheck = True) const; 00168 virtual void mapToColor(const Colormap * map, Array<uInt> & outArray, 00169 const Array<uInt> & inArray, Bool rangeCheck = True) const; 00170 virtual void mapToColor(const Colormap * map, Array<uLong> & outArray, 00171 const Array<uLong> & inArray, Bool rangeCheck = True) const; 00172 // </group> 00173 00174 // Same as above except the matrix is operated on in place. Only unsigned 00175 // values make sense here. 00176 // <group> 00177 virtual void mapToColor(const Colormap * map, Array<uChar> & inOutArray, 00178 Bool rangeCheck = True) const; 00179 virtual void mapToColor(const Colormap * map, Array<uShort> & inOutArray, 00180 Bool rangeCheck = True) const; 00181 virtual void mapToColor(const Colormap * map, Array<uInt> & inOutArray, 00182 Bool rangeCheck = True) const; 00183 virtual void mapToColor(const Colormap * map, Array<uLong> & inOutArray, 00184 Bool rangeCheck = True) const; 00185 // </group> 00186 00187 // (Multichannel Color) 00188 // Merge separate channel data into an output image. 00189 // This function maps floating values between 0 and 1 00190 // into a output image suitable for PixelCanvas::drawImage(). 00191 // <group> 00192 virtual void mapToColor3(Array<uLong> & out, 00193 const Array<Float> & chan1in, 00194 const Array<Float> & chan2in, 00195 const Array<Float> & chan3in); 00196 virtual void mapToColor3(Array<uLong> & out, 00197 const Array<Double> & chan1in, 00198 const Array<Double> & chan2in, 00199 const Array<Double> & chan3in); 00200 // </group> 00201 00202 // This one maps values between 0 and the integer 00203 // maximum value for each channel into a single 00204 // output image suitable for PixelCanvas::drawImage(). 00205 // <group> 00206 virtual void mapToColor3(Array<uLong> & out, 00207 const Array<uShort> & chan1in, 00208 const Array<uShort> & chan2in, 00209 const Array<uShort> & chan3in); 00210 virtual void mapToColor3(Array<uLong> & out, 00211 const Array<uInt> & chan1in, 00212 const Array<uInt> & chan2in, 00213 const Array<uInt> & chan3in); 00214 // </group> 00215 00216 // Convert from a packed array of RGB triples to an array of color values. 00217 // The output array needs to be 3 times as long as the input array. 00218 // Used by PSPixelCanvas to convert from D.L. RGB format to an array 00219 // the PostScript driver can use. 00220 void mapFromColor3(const Array<uLong> & inArray, 00221 Array<uShort> & outArray) const; 00222 00223 // (Multichannel Color) 00224 // Transform arrays from the passed color model into 00225 // the colormodel of the PSPCCT. 00226 // Does nothing if colorModel is Display::Index. 00227 // It is assumed that input arrays are in the range of [0,1] 00228 virtual Bool colorSpaceMap(Display::ColorModel, 00229 const Array<Float> & chan1in, 00230 const Array<Float> & chan2in, 00231 const Array<Float> & chan3in, 00232 Array<Float> & chan1out, 00233 Array<Float> & chan2out, 00234 Array<Float> & chan3out); 00235 00236 00237 // Return the color model for multichannel color 00238 Display::ColorModel colorModel() const; 00239 // Returns the current # of color components (1 for Indexed, 3 for RGB/HSV). 00240 uInt numComponents()const; 00241 // Changeable at any time. 00242 virtual void setColorModel(const Display::ColorModel); 00243 00244 PSDriver *getPSDriver()const { 00245 return ps; 00246 } 00247 00248 //# //////////////////////////////////////////////////////////////// 00249 // X11 emulation routines 00250 //# //////////////////////////////////////////////////////////////// 00251 //<srcblock> 00252 // Convert a colorname to a color triple. Returns True for success, 00253 // False if name can't be found. The color spec can also be in the form: 00254 // "#xxxxxx" A '#' character followed by exactly 6 hex digits. 00255 // (This form is considered obsolete and is not 00256 // completely implemented here). 00257 // "rgb:<red>/<green>/<blue>" Where <red>, <green> and <blue> are 00258 // Each 1 to 4 hex digits. Each value is divided 00259 // by 1.0/(2^n -1) where n is the # of hex chars in 00260 // the term. The result is 3 floating point numbers in 00261 // the range 0..1. 00262 // "rgbi:<red>/<green>/<blue>" Where <red>, <green> and <blue> are 00263 // floating point #s in the range 0..1. 00264 //</srcblock> 00265 // See <em>XParseColor</em> for more information. 00266 00267 //<group> 00268 static Bool parseColor(const char *name, 00269 float &red, float &green, float &blue); 00270 static Bool parseColor(const String &name, 00271 float &red, float &green, float &blue); 00272 //</group> 00273 00274 // Return contents of colormap at the given index. Returns False if 00275 // the index is out of range. The valid range of index is 0..4095. 00276 Bool queryColor(const int index, float &r, float &g, float &b); 00277 // Sets the contents of colormap at the given index. Returns False if 00278 // the index is out of range. The valid range of index is 0..nColors(). 00279 // ( Can't change read only values). 00280 Bool storeColor(const int index, 00281 const float r, const float g, const float b); 00282 // Allocate the color value in the color table. index is set to the 00283 // index allocated. Returns True for success, else False. 00284 Bool allocColor(const float r, const float g, const float b, int &index); 00285 Bool allocColor(const String &name, int &index); 00286 Bool allocColor(const char *name, int &index); 00287 00288 // Whether to put tracing comments in the output. This may be helpful 00289 // when trying to decipher the PostScript file. 00290 Bool annotate()const { 00291 return annotate_; 00292 } 00293 void annotate(const Bool a) { 00294 annotate_ = a; 00295 } 00296 00297 // print details of class to ostream 00298 friend ostream & operator << (ostream & os, 00299 const PSPixelCanvasColorTable & pcc); 00300 00301 // Convert a packed pixel (from mapToColor3) to three color components. 00302 static inline void pixelToComponents( const uLong pixel, 00303 uShort &r, uShort &g, uShort &b) { 00304 r = (pixel >> RSHIFT) & RGBMASK; 00305 g = (pixel >> GSHIFT) & RGBMASK; 00306 b = (pixel >> BSHIFT) & RGBMASK; 00307 } 00308 // Pack RGB or HSV color components into a single unsigned long. 00309 static inline void componentsToPixel( const uShort r, const uShort g, 00310 uShort &b, uLong &pixel) { 00311 pixel = ((r & RGBMASK) << RSHIFT) | ((g & RGBMASK) << GSHIFT) 00312 | ((b & RGBMASK) << BSHIFT); 00313 } 00314 00315 private: 00316 PSPixelCanvasColorTable(); 00317 void pspcinit(PSDriver *ps, const Display::ColorModel); 00318 // Finds the index of a color triple coming 'close' to the RGB args. 00319 // Returns: True if a match is found, else False. 00320 // If lookROColor finds a match with a deallocated cell, it reallocates it. 00321 Bool lookupROColor(const float r, const float g, const float b, int &index); 00322 Bool lookupRWColor(const float r, const float g, const float b, int &index); 00323 int allocColor_(const float r, const float g, const float b, int &index); 00324 00325 // Mark a RO color as unallocated. 00326 void deallocate(uLong index); 00327 00328 // (Valid Always) number of total colors available. Changed by resize. 00329 uInt nColors_; 00330 // Number of bits/per component. Determined by colorModel_. 00331 uInt bpc_; 00332 00333 // (Valid Always) 00334 // The colormodel that this PSPixelCanvasColorTable is currently 00335 // configured as. 00336 Display::ColorModel colorModel_; 00337 00338 // PS 00339 PSDriver *ps; 00340 // Copies of the color table. 00341 float red_[INDEXCOLORS], 00342 blue_[INDEXCOLORS], 00343 green_[INDEXCOLORS]; 00344 // True if index has been allocated. 00345 Bool allocated_[NUMROCOLORS]; 00346 Bool annotate_; 00347 }; 00348 00349 00350 } //# NAMESPACE CASA - END 00351 00352 #endif