IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19335


Ignore:
Timestamp:
Sep 2, 2008, 3:37:23 PM (18 years ago)
Author:
Paul Price
Message:

Moving propagation of mask into convolveRegion(): it's already going over the mask, so it may as well do the lot; I also hoped this would fix the thread problems in subMask. I finally found what I believe is the source of the subMask thread problem: the subMask is being placed on the job arguments array, which alters the reference counter, so there can be a race condition.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmSubtraction.c

    r19299 r19335  
    223223    if (threaded) {
    224224        psMutexUnlock(image);
    225         psMutexLock(mask);
    226     }
    227     psImage *subMask = mask ? psImageSubset(mask, border) : NULL; // Subimage mask
    228     if (threaded) {
    229         psMutexUnlock(mask);
     225    }
     226
     227    psImage *subMask;                   // Subimage mask
     228    if (mask) {
     229        if (threaded) {
     230            psMutexLock(mask);
     231        }
     232        subMask = psImageSubset(mask, border);
     233        if (threaded) {
     234            psMutexUnlock(mask);
     235        }
     236    } else {
     237        subMask = NULL;
    230238    }
    231239
     
    238246    if (threaded) {
    239247        psMutexUnlock(image);
    240         psMutexLock(mask);
    241     }
    242     psFree(subMask);
    243     if (threaded) {
    244         psMutexUnlock(mask);
    245     }
    246 
    247     // Now, we have to chop off the borders, and stick it in where it belongs
    248     // No locking because we own this one
    249     psImage *subConv = psImageSubset(convolved, psRegionSet(size, -size, size, -size)); // Cut off the edges
    250 
     248    }
     249
     250    if (mask) {
     251        if (threaded) {
     252            psMutexLock(mask);
     253        }
     254        psFree(subMask);
     255        if (threaded) {
     256            psMutexUnlock(mask);
     257        }
     258    }
     259
     260    // Now, we have to stick it in where it belongs
    251261    int xMin = region.x0, xMax = region.x1, yMin = region.y0, yMax = region.y1; // Bounds of region
    252262    if (background != 0.0) {
     
    262272        }
    263273    }
    264     psFree(subConv);
    265274    psFree(convolved);
    266275
     
    303312                                  float background, // Background value to apply
    304313                                  psRegion region, // Region to convolve
     314                                  psMaskType maskBad, // Value to give bad pixels
     315                                  psMaskType maskPoor, // Value to give poor pixels
    305316                                  float poorFrac, // Fraction for "poor"
    306317                                  bool useFFT,  // Use FFT to convolve?
     
    313324    }
    314325
    315     psMaskType maskSource;              // Mask these values when
    316     psMaskType maskTarget;              // Set this mask value when convolving
     326    psMaskType subBad;                  // Bad pixels in subtraction mask
     327    psMaskType subConvBad;              // Bad pixels in subtraction mask when convolving
     328    psMaskType subConvPoor;             // Poor pixels in subtraction mask when convolving
    317329    if (kernels->mode == PM_SUBTRACTION_MODE_1 || (kernels->mode == PM_SUBTRACTION_MODE_DUAL && !wantDual)) {
    318         maskSource = PM_SUBTRACTION_MASK_BAD_1;
    319         maskTarget = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1;
     330        subBad = PM_SUBTRACTION_MASK_BAD_1;
     331        subConvBad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1;
     332        subConvPoor = PM_SUBTRACTION_MASK_CONVOLVE_1;
    320333    } else {
    321         maskSource = PM_SUBTRACTION_MASK_BAD_2;
    322         maskTarget = PM_SUBTRACTION_MASK_CONVOLVE_BAD_2;
     334        subBad = PM_SUBTRACTION_MASK_BAD_2;
     335        subConvBad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_2;
     336        subConvPoor = PM_SUBTRACTION_MASK_CONVOLVE_2;
    323337    }
    324338
     
    327341        // Use Fast Fourier Transform to do the convolution
    328342        // This provides a big speed-up for large kernels
    329         convolveFFT(convImage, image, subMask, maskSource, *kernelImage, region, background, kernels->size);
     343        convolveFFT(convImage, image, subMask, subBad, *kernelImage, region, background, kernels->size);
    330344        if (weight) {
    331             convolveFFT(convWeight, weight, subMask, maskSource, *kernelWeight, region, 0.0, kernels->size);
     345            convolveFFT(convWeight, weight, subMask, subBad, *kernelWeight, region, 0.0, kernels->size);
    332346        }
    333347    } else {
     348        // XXX Direct convolution doesn't account for bad pixels yet
    334349        convolveDirect(convImage, image, *kernelImage, region, background, kernels->size);
    335350        if (weight) {
     
    344359        if (box > 0) {
    345360            int colMin = region.x0, colMax = region.x1, rowMin = region.y0, rowMax = region.y1; // Bounds
    346 
    347361            bool threaded = pmSubtractionThreaded(); // Are we running threaded?
     362
    348363            if (threaded) {
    349364                psMutexLock(subMask);
    350365            }
    351366            psImage *image = psImageSubset(subMask, psRegionSet(colMin - box, colMax + box,
    352                                                                 rowMin - box, rowMax + box));
     367                                                                rowMin - box, rowMax + box)); // Mask
    353368            if (threaded) {
    354369                psMutexUnlock(subMask);
    355370            }
    356371
    357             psImage *convolved = psImageConvolveMask(NULL, image, maskSource, maskTarget,
     372            psImage *convolved = psImageConvolveMask(NULL, image, subBad, subConvBad,
    358373                                                     -box, box, -box, box); // Convolved subtraction mask
    359374
     
    366381            }
    367382
    368             int numBytes = (colMax - colMin) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy
    369383            psAssert(convolved->numCols - 2 * box == colMax - colMin, "Bad number of columns");
    370384            psAssert(convolved->numRows - 2 * box == rowMax - rowMin, "Bad number of rows");
    371385
    372             // Since we're copying back into the source, we need to lock
    373             if (threaded) {
    374                 psMutexLock(subMask);
    375             }
    376386            for (int yTarget = rowMin, ySource = box; yTarget < rowMax; yTarget++, ySource++) {
    377                 memcpy(&subMask->data.PS_TYPE_MASK_DATA[yTarget][colMin],
    378                        &convolved->data.PS_TYPE_MASK_DATA[ySource][box], numBytes);
    379             }
    380             if (threaded) {
    381                 psMutexUnlock(subMask);
     387                // Dereference images
     388                psMaskType *target = &convMask->data.PS_TYPE_MASK_DATA[yTarget][colMin]; // Target values
     389                psMaskType *source = &convolved->data.PS_TYPE_MASK_DATA[ySource][box]; // Source values
     390                for (int xTarget = colMin; xTarget < colMax; xTarget++, target++, source++) {
     391                    if (*source & subConvBad) {
     392                        *target |= maskBad;
     393                    } else if (*source & subConvPoor) {
     394                        *target |= maskPoor;
     395                    }
     396                }
    382397            }
    383398
     
    896911    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    897912        convolveRegion(out1->image, out1->weight, convMask, &kernelImage, &kernelWeight,
    898                        ro1->image, ro1->weight, subMask, kernels, polyValues, background,
    899                        *region, poorFrac, useFFT, false);
     913                       ro1->image, ro1->weight, subMask, kernels, polyValues, background, *region,
     914                       maskBad, maskPoor, poorFrac, useFFT, false);
    900915    }
    901916    if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    902917        convolveRegion(out2->image, out2->weight, convMask, &kernelImage, &kernelWeight,
    903                        ro2->image, ro2->weight, subMask, kernels, polyValues, background,
    904                        *region, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL);
     918                       ro2->image, ro2->weight, subMask, kernels, polyValues, background, *region,
     919                       maskBad, maskPoor, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL);
    905920    }
    906921
     
    909924    psFree(polyValues);
    910925
    911     // Propagate the subtraction mask
    912     if (subMask) {
    913         psMaskType **target = convMask->data.PS_TYPE_MASK_DATA; // Target mask
    914         psMaskType **source = subMask->data.PS_TYPE_MASK_DATA; // Source mask
    915 
    916         psMaskType poor, bad;           // Mask value for "poor" and "bad" pixels in subtraction mask
    917         switch (kernels->mode) {
    918           case PM_SUBTRACTION_MODE_1:
    919             poor = PM_SUBTRACTION_MASK_CONVOLVE_1;
    920             bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 | PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2;
    921             break;
    922           case PM_SUBTRACTION_MODE_2:
    923             poor = PM_SUBTRACTION_MASK_CONVOLVE_2;
    924             bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 | PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2;
    925             break;
    926           case PM_SUBTRACTION_MODE_DUAL:
    927             poor = PM_SUBTRACTION_MASK_CONVOLVE_1 | PM_SUBTRACTION_MASK_CONVOLVE_1;
    928             bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 | PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 |
    929                 PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2;
    930             break;
    931           default:
    932             psAbort("Unrecognised subtraction mode: %x", kernels->mode);
    933         }
    934 
    935         for (int y = yMin; y < yMax; y++) {
    936             for (int x = xMin; x < xMax; x++) {
    937                 // Pixels marked as "bad" shouldn't also be marked as "poor"
    938                 if (source[y][x] & bad) {
    939                     target[y][x] |= maskBad;
    940                 } else if (source[y][x] & poor){
    941                     target[y][x] |= maskPoor;
    942                 }
    943             }
    944         }
    945     }
    946926    if ((kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) && ro1->mask) {
    947927        psMaskType **target = convMask->data.PS_TYPE_MASK_DATA; // Target mask
     
    11601140                psArrayAdd(args, 1, (pmReadout*)ro1); // Casting away const
    11611141                psArrayAdd(args, 1, (pmReadout*)ro2); // Casting away const
     1142                // Since adding to the array can impact the reference count, we need to lock
     1143                psMutexLock(subMask);
    11621144                psArrayAdd(args, 1, (psImage*)subMask); // Casting away const
     1145                psMutexUnlock(subMask);
    11631146                PS_ARRAY_ADD_SCALAR(args, maskBad, PS_TYPE_U8);
    11641147                PS_ARRAY_ADD_SCALAR(args, maskPoor, PS_TYPE_U8);
Note: See TracChangeset for help on using the changeset viewer.