Changeset 25383 for trunk/psLib
- Timestamp:
- Sep 15, 2009, 12:45:01 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
-
. (modified) (1 prop)
-
psLib/src/fits/psFits.c (modified) (4 diffs)
-
psLib/src/fits/psFits.h (modified) (1 diff)
-
psLib/src/imageops/psImageConvolve.c (modified) (4 diffs)
-
psLib/src/imageops/psImageConvolve.h (modified) (1 diff)
-
psLib/src/types/psMetadata.c (modified) (4 diffs)
-
psLib/src/types/psMetadata.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/pap (added) merged: 25238,25241-25243,25246,25258-25267,25278,25302,25309-25312,25326-25329,25331-25339
- Property svn:mergeinfo changed
-
trunk/psLib/src/fits/psFits.c
r25049 r25383 344 344 // Therefore, we implement our own version of moving to an extension specified by name. The pure cfitsio 345 345 // version is used if "conventions.compression" handling is turned off in the psFits structure. 346 bool psFitsMoveExtName(const psFits* fits, 347 const char* extname) 346 static bool fitsMoveExtName(const psFits* fits, // FITS file 347 const char* extname, // Extension name 348 bool errors // Generate errors? 349 ) 348 350 { 349 351 PS_ASSERT_FITS_NON_NULL(fits, false); … … 356 358 // User wants to use cfitsio. Good luck to them! 357 359 if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) { 358 psFitsError(status, true, _("Could not find HDU '%s'"), extname); 360 if (errors) { 361 psFitsError(status, true, _("Could not find HDU '%s'"), extname); 362 } 359 363 return false; 360 364 } … … 378 382 if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) { 379 383 // We've run off the end 380 psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname); 384 if (errors) { 385 psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname); 386 } 381 387 return false; 382 388 } … … 406 412 } 407 413 psAbort("Should never reach here."); 414 } 415 416 417 bool psFitsMoveExtName(const psFits* fits, const char* extname) 418 { 419 return fitsMoveExtName(fits, extname, true); 420 } 421 422 bool psFitsMoveExtNameClean(const psFits* fits, const char* extname) 423 { 424 return fitsMoveExtName(fits, extname, false); 408 425 } 409 426 -
trunk/psLib/src/fits/psFits.h
r19035 r25383 245 245 ); 246 246 247 /** Moves the FITS HDU to the specified extension name without generating errors. 248 * 249 * @return bool TRUE if the extension name was found and move was 250 * successful, otherwise FALSE 251 */ 252 bool psFitsMoveExtNameClean( 253 const psFits* fits, ///< the psFits object to move 254 const char* extname ///< the extension name 255 ); 256 247 257 /** Moves the FITS HDU to the specified extension number 248 258 * -
trunk/psLib/src/imageops/psImageConvolve.c
r24272 r25383 678 678 } 679 679 680 static bool imageSmoothMaskPixels(psVector *out, const psImage *image, const psImage *mask, 681 psImageMaskType maskVal, const psVector *x, const psVector *y, 682 const psVector *gaussNorm, float minGauss, int size, int start, int stop) 683 { 684 const psF32 *gauss = &gaussNorm->data.F32[size]; // Gaussian convolution kernel 685 int numCols = image->numCols, numRows = image->numRows; // Size of image 686 int xLast = numCols - 1, yLast = numRows - 1; // Last index 687 for (int i = start; i < stop; i++) { 688 int xPix = x->data.S32[i], yPix = y->data.S32[i]; // Pixel coordinates for smoothing 689 690 int yMin = PS_MAX(yPix - size, 0); 691 int yMax = PS_MIN(yPix + size, yLast); 692 int xMin = PS_MAX(xPix - size, 0); 693 int xMax = PS_MIN(xPix + size, xLast); 694 695 const float *yGauss = &gauss[yMin - yPix]; 696 697 double ySumIG = 0.0, ySumG = 0.0; 698 for (int v = yMin; v <= yMax; v++, yGauss++) { 699 const float *xGauss = &gauss[xMin - xPix]; 700 double xSumIG = 0.0, xSumG = 0.0; 701 const psImageMaskType *maskData = &mask->data.PS_TYPE_IMAGE_MASK_DATA[v][xMin]; 702 const psF32 *imageData = &image->data.F32[v][xMin]; 703 for (int u = xMin; u <= xMax; u++, xGauss++, imageData++, maskData++) { 704 if (*maskData & maskVal) { 705 continue; 706 } 707 xSumIG += *imageData * *xGauss; 708 xSumG += *xGauss; 709 } 710 if (xSumG > minGauss) { 711 ySumIG += xSumIG * *yGauss; 712 ySumG += xSumG * *yGauss; 713 } 714 } 715 716 out->data.F32[i] = ySumG > minGauss ? ySumIG / ySumG : NAN; 717 } 718 719 return true; 720 } 721 722 static bool psImageSmoothMaskPixelsThread(psThreadJob *job) 723 { 724 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 725 psAssert(job->args, "programming error: no job arguments"); 726 psAssert(job->args->n == 11, "programming error: wrong number of job arguments"); 727 728 psVector *out = job->args->data[0]; // Output vector 729 const psImage *image = job->args->data[1]; // Input image 730 const psImage *mask = job->args->data[2]; // Input mask 731 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[3], PS_TYPE_IMAGE_MASK_DATA); 732 const psVector *x = job->args->data[4]; 733 const psVector *y = job->args->data[5]; 734 const psVector *gaussNorm = job->args->data[6]; 735 float minGauss = PS_SCALAR_VALUE(job->args->data[7], F32); 736 int size = PS_SCALAR_VALUE(job->args->data[8], S32); 737 int start = PS_SCALAR_VALUE(job->args->data[9], S32); 738 int stop = PS_SCALAR_VALUE(job->args->data[10], S32); 739 return imageSmoothMaskPixels(out, image, mask, maskVal, x, y, gaussNorm, 740 minGauss, size, start, stop); 741 } 742 743 744 psVector *psImageSmoothMaskPixels(const psImage *image, const psImage *mask, psImageMaskType maskVal, 745 const psVector *x, const psVector *y, 746 float sigma, float numSigma, float minGauss) 747 { 748 PS_ASSERT_IMAGE_NON_NULL(image, NULL); 749 PS_ASSERT_IMAGE_NON_NULL(mask, NULL); 750 PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL); 751 PS_ASSERT_IMAGES_SIZE_EQUAL(image, mask, NULL); 752 PS_ASSERT_VECTOR_NON_NULL(x, NULL); 753 PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_S32, NULL); 754 PS_ASSERT_VECTOR_NON_NULL(y, NULL); 755 PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_S32, NULL); 756 PS_ASSERT_VECTORS_SIZE_EQUAL(x, y, NULL); 757 758 int size = sigma * numSigma + 0.5; // Half-size of kernel 759 760 int num = x->n; // Number of pixels to smooth 761 psVector *out = psVectorAlloc(num, PS_TYPE_F32); // Output results 762 763 // Generate normalized gaussian 764 IMAGE_SMOOTH_GAUSS(gaussNorm, size, sigma, F32); 765 766 // Columns 767 if (threaded) { 768 int numThreads = psThreadPoolSize(); // Number of threads 769 int delta = (numThreads) ? num / numThreads + 1 : num; // Block of cols to do at once 770 for (int start = 0; start < num; start += delta) { 771 int stop = PS_MIN(start + delta, num); // End of block 772 773 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_PIXELS"); 774 psArrayAdd(job->args, 1, out); 775 psArrayAdd(job->args, 1, (psImage*)image); 776 psArrayAdd(job->args, 1, (psImage*)mask); 777 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 778 psArrayAdd(job->args, 1, (psVector*)x); 779 psArrayAdd(job->args, 1, (psVector*)y); 780 psArrayAdd(job->args, 1, gaussNorm); 781 PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32); 782 PS_ARRAY_ADD_SCALAR(job->args, size, PS_TYPE_S32); 783 PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32); 784 PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32); 785 if (!psThreadJobAddPending(job)) { 786 psFree(job); 787 psFree(gaussNorm); 788 psFree(out); 789 return NULL; 790 } 791 psFree(job); 792 } 793 } else if (!imageSmoothMaskPixels(out, image, mask, maskVal, x, y, 794 gaussNorm, minGauss, size, 0, num)) { 795 psError(PS_ERR_UNKNOWN, false, "Unable to smooth pixels."); 796 psFree(gaussNorm); 797 psFree(out); 798 return NULL; 799 } 800 801 if (threaded && !psThreadPoolWait(true)) { 802 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 803 psFree(gaussNorm); 804 psFree(out); 805 return NULL; 806 } 807 808 psFree(gaussNorm); 809 return out; 810 } 811 812 680 813 // Smooth an image with masked pixels 681 814 // The calculation and calcMask images are *deliberately* backwards (row,col instead of col,row or … … 1325 1458 if (threaded) { 1326 1459 int numThreads = psThreadPoolSize(); // Number of threads 1327 int deltaRows = (numThreads) ? numRows / numThreads : numRows; // Block of rows to do at once1460 int deltaRows = (numThreads) ? numRows / numThreads + 1 : numRows; // Block of rows to do at once 1328 1461 for (int start = 0; start < numRows; start += deltaRows) { 1329 int stop = PS_MIN (start + deltaRows, numRows); // end of row block1462 int stop = PS_MIN(start + deltaRows, numRows); // end of row block 1330 1463 1331 1464 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK"); … … 1363 1496 if (threaded) { 1364 1497 int numThreads = psThreadPoolSize(); // Number of threads 1365 int deltaCols = (numThreads) ? numCols / numThreads : numCols; // Block of cols to do at once1498 int deltaCols = (numThreads) ? numCols / numThreads + 1 : numCols; // Block of cols to do at once 1366 1499 for (int start = 0; start < numCols; start += deltaCols) { 1367 int stop = PS_MIN (start + deltaCols, numCols); // end of col block1500 int stop = PS_MIN(start + deltaCols, numCols); // end of col block 1368 1501 1369 1502 psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK"); … … 1486 1619 psFree(task); 1487 1620 } 1621 { 1622 psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_SMOOTHMASK_PIXELS", 9); 1623 task->function = &psImageSmoothMaskPixelsThread; 1624 psThreadTaskAdd(task); 1625 psFree(task); 1626 } 1488 1627 } else if (!set && threaded) { 1489 1628 psThreadTaskRemove("PSLIB_IMAGE_CONVOLVE_MASK"); -
trunk/psLib/src/imageops/psImageConvolve.h
r24272 r25383 222 222 ); 223 223 224 /// Smooth particular pixels on an image, allowing for masked pixels 225 /// 226 /// Applies a circularly symmetric Gaussian smoothing first in x and then in y 227 /// directions with just a vector. This process is 2N faster than 2D convolutions (in general). 228 psVector *psImageSmoothMaskPixels( 229 const psImage *image, ///< Input image (F32) 230 const psImage *mask, ///< Mask image 231 psImageMaskType maskVal, ///< Value to mask 232 const psVector *x, ///< x coordinates 233 const psVector *y, ///< y coordinates 234 float sigma, ///< Width of the smoothing kernel (pixels) 235 float numSigma, ///< Size of the smoothing box (sigma) 236 float minGauss ///< Minimum fraction of Gaussian to accept 237 ); 224 238 225 239 psImage *psImageSmoothMask_Threaded(psImage *output, -
trunk/psLib/src/types/psMetadata.c
r21183 r25383 996 996 if (metadataItem->type == PS_DATA_METADATA_MULTI) { 997 997 // if multiple keys found, use the first. 998 // metadataItem = (psMetadataItem*)((metadataItem->data.list)->head);999 998 metadataItem = (psMetadataItem*)(metadataItem->data.list->head->data); 1000 999 if (status) { … … 1082 1081 } \ 1083 1082 \ 1084 /* psFree(metadataItem); currently, the lookup doesn't increment the ref count */ \1085 1083 return value; \ 1086 1084 } … … 1101 1099 psMetadataLookupNumTYPE(VectorMaskType,VectorMask) 1102 1100 psMetadataLookupNumTYPE(ImageMaskType,ImageMask) 1101 1102 #define psMetadataLookupPtrTYPE(TYPENAME,NAME,TYPE,VAL) \ 1103 TYPENAME psMetadataLookup##NAME(bool *status, const psMetadata *md, const char *key) \ 1104 { \ 1105 PS_ASSERT_METADATA_NON_NULL(md, NULL); \ 1106 PS_ASSERT_STRING_NON_EMPTY(key, NULL); \ 1107 psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); /* The item of interest */ \ 1108 if (!item) { \ 1109 if (status) { \ 1110 *status = false; \ 1111 } else { \ 1112 psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key); \ 1113 } \ 1114 return NULL; \ 1115 } \ 1116 \ 1117 if (item->type == PS_DATA_METADATA_MULTI) { \ 1118 /* if multiple keys found, use the first. */ \ 1119 item = item->data.list->head->data; \ 1120 } \ 1121 if (item->type != TYPE) { \ 1122 if (status) { \ 1123 *status = false; \ 1124 } else { \ 1125 psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_META, as expected.\n", key); \ 1126 } \ 1127 return NULL; \ 1128 } \ 1129 \ 1130 if (status) { \ 1131 *status = true; \ 1132 } \ 1133 return item->data.VAL; \ 1134 } 1135 1136 psMetadataLookupPtrTYPE(psMetadata*, Metadata, PS_DATA_METADATA, md) 1137 psMetadataLookupPtrTYPE(psString, Str, PS_DATA_STRING, str) 1138 psMetadataLookupPtrTYPE(psTime*, Time, PS_DATA_TIME, V) 1139 psMetadataLookupPtrTYPE(psVector*, Vector, PS_DATA_VECTOR, V) 1140 1103 1141 1104 1142 psMetadataItem* psMetadataGet(const psMetadata *md, … … 1257 1295 } 1258 1296 1259 psMetadata *psMetadataLookupMetadata(bool *status, 1260 const psMetadata *md, 1261 const char *key) 1262 { 1263 PS_ASSERT_METADATA_NON_NULL(md,NULL); 1264 psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); // The metadata with instruments 1265 psMetadata *value = NULL; // The value to return 1266 if (!item) { 1267 // The given key isn't in the metadata 1268 if (status) { 1269 *status = false; 1270 } else { 1271 psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key); 1272 } 1273 } else if (item->type != PS_DATA_METADATA) { 1274 // The value at the key isn't metadata 1275 if (status) { 1276 *status = false; 1277 } else { 1278 psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_META, as expected.\n", key); 1279 } 1280 // value = NULL; 1281 } else { 1282 // We have the requested metadata 1283 if (status) { 1284 *status = true; 1285 } 1286 value = item->data.md; // The requested metadata 1287 } 1288 return value; 1289 } 1290 1291 psTime *psMetadataLookupTime(bool *status, 1292 const psMetadata *md, 1293 const char *key) 1294 { 1295 PS_ASSERT_METADATA_NON_NULL(md,NULL); 1296 1297 psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); 1298 if (!item) { 1299 // The given key isn't in the metadata 1300 if (status) { 1301 *status = false; 1302 } else { 1303 psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key); 1304 } 1305 return NULL; 1306 } 1307 1308 if (item->type != PS_DATA_TIME) { 1309 // The value at the key isn't metadata 1310 if (status) { 1311 *status = false; 1312 } else { 1313 psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_TIME, as expected.\n", key); 1314 } 1315 return NULL; 1316 } 1317 1318 // We have the requested metadata 1319 if (status) { 1320 *status = true; 1321 } 1322 1323 return item->data.V; 1324 } 1325 1326 1327 psString psMetadataLookupStr(bool *status, 1328 const psMetadata *md, 1329 const char *key) 1330 { 1331 PS_ASSERT_METADATA_NON_NULL(md,NULL); 1332 1333 psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); // The metadata with instruments 1334 // char *value = NULL; // The value to return 1335 psString value = NULL; 1336 if (!item) { 1337 // The given key isn't in the metadata 1338 if (status) { 1339 *status = false; 1340 } else { 1341 psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key); 1342 } 1343 } else if (item->type != PS_DATA_STRING) { 1344 // The value at the key isn't of the desired type 1345 if (status) { 1346 *status = false; 1347 } else { 1348 psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_STRING, as expected.\n", key); 1349 } 1350 // value = NULL; 1351 } else { 1352 // We have the requested metadata 1353 if (status) { 1354 *status = true; 1355 } 1356 value = item->data.V; 1357 } 1358 return value; 1359 } 1297 1298 1299 1360 1300 1361 1301 psList *psMetadataKeys(psMetadata *md) -
trunk/psLib/src/types/psMetadata.h
r23148 r25383 717 717 PS_METADATA_LOOKUP_TYPE_DECL(Ptr, psPtr); 718 718 PS_METADATA_LOOKUP_TYPE_DECL(Str, psString); 719 PS_METADATA_LOOKUP_TYPE_DECL(Vector, psVector*); 719 720 PS_METADATA_LOOKUP_TYPE_DECL(Metadata, psMetadata*); 720 721 PS_METADATA_LOOKUP_TYPE_DECL(Time, psTime*);
Note:
See TracChangeset
for help on using the changeset viewer.
