1 //******************************************************************* 2 // Copyright (C) 2002 ImageLinks Inc. 3 // 4 // License: MIT 5 // 6 // See LICENSE.txt file in the top level directory for more details. 7 // 8 // Author: David Burken 9 // 10 // Description: 11 // 12 // Class to scan pixels and flip target dn pixel value to new dn pixel value. 13 // This was written to fix partial null pixels. 14 // 15 //************************************************************************* 16 // $Id: ossimPixelFlipper.h 19728 2011-06-06 21:31:17Z dburken $ 17 #ifndef ossimPixelFlipper_HEADER 18 #define ossimPixelFlipper_HEADER 19 20 #include <ossim/imaging/ossimImageSourceFilter.h> 21 #include <ossim/base/ossimPolygon.h> 22 #include <mutex> 23 24 /** 25 * Class to scan pixels and flip target dn value to a replacement dn 26 * value. 27 * 28 * This was written to fix problems with null pixels, i.e. an image has a 29 * digital number(dn) of 255 for null and it is desired to use a dn of 0 as 30 * a null. This can really be used to flip any pixel value to another. 31 * 32 * @note This filter currently works on the input tile directly and does 33 * not copy the data. 34 * 35 * @see theReplacementMode data member documentation for more info. 36 */ 37 class OSSIM_DLL ossimPixelFlipper : public ossimImageSourceFilter 38 { 39 public: 40 static const char PF_TARGET_VALUE_KW[]; 41 static const char PF_TARGET_RANGE_KW[]; 42 static const char PF_REPLACEMENT_VALUE_KW[]; 43 static const char PF_REPLACEMENT_MODE_KW[]; 44 static const char PF_CLAMP_VALUE_KW[]; 45 static const char PF_CLAMP_VALUE_LO_KW[]; 46 static const char PF_CLAMP_VALUE_HI_KW[]; 47 static const char PF_CLIP_MODE_KW[]; 48 49 /** 50 * Target Replacement Mode: 51 * 52 * Examples given for 3-band pixel values as (R, G, B) with target = 0, and replacement = 1 53 54 * If mode is REPLACE_BAND_IF_TARGET (default): 55 * Any pixel band with value of target will be replaced. 56 * (0, 0, 0) becomes (1, 1, 1) 57 * (0, 3, 2) becomes (1, 3, 2) 58 * 59 * If mode is REPLACE_BAND_IF_PARTIAL_TARGET: 60 * A band with target value will be replaced only if at least one other band in the pixel does 61 * not have the target. 62 * (0, 0, 0) remains (0, 0, 0) 63 * (0, 3, 2) becomes (1, 3, 2) 64 * 65 * If mode is REPLACE_ALL_BANDS_IF_PARTIAL_TARGET: 66 * All bands of the pixel will be replaced if any but not all bands in the pixel have the 67 * target value. 68 * (0, 0, 0) remains (0, 0, 0) 69 * (0, 3, 2) becomes (1, 1, 1) 70 * 71 * If mode is REPLACE_ONLY_FULL_TARGETS: 72 * All bands in the pixel will be replaced only if they all have the target. 73 * (0, 0, 0) becomes (1, 1, 1) 74 * (0, 3, 2) remains (0, 3, 2) 75 * 76 * If mode is REPLACE_ALL_BANDS_IF_ANY_TARGET: 77 * All bands in the pixel will be replaced if even one band has the target. 78 * (0, 0, 0) becomes (1, 1, 1) 79 * (0, 3, 2) remains (1, 1, 1) 80 */ 81 enum ReplacementMode 82 { 83 REPLACE_BAND_IF_TARGET = 0, 84 REPLACE_BAND_IF_PARTIAL_TARGET = 1, 85 REPLACE_ALL_BANDS_IF_PARTIAL_TARGET = 2, 86 REPLACE_ONLY_FULL_TARGETS = 3, 87 REPLACE_ALL_BANDS_IF_ANY_TARGET = 4, 88 }; 89 90 /** 91 * When either a lo and/or hi clamp value is set, the clamping mode will be enabled accordingly 92 * and override any target replacement defined 93 */ 94 enum ClampingMode 95 { 96 DISABLED = 0, 97 CLAMPING_LO = 1, 98 CLAMPING_HI = 2, 99 CLAMPING_LO_AND_HI = 3, 100 }; 101 102 enum ClipMode 103 { 104 NONE = 0, 105 BOUNDING_RECT = 1, 106 VALID_VERTICES = 2 107 }; 108 109 /** default constructor */ 110 ossimPixelFlipper(ossimObject* owner=NULL); 111 112 113 /** @return "Pixel flipper" as an ossimString. */ 114 virtual ossimString getShortName()const; 115 116 /** Initializes the state of the object from theInputConnection. */ 117 virtual void initialize(); 118 119 /** 120 * @param tile_rect Rectangle to fill tile with. 121 * 122 * @param resLevel Reduced resolution level to grab from. 123 * 124 * @return ossimRefPtr<ossimImageData> This is tile that was filled with 125 * tile_rect. 126 * 127 * @note Callers should check the ossimRefPtr::valid method. 128 * The internal pointer of the ossimRefPtr<ossimImageData> can be 129 * null if the tile_rect did not intersect the input connection's 130 * bounding rectangle. 131 */ 132 virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect, 133 ossim_uint32 resLevel=0); 134 135 virtual bool saveState(ossimKeywordlist& kwl, 136 const char* prefix=0)const; 137 138 /** 139 * Method to the load (recreate) the state of an object from a keyword 140 * list. Return true if ok or false on error. 141 */ 142 virtual bool loadState(const ossimKeywordlist& kwl, 143 const char* prefix=0); 144 145 virtual ossimScalarType getOutputScalarType() const; 146 virtual ossim_float64 getMaxPixelValue (ossim_uint32 band = 0 ) const; 147 virtual ossim_float64 getMinPixelValue (ossim_uint32 band = 0 ) const; 148 149 virtual std::ostream& print(std::ostream& out) const; 150 151 /** 152 * @param target_value This is the value to flip. 153 * @note If clamping is specified, it will take precedence over any target value (or range) test 154 */ 155 void setTargetValue(ossim_float64 target_value); 156 157 /** 158 * Instead of a single value for a target, this method allows for specifying a range of values 159 * to flip to the replacement. The replacement mode is still referenced. 160 * @param This is the value to flip. 161 * @note If clamping is specified, it will take precedence over any target range test. 162 */ 163 void setTargetRange(ossim_float64 target_min, ossim_float64 target_max); 164 165 /** 166 * @param replacement_value This is the value to flip target to. 167 * @note If clamping is specified, it will take precedence over any target replacement. 168 */ 169 void setReplacementValue(ossim_float64 replacement_value); 170 171 /** 172 * @param clamp_value If set all pixel values above this range will (or below if clamp_max_value 173 * = false) be clamped to clamp_value. Must be less than max pixel (or greater than the min 174 * pixel) value of the input and cannot be null. 175 * @note If any clamp limit is defined, it will take precedence over any target value (or range) 176 * replacement. The replacement mode is referenced when deciding whether a pixel should be 177 * clamped or left alone. 178 */ 179 void setClampValue(ossim_float64 clamp_value, bool is_high_clamp_value=true); 180 void setClampValues(ossim_float64 clamp_value_lo, ossim_float64 clamp_value_hi); 181 182 /** @see enum ReplacementMode */ 183 void setReplacementMode(ossimPixelFlipper::ReplacementMode mode); 184 185 /** Accepts a string that must match the enumerator's label (can be lower case) and sets the 186 * replacement mode accordingly. If the string is not understood, the mode remains unchanged and 187 * FALSE is returned. */ 188 bool setReplacementMode(const ossimString& modeString); 189 190 /** 191 * Clipping here refers to bounding rect or valid polygon (spacial) clipping, where all pixels 192 * outside the valid area are mapped to the replacement value. 193 */ 194 void setClipMode(const ossimString& modeString); 195 void setClipMode(ClipMode mode); 196 197 //ossim_float64 getTargetValue() const; 198 ossim_float64 getReplacementValue() const; 199 //ossim_float64 getClampValue() const; 200 ossimPixelFlipper::ReplacementMode getReplacementMode() const; 201 ossimString getReplacementModeString() const; 202 ossimString getClipModeString() const; 203 ClipMode getClipMode() const; 204 205 virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const; 206 virtual void setProperty(ossimRefPtr<ossimProperty> property); 207 virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const; 208 209 210 protected: 211 /** destructor */ 212 virtual ~ossimPixelFlipper(); 213 //! This object can be used outside of an image chain for offline processing of existing tile. 214 template <class T> 215 void flipPixels(T dummy, ossimImageData *inpuTile, ossim_uint32 resLevel); 216 217 template <class T> 218 void clipTile(T dummy, 219 ossimImageData *inpuTile, 220 ossim_uint32 resLevel); 221 222 /** 223 * Verifies pixel is in range. 224 * @return Returns true if in range else false. 225 */ 226 bool inRange(ossim_float64 value) const; 227 228 void allocateClipTileBuffer(ossimRefPtr<ossimImageData> inputImage); 229 230 /** The value range to replace. For a single value replacement, both Lo and Hi are equal. Any 231 * pixel within this range will be remapped to the replacement value */ 232 ossim_float64 theTargetValueLo; 233 ossim_float64 theTargetValueHi; 234 235 /** When target values are defined, this is the value the pixel will assume if the pixel falls 236 * within the target range (according to the rules for replacement mode) */ 237 ossim_float64 theReplacementValue; 238 ReplacementMode theReplacementMode; //!< See documentation for ReplacementMode enum above 239 240 /** The range of desired pixel values. Any pixels outside this range are set to the corresponding 241 * clamp value. Note that theReplacementValue is not referenced when clamping. */ 242 ossim_float64 theClampValueLo; 243 ossim_float64 theClampValueHi; 244 ClampingMode theClampingMode; 245 246 /** 247 * Border Clip mode 248 * 249 * This will flip to nulls any pixel value outside the specified mode. 250 * 251 * Valid modes are: 252 * 253 * none 254 * bounding_rect 255 * valid_vertices 256 * 257 * if the mode is "none" then nothing is done. 258 * if the mode is "bounding_rect" then the bounding rect for the requested rlevel 259 * is used and every pixel outside that 260 */ 261 ClipMode theClipMode; 262 263 /** For lock and unlock. */ 264 mutable std::recursive_mutex theMutex; 265 266 mutable std::vector<ossimPolygon> theValidVertices; 267 mutable std::vector<ossimIrect> theBoundingRects; 268 269 ossimRefPtr<ossimImageData> theClipTileBuffer; 270 271 TYPE_DATA 272 }; 273 274 275 #endif 276