Changeset 19441
- Timestamp:
- Sep 9, 2008, 2:22:19 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/config/pmConfigMask.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/config/pmConfigMask.c
r19155 r19441 9 9 #include "pmConfigMask.h" 10 10 11 12 psMaskType pmConfigMaskGet(const char *masks, const pmConfig *config) 13 { 14 psAssert(config, "Require configuration"); 15 PS_ASSERT_STRING_NON_EMPTY(masks, 0); 16 17 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 18 if (!recipe) { 19 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 20 return 0; 21 } 22 11 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 12 // Private functions 13 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 14 15 static psMaskType maskGet(const psMetadata *source, // Source of masks 16 const char *masks // Mask values to get 17 ) 18 { 23 19 psMaskType mask = 0; // Mask value, to return 24 20 … … 27 23 const char *name = names->data[i]; // Symbolic name of interest 28 24 bool mdok; // Status of MD lookup 29 psMaskType value = psMetadataLookupU8(&mdok, recipe, name);25 psMaskType value = psMetadataLookupU8(&mdok, source, name); 30 26 if (!mdok) { 31 psError(PS_ERR_BAD_PARAMETER_VALUE, false, 32 "Unable to find mask value for %s in MASK recipe", name); 27 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find mask value for %s", name); 33 28 psFree(names); 34 29 return 0; … … 41 36 } 42 37 43 bool pmConfigMaskSet(const pmConfig *config, const char *maskName, psMaskType maskValue) 44 { 45 psAssert(config, "Require configuration"); 46 PS_ASSERT_STRING_NON_EMPTY(maskName, false); 47 48 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 49 if (!recipe) { 50 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 51 return false; 52 } 53 54 psMetadataAddU8 (recipe, PS_LIST_TAIL, maskName, PS_META_REPLACE, "user-defined mask", maskValue); 55 56 return true; 57 } 58 59 // replace the named masks in the recipe with values in the header: 60 // replace only the names in the header in the recipe 61 bool pmConfigMaskReadHeader(pmConfig *config, const psMetadata *header) 62 { 63 PS_ASSERT_PTR_NON_NULL(config, false); 64 PS_ASSERT_METADATA_NON_NULL(header, false); 65 66 bool status = false; 67 68 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 69 if (!recipe) { 70 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 71 return false; 72 } 73 74 // MASK.VALUE and MARK.VALUE aren't usually set in the recipe, but may be set in the header: create fake 75 // versions so that it won't complain later 76 if (!psMetadataLookup(recipe, "MASK.VALUE")) { 77 psMetadataAddU8(recipe, PS_LIST_TAIL, "MASK.VALUE", 0, "Bits to mask", 0); 78 } 79 if (!psMetadataLookup(recipe, "MARK.VALUE")) { 80 psMetadataAddU8(recipe, PS_LIST_TAIL, "MARK.VALUE", 0, "Bits for marking", 0); 81 } 82 83 int nMask = psMetadataLookupS32(&status, header, "MSKNUM"); 84 if (!status) { 85 if (psMetadataLookupBool(&status, config->camera, "MASK.FORCE")) { 86 psWarning("No mask values in header. Assuming MASKS recipe is accurate because of MASK.FORCE"); 87 return true; 88 } 89 psError(PS_ERR_UNKNOWN, true, "Unable to find MSKNUM in header."); 90 return false; 91 } 92 93 char namekey[80]; // Keyword name for symbolic name of mask entry 94 char valuekey[80]; // Keyword name for value of mask entry 95 for (int i = 0; i < nMask; i++) { 96 snprintf(namekey, 64, "MSKNAM%02d", i); 97 snprintf(valuekey, 64, "MSKVAL%02d", i); 98 99 char *name = psMetadataLookupStr(&status, header, namekey); 100 if (!status || !name) { 101 psWarning("Unable to find header keyword %s when parsing mask", namekey); 102 continue; 103 } 104 psU8 bit = psMetadataLookupU8(&status, header, valuekey); 105 if (!status) { 106 psWarning("Unable to find header keyword %s when parsing mask", namekey); 107 continue; 108 } 109 110 // XXX validate that bit is a 2^n value? 111 112 psString nameAlready = NULL; // Name of key with ".ALREADY" added 113 psStringAppend(&nameAlready, "%s.ALREADY", name); 114 bool already = psMetadataLookupBool(&status, recipe, nameAlready); // Already read this one? 115 116 psMetadataItem *item = psMetadataLookup(recipe, name); // Item in recipe with current value 117 if (item && item->type != PS_TYPE_MASK) { 118 psWarning("Mask recipe entry is not of a mask type (%x)", item->type); 119 item->type = PS_TYPE_MASK; 120 } 121 122 if (already) { 123 if (item && item->data.U8 != bit) { 124 psWarning("New mask recipe entry doesn't match previously loaded entry: %x vs %x", 125 bit, item->data.U8); 38 // maskSetValues examine named mask values and set the bits for maskValue and markValue. 39 // Ensures that the below-named bad mask values are set, and calculates the mask value to catch them all 40 // Ensure that the below-named other mask values are set (to 0x00 if necessary) 41 42 // List of mask names for "bad" (i.e., mask me please) pixels 43 static const char *badMaskNames[] = { "DETECTOR", // Something is wrong with the detector 44 "DARK", // Pixel doesn't dark-subtract properly 45 "FLAT", // Pixel doesn't flat-field properly 46 "BLANK", // Pixel doesn't contain valid data 47 "RANGE",// Pixel is out-of-range of linearity 48 "SAT", // Pixel is saturated 49 "LOW", // Pixel is low 50 "CONV", // Pixel is bad after convolution with a bad pixel 51 "CR", // Pixel contains a cosmic ray 52 "GHOST",// Pixel contains an optical ghost 53 NULL // End marker 54 }; 55 // Fallback names in case a bad mask name is not defined 56 static const char *fallbackMaskNames[] = { NULL, // DETECTOR 57 "DETECTOR", // DARK 58 "DETECTOR", // FLAT 59 "DETECTOR", // BLANK 60 NULL, // RANGE 61 "RANGE", // SAT 62 "RANGE", // LOW 63 NULL, // CONV 64 NULL, // CR 65 NULL, // GHOST 66 }; 67 // Default values in case a bad mask name and its fallback is not defined 68 static const psMaskType defaultMask[] = { 0x00, // DETECTOR 69 0x00, // DARK 70 0x01, // FLAT 71 0x01, // BLANK 72 0x00, // RANGE 73 0x01, // SAT 74 0x01, // LOW 75 0x01, // CONV 76 0x00, // CR 77 0x00 // GHOST 78 }; 79 // Other mask names to ensure exist; these shouldn't be combined in the MASK.VALUE 80 static const char *otherMaskNames[] = { "POOR", // Pixel is poor after convolution with a bad pixel 81 NULL // End marker 82 }; 83 84 static bool maskSetValues(psMaskType *outMaskValue, // Value of MASK.VALUE, returned 85 psMaskType *outMarkValue, // Value of MARK.VALUE, returned 86 psMetadata *source // Source of mask bits 87 ) 88 { 89 PS_ASSERT_METADATA_NON_NULL(source, false); 90 91 // Ensure all the bad mask names exist, and set the value to catch all bad pixels 92 psMaskType maskValue = 0; // Value to mask to catch all the bad pixels 93 for (int i = 0; badMaskNames[i]; i++) { 94 const char *name = badMaskNames[i]; // Name for mask 95 const char *fallback = fallbackMaskNames[i]; // Fallback for mask 96 97 bool mdok; // Status of MD lookup 98 psMaskType value = psMetadataLookupU8(&mdok, source, name); // Value of mask 99 if (!value) { 100 if (fallback) { 101 value = psMetadataLookupU8(&mdok, source, fallback); 126 102 } 103 if (!value) { 104 value = defaultMask[i]; 105 } 106 psMetadataAddU8(source, PS_LIST_TAIL, name, PS_META_REPLACE, NULL, value); 107 } 108 maskValue |= value; 109 } 110 111 // Ensure all the other mask names exist 112 for (int i = 0; otherMaskNames[i]; i++) { 113 const char *name = otherMaskNames[i]; // Name for mask 114 bool mdok; // Status of MD lookup 115 psMaskType value = psMetadataLookupU8(&mdok, source, name); // Value of mask 116 if (!value) { 117 psMetadataAddU8(source, PS_LIST_TAIL, name, PS_META_REPLACE, NULL, 0x00); 118 } 119 } 120 121 // search for an unset bit to use for MARK: 122 psMaskType markValue = 0x80; 123 124 int nBits = sizeof(psMaskType) * 8; 125 for (int i = 0; !markValue && (i < nBits); i++) { 126 if (maskValue & markValue) { 127 markValue >>= 1; 127 128 } else { 128 psMetadataAddBool(recipe, PS_LIST_TAIL, nameAlready, 0, "Already read this mask value", true); 129 } 130 131 if (!item) { 132 psWarning("Mask recipe entry %s not in recipe\n", name); 133 psMetadataAddU8(recipe, PS_LIST_TAIL, name, 0, "Bitmask bit value", bit); 134 } else { 135 item->data.U8 = bit; 136 } 137 138 psFree(nameAlready); 139 } 140 129 markValue = markValue; 130 } 131 } 132 if (!markValue) { 133 psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!"); 134 return false; 135 } 136 137 // update the list with the results 138 psMetadataAddU8(source, PS_LIST_TAIL, "MASK.VALUE", PS_META_REPLACE, NULL, maskValue); 139 psMetadataAddU8(source, PS_LIST_TAIL, "MARK.VALUE", PS_META_REPLACE, NULL, markValue); 140 141 if (outMaskValue) { 142 *outMaskValue = maskValue; 143 } 144 if (outMarkValue) { 145 *outMarkValue = markValue; 146 } 141 147 142 148 return true; … … 162 168 } 163 169 164 165 // write the named mask bits to the header 166 bool pmConfigMaskWriteHeader(const pmConfig *config, psMetadata *header) 167 { 170 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 171 // FPA version of mask functions. These are not ready to go yet. 172 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 173 174 #if 0 175 bool pmFPAMaskSetValues(psMaskType *outMaskValue, psMaskType *outMarkValue, pmFPA *fpa) 176 { 177 PS_ASSERT_PTR_NON_NULL(fpa, false); 178 179 return maskSetValues(outMaskValue, outMarkValue, fpa->masks); 180 } 181 182 psMaskType pmFPAMaskGet(const pmFPA *fpa, const char *masks, const pmConfig *config) 183 { 184 PS_ASSERT_PTR_NON_NULL(fpa, 0); 185 PS_ASSERT_STRING_NON_EMPTY(masks, 0); 186 PS_ASSERT_PTR_NON_NULL(config, 0); 187 188 if (fpa->masks) { 189 return maskGet(fpa->masks, masks); 190 } 191 return pmConfigMaskGet(masks, config); 192 } 193 194 bool pmFPAMaskSet(pmFPA *fpa, const char *maskName, psMaskType maskValue) 195 { 196 PS_ASSERT_PTR_NON_NULL(fpa, 0); 197 PS_ASSERT_STRING_NON_EMPTY(maskName, false); 198 199 if (!fpa->masks) { 200 fpa->masks = psMetadataAlloc(); 201 } 202 return psMetadataAddU8(fpa->masks, PS_LIST_TAIL, maskName, PS_META_REPLACE, NULL, maskValue); 203 } 204 205 bool pmFPAMaskReadHeader(pmFPA *fpa, const psMetadata *header, pmConfig *config) 206 { 207 PS_ASSERT_PTR_NON_NULL(fpa, false); 208 PS_ASSERT_METADATA_NON_NULL(header, false); 168 209 PS_ASSERT_PTR_NON_NULL(config, false); 210 211 if (!fpa->masks) { 212 fpa->masks = psMetadataAlloc(); 213 } 214 215 bool mdok; // Status of MD lookup 216 int numMask = psMetadataLookupS32(&mdok, header, "MSKNUM"); // Number of mask values in header 217 if (!mdok) { 218 if (psMetadataLookupBool(&mdok, config->camera, "MASK.FORCE")) { 219 psWarning("No mask values in header. Assuming MASKS recipe is accurate because of MASK.FORCE"); 220 numMask = 0; 221 } else { 222 psError(PS_ERR_UNKNOWN, true, "Unable to find MSKNUM in header."); 223 return false; 224 } 225 } 226 227 char namekey[80]; // Keyword name for symbolic name of mask entry 228 char valuekey[80]; // Keyword name for value of mask entry 229 for (int i = 0; i < numMask; i++) { 230 snprintf(namekey, 64, "MSKNAM%02d", i); 231 snprintf(valuekey, 64, "MSKVAL%02d", i); 232 233 char *name = psMetadataLookupStr(&mdok, header, namekey); 234 if (!mdok || !name) { 235 psWarning("Unable to find header keyword %s when parsing mask", namekey); 236 continue; 237 } 238 psU8 bit = psMetadataLookupU8(&mdok, header, valuekey); 239 if (!mdok) { 240 psWarning("Unable to find header keyword %s when parsing mask", namekey); 241 continue; 242 } 243 244 // XXX validate that bit is a 2^n value? 245 246 psMetadataItem *item = psMetadataLookup(fpa->masks, name); // Item in recipe with current value 247 if (item) { 248 psAssert(item->type == PS_TYPE_MASK, "Mask entry %s is not of a mask type (%x)", 249 name, item->type); 250 if (item->data.PS_TYPE_MASK_DATA != bit) { 251 psWarning("New mask entry %s doesn't match previously loaded entry: %x vs %x", 252 name, bit, item->data.PS_TYPE_MASK_DATA); 253 } 254 } else { 255 psMetadataAddU8(fpa->masks, PS_LIST_TAIL, name, 0, NULL, bit); 256 } 257 } 258 259 // Now copy everything else from the recipe 260 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 261 if (!recipe) { 262 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 263 return false; 264 } 265 266 psMetadataIterator *iter = psMetadataIteratorAlloc(recipe, PS_LIST_HEAD, NULL); // Iterator 267 psMetadataItem *item; // Item from iteration 268 while ((item = psMetadataGetAndIncrement(iter))) { 269 if (item->type != PS_TYPE_MASK) { 270 psWarning("Recipe mask entry %s is not of a mask type (%x)", item->name, item->type); 271 continue; 272 } 273 if (!psMetadataLookup(fpa->masks, item->name)) { 274 psMetadataAddU8(fpa->masks, PS_LIST_TAIL, item->name, 0, item->comment, 275 item->data.PS_TYPE_MASK_DATA); 276 } 277 } 278 psFree(iter); 279 280 return true; 281 } 282 283 284 bool pmFPAMaskWriteHeader(psMetadata *header, const pmFPA *fpa) 285 { 169 286 PS_ASSERT_METADATA_NON_NULL(header, false); 287 PS_ASSERT_PTR_NON_NULL(fpa, false); 170 288 171 289 maskRemoveHeader(header, "MSKNAM"); … … 175 293 } 176 294 295 char namekey[80], valuekey[80]; // Mask name and mask value header keywords 296 int numMask = 0; // Number of mask entries 297 298 psMetadataIterator *iter = psMetadataIteratorAlloc(fpa->masks, PS_LIST_HEAD, NULL); // Iterator 299 psMetadataItem *item; // Item from iteration 300 while ((item = psMetadataGetAndIncrement(iter))) { 301 if (item->type != PS_TYPE_MASK) { 302 psWarning("mask recipe entry %s is not of a mask type (%x)", item->name, item->type); 303 continue; 304 } 305 306 snprintf(namekey, 64, "MSKNAM%02d", numMask); 307 snprintf(valuekey, 64, "MSKVAL%02d", numMask); 308 309 psMetadataAddStr(header, PS_LIST_TAIL, namekey, 0, "Bitmask bit name", item->name); 310 psMetadataAddU8(header, PS_LIST_TAIL, valuekey, 0, "Bitmask bit value", item->data.PS_TYPE_MASK_DATA); 311 numMask++; 312 } 313 psFree(iter); 314 315 return psMetadataAddS32(header, PS_LIST_TAIL, "MSKNUM", 0, "Number of named mask entries", numMask); 316 } 317 318 #endif 319 320 321 psMaskType pmConfigMaskGet(const char *masks, const pmConfig *config) 322 { 323 psAssert(config, "Require configuration"); 324 PS_ASSERT_STRING_NON_EMPTY(masks, 0); 325 326 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 327 if (!recipe) { 328 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 329 return 0; 330 } 331 return maskGet(recipe, masks); 332 } 333 334 335 bool pmConfigMaskSet(const pmConfig *config, const char *maskName, psMaskType maskValue) 336 { 337 psAssert(config, "Require configuration"); 338 PS_ASSERT_STRING_NON_EMPTY(maskName, false); 339 340 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 341 if (!recipe) { 342 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 343 return false; 344 } 345 346 return psMetadataAddU8(recipe, PS_LIST_TAIL, maskName, PS_META_REPLACE, NULL, maskValue); 347 } 348 349 350 // replace the named masks in the recipe with values in the header: 351 // replace only the names in the header in the recipe 352 bool pmConfigMaskReadHeader(pmConfig *config, const psMetadata *header) 353 { 354 PS_ASSERT_PTR_NON_NULL(config, false); 355 PS_ASSERT_METADATA_NON_NULL(header, false); 356 357 bool status = false; 358 359 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 360 if (!recipe) { 361 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 362 return false; 363 } 364 365 // MASK.VALUE and MARK.VALUE aren't usually set in the recipe, but may be set in the header: create fake 366 // versions so that it won't complain later 367 if (!psMetadataLookup(recipe, "MASK.VALUE")) { 368 psMetadataAddU8(recipe, PS_LIST_TAIL, "MASK.VALUE", 0, "Bits to mask", 0); 369 } 370 if (!psMetadataLookup(recipe, "MARK.VALUE")) { 371 psMetadataAddU8(recipe, PS_LIST_TAIL, "MARK.VALUE", 0, "Bits for marking", 0); 372 } 373 374 int nMask = psMetadataLookupS32(&status, header, "MSKNUM"); 375 if (!status) { 376 if (psMetadataLookupBool(&status, config->camera, "MASK.FORCE")) { 377 psWarning("No mask values in header. Assuming MASKS recipe is accurate because of MASK.FORCE"); 378 return true; 379 } 380 psError(PS_ERR_UNKNOWN, true, "Unable to find MSKNUM in header."); 381 return false; 382 } 383 384 char namekey[80]; // Keyword name for symbolic name of mask entry 385 char valuekey[80]; // Keyword name for value of mask entry 386 for (int i = 0; i < nMask; i++) { 387 snprintf(namekey, 64, "MSKNAM%02d", i); 388 snprintf(valuekey, 64, "MSKVAL%02d", i); 389 390 char *name = psMetadataLookupStr(&status, header, namekey); 391 if (!status || !name) { 392 psWarning("Unable to find header keyword %s when parsing mask", namekey); 393 continue; 394 } 395 psU8 bit = psMetadataLookupU8(&status, header, valuekey); 396 if (!status) { 397 psWarning("Unable to find header keyword %s when parsing mask", namekey); 398 continue; 399 } 400 401 // XXX validate that bit is a 2^n value? 402 403 psString nameAlready = NULL; // Name of key with ".ALREADY" added 404 psStringAppend(&nameAlready, "%s.ALREADY", name); 405 bool already = psMetadataLookupBool(&status, recipe, nameAlready); // Already read this one? 406 407 psMetadataItem *item = psMetadataLookup(recipe, name); // Item in recipe with current value 408 if (item && item->type != PS_TYPE_MASK) { 409 psWarning("Mask recipe entry is not of a mask type (%x)", item->type); 410 item->type = PS_TYPE_MASK; 411 } 412 413 if (already) { 414 if (item && item->data.U8 != bit) { 415 psWarning("New mask recipe entry doesn't match previously loaded entry: %x vs %x", 416 bit, item->data.U8); 417 } 418 } else { 419 psMetadataAddBool(recipe, PS_LIST_TAIL, nameAlready, 0, "Already read this mask value", true); 420 } 421 422 if (!item) { 423 psWarning("Mask recipe entry %s not in recipe\n", name); 424 psMetadataAddU8(recipe, PS_LIST_TAIL, name, 0, "Bitmask bit value", bit); 425 } else { 426 item->data.U8 = bit; 427 } 428 429 psFree(nameAlready); 430 } 431 432 433 return true; 434 } 435 436 437 438 // write the named mask bits to the header 439 bool pmConfigMaskWriteHeader(const pmConfig *config, psMetadata *header) 440 { 441 PS_ASSERT_PTR_NON_NULL(config, false); 442 PS_ASSERT_METADATA_NON_NULL(header, false); 443 444 maskRemoveHeader(header, "MSKNAM"); 445 maskRemoveHeader(header, "MSKVAL"); 446 if (psMetadataLookup(header, "MSKNUM")) { 447 psMetadataRemoveKey(header, "MSKNUM"); 448 } 449 177 450 char namekey[80]; 178 451 char valuekey[80]; … … 211 484 } 212 485 213 // examine named mask values in mask recipe and set the bits for maskValue and markValue 214 // this function sets an appropriate value for the following required named mask concepts: 215 // FLAT (used to mark out-of-range corrections in the flat-fielding) 216 // BLANK (used to mark non-existent pixels) 217 // SAT (used to mark pixels with values out-of-range on the high end) 218 // BAD (used to mark pixels with values out-of-range on the low end) 219 // If there is no explicit value for the above, the 'DETECTOR' and 'RANGE' bits are used 220 // If these latter do not exist, the value 0x01 is used. 221 // The values actually used for these names are written back to the config file 486 222 487 bool pmConfigMaskSetBits(psMaskType *outMaskValue, psMaskType *outMarkValue, const pmConfig *config) 223 488 { 224 489 PS_ASSERT_PTR_NON_NULL(config, false); 225 490 226 psMaskType maskValue = 0; 227 228 // mask for generic detector defect 229 psMaskType detectorMask = pmConfigMaskGet("DETECTOR", config); 230 maskValue |= detectorMask; 231 232 // mask for dark structures 233 psMaskType darkMask = pmConfigMaskGet("DARK", config); 234 maskValue |= darkMask; 235 236 // mask for non-linear flat regions (default to DETECTOR if not defined) 237 psMaskType flatMask = pmConfigMaskGet("FLAT", config); 238 if (!flatMask) { 239 flatMask = detectorMask; 240 pmConfigMaskSet (config, "FLAT", flatMask); 241 } 242 if (!flatMask) { 243 flatMask = 0x01; 244 pmConfigMaskSet (config, "FLAT", flatMask); 245 } 246 maskValue |= flatMask; 247 248 // mask for non-existent data (default to DETECTOR if not defined) 249 psMaskType blankMask = pmConfigMaskGet("BLANK", config); 250 if (!blankMask) { 251 blankMask = detectorMask; 252 pmConfigMaskSet (config, "BLANK", blankMask); 253 } 254 if (!blankMask) { 255 blankMask = 0x01; 256 pmConfigMaskSet (config, "BLANK", blankMask); 257 } 258 maskValue |= blankMask; 259 260 // mask for generic data range errors 261 psMaskType rangeMask = pmConfigMaskGet("RANGE", config); 262 maskValue |= rangeMask; 263 264 // mask for saturated data (default to RANGE if not defined) 265 psMaskType satMask = pmConfigMaskGet("SAT", config); 266 if (!satMask) { 267 satMask = rangeMask; 268 pmConfigMaskSet (config, "SAT", satMask); 269 } 270 if (!satMask) { 271 satMask = 0x01; 272 pmConfigMaskSet (config, "SAT", satMask); 273 } 274 maskValue |= satMask; 275 276 // mask for below-range data (default to RANGE if not defined) 277 psMaskType badMask = pmConfigMaskGet("BAD", config); 278 if (!badMask) { 279 badMask = rangeMask; 280 pmConfigMaskSet (config, "BAD", badMask); 281 } 282 if (!badMask) { 283 badMask = 0x01; 284 pmConfigMaskSet (config, "BAD", badMask); 285 } 286 maskValue |= badMask; 287 288 // XXX not sure what to do with these 289 psMaskType crMask = pmConfigMaskGet("CR", config); 290 maskValue |= crMask; 291 292 psMaskType ghostMask = pmConfigMaskGet("GHOST", config); 293 maskValue |= ghostMask; 294 295 // search for an unset bit to use for MARK: 296 psMaskType markValue = 0x80; 297 298 int nBits = sizeof(psMaskType) * 8; 299 for (int i = 0; !markValue && (i < nBits); i++) { 300 if (maskValue & markValue) { 301 markValue >>= 1; 302 } else { 303 markValue = markValue; 304 } 305 } 306 if (!markValue) { 307 psError (PS_ERR_UNKNOWN, true, "Unable to define the MARK bit mask: all bits taken!"); 308 return false; 309 } 310 311 312 // update the config table 313 pmConfigMaskSet(config, "MASK.VALUE", maskValue); 314 pmConfigMaskSet(config, "MARK.VALUE", markValue); 315 316 if (outMaskValue) { 317 *outMaskValue = maskValue; 318 } 319 if (outMarkValue) { 320 *outMarkValue = markValue; 321 } 322 323 return true; 324 } 491 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe 492 if (!recipe) { 493 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe."); 494 return false; 495 } 496 497 return maskSetValues(outMaskValue, outMarkValue, recipe); 498 }
Note:
See TracChangeset
for help on using the changeset viewer.
