From 7cf4e84c41c6da2593618a130739ff6c48de2944 Mon Sep 17 00:00:00 2001 From: timlinux Date: Tue, 3 Feb 2004 07:00:18 +0000 Subject: [PATCH] More updates to api docs. Minor bugfix. git-svn-id: http://svn.osgeo.org/qgis/trunk@685 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/qgsrasterlayer.cpp | 19 ++- src/qgsrasterlayer.h | 292 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 270 insertions(+), 41 deletions(-) diff --git a/src/qgsrasterlayer.cpp b/src/qgsrasterlayer.cpp index 665efefcac1..ccea9bd513a 100644 --- a/src/qgsrasterlayer.cpp +++ b/src/qgsrasterlayer.cpp @@ -1,4 +1,4 @@ -/*************************************************************************** +/* ************************************************************************** qgsrasterlayer.cpp - description ------------------- begin : Sat Jun 22 2002 @@ -6,7 +6,7 @@ copyright : (C) 2003 by Tim Sutton, Steve Halasz and Gary E.Sherman email : tim at linfiniti.com ***************************************************************************/ -/*************************************************************************** +/* ************************************************************************** * * * 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 * @@ -98,11 +98,10 @@ QgsRasterLayer::QgsRasterLayer(QString path, QString baseName) if( gdalDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { - printf( "Origin = (%.6f,%.6f)\n", - adfGeoTransform[0], adfGeoTransform[3] ); - - printf( "Pixel Size = (%.6f,%.6f)\n", - adfGeoTransform[1], adfGeoTransform[5] ); +#ifdef DEBUG + printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); + printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); +#endif } double myXMaxDouble = adfGeoTransform[0] + gdalDataset->GetRasterXSize() * adfGeoTransform[1] + @@ -117,8 +116,8 @@ QgsRasterLayer::QgsRasterLayer(QString path, QString baseName) // // Set up the x and y dimensions of this raster layer // - rasterXDimInt = gdalDataset->GetRasterBand( 1 )->GetXSize(); - rasterYDimInt = gdalDataset->GetRasterBand( 1 )->GetYSize(); + rasterXDimInt = gdalDataset->GetRasterXSize(); + rasterYDimInt = gdalDataset->GetRasterYSize(); // // Determin the no data value // @@ -168,7 +167,7 @@ QgsRasterLayer::QgsRasterLayer(QString path, QString baseName) //for the third layer we cant be sure so.. if (gdalDataset->GetRasterCount() > 2) { - blueBandNameQString=getRasterBandName(2); // sensible default + blueBandNameQString=getRasterBandName(3); // sensible default } else { diff --git a/src/qgsrasterlayer.h b/src/qgsrasterlayer.h index 824a0150318..34d6f9a4319 100644 --- a/src/qgsrasterlayer.h +++ b/src/qgsrasterlayer.h @@ -45,15 +45,87 @@ * reason, qgsraster has a vector class member to store stats for each band. The * constructor initialises this vector on startup, but only populates the band name and * number fields. + * + * Note that where bands are of gdal 'undefined' type, their values may exceed the + * renderable range of 0-255. Because of this a linear scaling histogram stretch is + * applied to undefined layers to normalise the data into the 0-255 range. * * A qgsrasterlayer band can be referred to either by name or by number (base=1). It * should be noted that band names as stored in datafiles may not be uniqe, and * so the rasterlayer class appends the band number in brackets behind each band name. + * + * Sample useage of the QgsRasterLayer class: + * + * QString myFileNameQString = "/path/to/file"; + * QFileInfo myFileInfo(myFileNameQString); + * QString myBaseNameQString = myFileInfo.baseName(); + * QgsRasterLayer *myRasterLayer = new QgsRasterLayer(myFileNameQString, myBaseNameQString); + * myRasterLayer->initContextMenu(this); //prepare the right click pop up menu + * + * In order to automate redrawing of a raster layer, you should like it to a map canvas like this : + * + * QObject::connect( myRasterLayer, SIGNAL(repaintRequested()), mapCanvas, SLOT(refresh()) ); + * + * A raster layer can also export its legend as a pixmap: + * + * QPixmap myQPixmap = myRasterLayer->legendPixmap(); + * + * Once a layer has been created you can find out what type of layer it is (GRAY_OR_UNDEFINED, PALETTE or MULTIBAND): + * + * if (rasterLayer->getRasterLayerType()==QgsRasterLayer::MULTIBAND) + * { + * //do something + * } + * else if (rasterLayer->getRasterLayerType()==QgsRasterLayer::PALETTE) + * { + * //do something + * } + * else // QgsRasterLayer::GRAY_OR_UNDEFINED + * { + * //do something. + * } + * + * You can combine layer type detection with the setDrawingStyle method to override the default drawing style assigned + * when a layer is loaded.: + * + * if (rasterLayer->getRasterLayerType()==QgsRasterLayer::MULTIBAND) + * { + * myRasterLayer->setDrawingStyle(QgsRasterLayer::MULTI_BAND_SINGLE_BAND_PSEUDO_COLOR); + * } + * else if (rasterLayer->getRasterLayerType()==QgsRasterLayer::PALETTE) + * { + * myRasterLayer->setDrawingStyle(QgsRasterLayer::PALETTED_SINGLE_BAND_PSEUDO_COLOR); + * } + * else // QgsRasterLayer::GRAY_OR_UNDEFINED + * { + * myRasterLayer->setDrawingStyle(QgsRasterLayer::SINGLE_BAND_PSEUDO_COLOR); + * } + * + * Raster layers can also have an aribitary level of transparency defined, and have their + * colour palettes inverted using the setTransparency and setInvertHistogramFlag methods. + * + * Pseudocolour images can have their output adjusted to a given number of standard + * deviations using the setStdDevsToPlot method. + * + * The final area of functionality you may be interested in is band mapping. Band mapping + * allows you to choose arbitary band -> colour mappings and is applicable only to PALETTE + * and MULTIBAND rasters, There are four mappings that can be made : red, green, blue and gray. + * Mappings are non exclusive. That is a given band can be assigned to no, some or all + * colour mappings. The constructor sets sensible defaults for band mappings but these can be + * overridden at run time using the setRedBandName,setGreenBandName,setBlueBandName and setGrayBandName + * methods. */ + /* + * + * PROGRAMMERS NOTES: + * + * Please observe the following variable naming guidelines when editing this class: ---------------- -In my opinion, clarity of code is more important than brevity, so variables should be given clear, unambiguous names. Variables names should be written in mixed case, with a lowercase first letter. Each variable name should include a scope resolution indicator and a type indicator, in the form: +In my opinion, clarity of code is more important than brevity, so variables should be given clear, +unambiguous names. Variables names should be written in mixed case, with a lowercase first letter. +Each variable name should include a scope resolution indicator and a type indicator, in the form: [scope]+[name]+[type] @@ -76,99 +148,182 @@ class FooClass { } } -Using this scope resolution naming scheme makes the origin of each variable unambiguous and the code easy to read (especially by people who did not write it!). +Using this scope resolution naming scheme makes the origin of each variable unambiguous and the +code easy to read (especially by people who did not write it!). The [name] part of the variable should be short and descriptive, usually a noun. The [type] part of the variable should be the type class of the variable written out in full. + */ #ifndef QGSRASTERLAYER_H #define QGSRASTERLAYER_H +// +// Includes +// + #include - #include "qgspoint.h" #include "qgsmaplayer.h" #include "qgsrasterlayer.h" - - +// +// Forward declarations +// class QgsRect; class GDALDataset; class GDALRasterBand; +// +// Structs +// + +/** \brief The RasterBandStats struct is a container for statistics about a single + * raster band. + */ struct RasterBandStats { + /** \brief The name of the band that these stats belong to. */ QString bandName; - int bandNoInt; //the gdal band number (starts at 1) - bool statsGatheredFlag; //use so we can only gather stats once for a layer + /** \brief The gdal band number (starts at 1)*/ + int bandNoInt; + /** \brief A flag to indicate whether this RasterBandStats struct + * is completely populated */ + bool statsGatheredFlag; + /** \brief The minimum cell value in the raster band. NO_DATA values + * are ignored. This does not use the gdal GetMinimum function. */ double minValDouble; + /** \brief The maximum cell value in the raster band. NO_DATA values + * are ignored. This does not use the gdal GetMaximmum function. */ double maxValDouble; - //the distance between min & max + /** \brief The range is the distance between min & max. */ double rangeDouble; + /** \brief The mean cell value for the band. NO_DATA values are excluded. */ double meanDouble; - double sumSqrDevDouble; //used to calculate stddev + /** \brief The sum of the squares. Used to calculate standard deviation. */ + double sumSqrDevDouble; + /** \brief The standard deviation of the cell values. */ double stdDevDouble; + /** \brief The sum of all cells in the band. NO_DATA values are excluded. */ double sumDouble; + /** \brief The number of cells in the band. Equivalent to height x width. + * TODO: check if NO_DATA are excluded!*/ int elementCountInt; }; +/** \brief The RasterViewPort describes the area of the raster layer that will be + * rendered during a draw operation. + */ struct RasterViewPort { + /** \brief The offset from the left hand edge of the raster for the rectangle that will be drawn to screen. + * TODO Check this explanation is correc!*/ int rectXOffsetInt; + /** \brief The offset from the bottom edge of the raster for the rectangle that will be drawn to screen. + * TODO Check this explanation is correc!*/ int rectYOffsetInt; + /** \brief Lower left X dimension of clipped raster image in raster pixel space. + * RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only + * be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to + * whatever the screen coordinates are (e.g. a 600x800 display window) */ double clippedXMinDouble; + /** \brief Top Right X dimension of clipped raster image in raster pixel space. + * RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only + * be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to + * whatever the screen coordinates are (e.g. a 600x800 display window) */ double clippedXMaxDouble; + /** \brief Lower left Y dimension of clipped raster image in raster pixel space. + * RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only + * be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to + * whatever the screen coordinates are (e.g. a 600x800 display window) */ double clippedYMinDouble; + /** \brief Top Right X dimension of clipped raster image in raster pixel space. + * RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only + * be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to + * whatever the screen coordinates are (e.g. a 600x800 display window) */ double clippedYMaxDouble; + /** \brief Distance in pixels from clippedXMinDouble to clippedXMaxDouble. */ int clippedWidthInt; + /** \brief Distance in pixels from clippedYMinDouble to clippedYMaxDouble */ int clippedHeightInt; + /** \brief Coordinate (in geographic coordinate system) of top left corner of the part of the raster that + * is to be rendered.*/ QgsPoint topLeftPoint; + /** \brief Coordinate (in geographic coordinate system) of bottom right corner of the part of the raster that + * is to be rendered.*/ QgsPoint bottomRightPoint; + /** \brief Distance in map units from left edge to right edge for the part of the raster that + * is to be rendered.*/ int drawableAreaXDimInt; + /** \brief Distance in map units from bottom edge to top edge for the part of the raster that + * is to be rendered.*/ int drawableAreaYDimInt; }; +/** \brief A vector containing one RasterBandStats struct per raster band in this raster layer. + * Note that while very RasterBandStats element will have the name and number of its associated + * band populated, any additional stats are calculated on a need to know basis.*/ typedef QValueVector RasterStatsVector; /*! \class QgsRasterLayer - * \brief Raster layer class + * \brief This class provides qgis with the ability to render raster datasets + * onto the mapcanvas.. */ class QgsRasterLayer : public QgsMapLayer { Q_OBJECT public: - //! Constructor + /** \brief This is the constructor for the RasterLayer class. + * + * The main tasks carried out by the constructor are: + * + * -Populate the RasterStatsVector with initial values for each band. + * + * -Calculate the layer extents + * + * -Determine whether the layer is gray, paletted or multiband. + * + * -Assign sensible defaults for the red,green, blue and gray bands. + * + * - + * */ QgsRasterLayer(QString path = 0, QString baseName = 0); - //! Destructor + /** \brief The destuctor. */ ~QgsRasterLayer(); - //this is called when the properties for this layer needs to be modified - + /** \brief This method is called when the properties for this layer needs to be modified. + * invokes an instance of the QgsRasterLayerProperties dialog box.*/ void showLayerProperties(); - //this is called when the view on the rasterlayer needs to be refreshed + /** \brief This is called when the view on the rasterlayer needs to be refreshed (redrawn). */ void draw(QPainter * theQPainter, QgsRect * theViewExtent, QgsCoordinateTransform * theQgsCoordinateTransform); // // Accessors for image height and width // + /** \brief Accessor that returns the width of the (unclipped) raster */ const int getRasterXDim() {return rasterXDimInt;}; + /** \brief Accessor that returns the height of the (unclipped) raster */ const int getRasterYDim() {return rasterYDimInt;}; // // Accessor and mutator for no data double // + /** \brief Accessor that returns the NO_DATA entry for this raster. */ const double getNoDataValue() {return noDataValueDouble;}; + /** \brief Mutator that allows the NO_DATA entry for this raster to be overridden. */ void setNoDataValue(double theNoDataDouble) { noDataValueDouble=theNoDataDouble; return;}; // // Accessor and mutator for invertHistogramFlag // + /** \brief Accessor to find out whether the histogram should be inverted. */ bool getInvertHistogramFlag() { return invertHistogramFlag; } + /** \brief Mutator to alter the state of the invert histogram flag. */ void setInvertHistogramFlag(bool theFlag) { invertHistogramFlag=theFlag; @@ -176,142 +331,170 @@ public: // // Accessor and mutator for stdDevsToPlotDouble // + /** \brief Accessor to find out how many standard deviations are being plotted. */ double getStdDevsToPlot() { return stdDevsToPlotDouble; }; + /** \brief Mutator to alter the number of standard deviations that should be plotted. */ void setStdDevsToPlot(double theDouble) { stdDevsToPlotDouble = theDouble; }; - //get the number of bands in this layer + /** \brief Get the number of bands in this layer */ const unsigned int getBandCount() { return rasterStatsVector.size(); }; - // Get RasterBandStats for a band given its numer (read only) + /** \brief Get RasterBandStats for a band given its number (read only) */ const RasterBandStats getRasterBandStats(int); - /** Check whether a given band number has stats associated with it */ + /** \brief Check whether a given band number has stats associated with it */ const bool hasStats(int theBandNoInt); - // Overloaded method that also returns stats for a band, but uses the band color name - // Note this approach is not recommeneded because it is possibly for two gdal raster - // bands to have the same name! + /** \brief Overloaded method that also returns stats for a band, but uses the band colour name + * Note this approach is not recommeneded because it is possible for two gdal raster + * bands to have the same name! + */ const RasterBandStats getRasterBandStats(QString); - //get the number of a band given its name - //note this should be the rewritten name set up in the constructor, - //not the name retrieved directly from gdal! - //if no matching band is found zero will be returned! + /** \brief Get the number of a band given its name. Note this will be the rewritten name set + * up in the constructor, and will not necessarily be the same as the name retrieved directly from gdal! + * If no matching band is found zero will be returned! */ const int getRasterBandNumber (QString theBandNameQString); - // get the name of a band given its number + /** \brief Get the name of a band given its number. */ const QString getRasterBandName(int theBandNoInt); - // Find out whether a given band exists + /** \brief Find out whether a given band exists. */ bool hasBand(QString theBandName); - //accessor for transparency level + /** \brief accessor for transparency level. */ unsigned int getTransparency(); - //mutator for transparency - void setTransparency(unsigned int); //should be between 0 and 255 - // Accessor and mutator for red band name (allows alternate mappings e.g. map blue as red colour) + /** \brief Mutator for transparency level. Should be between 0 and 255 */ + void setTransparency(unsigned int); // + /** \brief Accessor for red band name (allows alternate mappings e.g. map blue as red colour). */ QString getRedBandName() { return redBandNameQString; }; + /** \brief Mutator for red band name (allows alternate mappings e.g. map blue as red colour). */ void setRedBandName(QString theBandNameQString); // Accessor and mutator for green band name + /** \brief */ QString getGreenBandName() { return greenBandNameQString; }; + /** \brief */ void setGreenBandName(QString theBandNameQString); // Accessor and mutator for blue band name + /** \brief */ QString getBlueBandName() { return blueBandNameQString; }; + /** \brief */ void setBlueBandName(QString theBandNameQString); // Accessor and mutator for gray band name + /** \brief */ QString getGrayBandName() { return grayBandNameQString; }; + /** \brief */ void setGrayBandName(QString theBandNameQString); // Accessor and mutator for showDebugOverlayFlag + /** \brief */ bool getShowDebugOverlayFlag() { return showDebugOverlayFlag; }; + /** \brief */ void setShowDebugOverlayFlag(bool theFlag) { showDebugOverlayFlag=theFlag; }; // Accessor and mutator for min and max red + /** \brief */ double getMinRedDouble() { return minRedDouble; }; + /** \brief */ void setMinRedDouble(double theDouble) { minRedDouble=theDouble; }; + /** \brief */ double getMaxRedDouble() { return maxRedDouble; }; + /** \brief */ void setMaxRedDouble(double theDouble) { maxRedDouble=theDouble; }; // Accessor and mutator for min and max green + /** \brief */ double getMinGreenDouble() { return minGreenDouble; }; + /** \brief */ void setMinGreenDouble(double theDouble) { minGreenDouble=theDouble; }; + /** \brief */ double getMaxGreenDouble() { return maxGreenDouble; }; + /** \brief */ void setMaxGreenDouble(double theDouble) { maxGreenDouble=theDouble; }; // Accessor and mutator for min and max red + /** \brief */ double getMinBlueDouble() { return minBlueDouble; }; + /** \brief */ void setMinBlueDouble(double theDouble) { minBlueDouble=theDouble; }; + /** \brief */ double getMaxBlueDouble() { return maxBlueDouble; }; + /** \brief */ void setMaxBlueDouble(double theDouble) { maxBlueDouble=theDouble; }; // Accessor and mutator for min and max red + /** \brief */ double getMinGrayDouble() { return minGrayDouble; }; + /** \brief */ void setMinGrayDouble(double theDouble) { minGrayDouble=theDouble; }; + /** \brief */ double getMaxGrayDouble() { return maxGrayDouble; }; + /** \brief */ void setMaxGrayDouble(double theDouble) { maxGrayDouble=theDouble; }; //this enumerator describes the types of scaling algorithms that can be used + /** \brief */ enum COLOR_SCALING_ALGORITHM { STRETCH_TO_MINMAX, //linear histogram stretch @@ -319,15 +502,18 @@ public: CLIP_TO_MINMAX } colorScalingAlgorithm; //Accessor and mutator for the color scaling algorithm + /** \brief */ COLOR_SCALING_ALGORITHM getColorScalingAlgorithm() { return colorScalingAlgorithm; }; + /** \brief */ void setColorScalingAlgorithm(COLOR_SCALING_ALGORITHM theAlgorithm) { colorScalingAlgorithm=theAlgorithm; }; //this enumerator describes the different kinds of drawing we can do + /** \brief */ enum DRAWING_STYLE { SINGLE_BAND_GRAY, // a "Gray" or "Undefined" layer drawn as a range of gray colors @@ -340,12 +526,17 @@ public: MULTI_BAND_COLOR //a layer containing 2 or more bands, mapped to the three RGBcolors. In the case of a multiband with only two bands, one band will have to be mapped to more than one color } drawingStyle; //accessor and mutator for drawins style + /** \brief */ DRAWING_STYLE getDrawingStyle() {return drawingStyle;}; + /** \brief */ QString getDrawingStyleAsQString(); + /** \brief */ void setDrawingStyle(DRAWING_STYLE theDrawingStyle) {drawingStyle=theDrawingStyle;}; //overloaded version of the above function for convenience when restoring from xml + /** \brief */ void setDrawingStyle(QString theDrawingStyleQString); //this enumerator describes the type of raster layer + /** \brief */ enum RASTER_LAYER_TYPE { GRAY_OR_UNDEFINED, @@ -353,18 +544,26 @@ public: MULTIBAND } rasterLayerType; //accessor and mutator for raster layer type + /** \brief */ RASTER_LAYER_TYPE getRasterLayerType() { return rasterLayerType; }; + /** \brief */ void setRasterLayerType( RASTER_LAYER_TYPE theRasterLayerType ) { rasterLayerType=theRasterLayerType; }; //get a legend image for this layer + /** \brief */ QPixmap getLegendQPixmap(); + /** \brief */ QPixmap getLegendQPixmap(bool); //similar to above but returns a pointer. Implemented for qgsmaplayer interface + /** \brief */ QPixmap * legendPixmap(); // Initialise the right click popup menu + /** \brief */ void initContextMenu(QgisApp *); /** Accessor for the superclass popmenu var - implements pure virtual fn*/ + /** \brief */ QPopupMenu *contextMenu(); // emit a signal asking for a repaint + /** \brief */ void triggerRepaint(); @@ -373,80 +572,111 @@ private: // // Private methods // + /** \brief */ void showDebugOverlay(QPainter * theQPainter, RasterViewPort * theRasterViewPort); + /** \brief */ void drawSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt); + /** \brief */ void drawSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt); + /** \brief */ void drawPalettedSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt, QString theColorQString); + /** \brief */ void drawPalettedSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt, QString theColorQString); + /** \brief */ void drawPalettedMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt); + /** \brief */ void drawMultiBandSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt); + /** \brief */ void drawMultiBandSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort, int theBandNoInt); + /** \brief */ void drawMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort); // // Private member vars // + /** \brief */ int rasterXDimInt; + /** \brief */ int rasterYDimInt; + /** \brief */ double noDataValueDouble; //flag to indicate whether debug infor overlay should be rendered onto the raster + /** \brief */ bool showDebugOverlayFlag; + /** \brief */ GDALDataset * gdalDataset; // values for mapping pixel to world coordinates + /** \brief */ double adfGeoTransform[6]; // flag indicating whether the histogram should be inverted or not + /** \brief */ bool invertHistogramFlag; // Number of stddev to plot (0) to ignore + /** \brief */ double stdDevsToPlotDouble; // a collection of stats - one for each band in the layer // the typedef for this is defined above before class declaration + /** \brief */ RasterStatsVector rasterStatsVector; // transparency for this layer should be 0-255 + /** \brief */ unsigned int transparencyLevelInt; //the band to be associated with the color red - usually 1 + /** \brief */ QString redBandNameQString; //the band to be associated with the color green - usually 2 + /** \brief */ QString greenBandNameQString; //the band to be associated with the color blue - usually 3 + /** \brief */ QString blueBandNameQString; //the band to be associated with the grayscale only ouput - usually 1 + /** \brief */ QString grayBandNameQString; // minimum red value - used in scaling procedure + /** \brief */ double minRedDouble; // maximum red value - used in scaling procedure + /** \brief */ double maxRedDouble; // minimum green value - used in scaling procedure + /** \brief */ double minGreenDouble; // maximum green value - used in scaling procedure + /** \brief */ double maxGreenDouble; // minimum blue value - used in scaling procedure + /** \brief */ double minBlueDouble; // maximum blue value - used in scaling procedure + /** \brief */ double maxBlueDouble; // minimum gray value - used in scaling procedure + /** \brief */ double minGrayDouble; // maximum gray value - used in scaling procedure + /** \brief */ double maxGrayDouble; };