IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 18957


Ignore:
Timestamp:
Aug 8, 2008, 8:07:30 AM (18 years ago)
Author:
Paul Price
Message:

Working psImageConvolveMask into threads, since it can take a while.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageConvolve.c

    r17810 r18957  
    77/// @author Eugene Magnier, IfA
    88///
    9 /// @version $Revision: 1.71 $ $Name: not supported by cvs2svn $
    10 /// @date $Date: 2008-05-24 23:01:42 $
     9/// @version $Revision: 1.72 $ $Name: not supported by cvs2svn $
     10/// @date $Date: 2008-08-08 18:07:30 $
    1111///
    1212/// Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    3030#include "psImagePixelManip.h"
    3131#include "psTrace.h"
     32#include "psThread.h"
    3233
    3334#include "psImageConvolve.h"
     
    757758
    758759
     760// Convolve mask columns
     761static bool imageConvolveMaskColumns(psImage *target, // Output, convolved image
     762                                     const psImage *input, // Input image
     763                                     int start, int stop, // Range of rows
     764                                     psMaskType maskVal, // Value to mask; NOTE subtle difference!
     765                                     int xMin, int xMax // Range in x for kernel
     766                                     )
     767{
     768    // Dereference mask images
     769    psMaskType **inputData = input->data.PS_TYPE_MASK_DATA;
     770    psMaskType **targetData = target->data.PS_TYPE_MASK_DATA;
     771
     772    int numCols = input->numCols;       // Number of columns
     773
     774    for (int y = start; y < stop; y++) {
     775        int min = 0, max = 0;           // Minimum and maximum points to mask
     776        bool masking = false;           // Currently masking?
     777        for (int x = 0; x < numCols; x++) {
     778            if (inputData[y][x] & maskVal) {
     779                if (!masking) {
     780                    masking = true;
     781                    min = x + xMin;
     782                    max = x + xMax;
     783                } else {
     784                    max++;
     785                }
     786            } else if (masking) {
     787                // Do the masking
     788                masking = false;
     789                min = PS_MAX(0, min);
     790                max = PS_MIN(numCols - 1, max);
     791                memset(&targetData[y][min], 0xff, (max - min + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     792            }
     793        }
     794        if (masking) {
     795            // Mask from the minimum to the end of the row
     796            min = PS_MAX(0, min);
     797            memset(&targetData[y][min], 0xff, (numCols - min) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
     798        }
     799    }
     800    return true;
     801}
     802
     803static bool imageConvolveMaskRows(psImage *target, // Output, convolved image
     804                                     const psImage *input, // Input image
     805                                     int start, int stop, // Range of rows
     806                                     psMaskType setVal, // Value to set; NOTE subtle difference!
     807                                     int yMin, int yMax // Range in y for kernel
     808                                     )
     809{
     810    // Dereference mask images
     811    psMaskType **inputData = input->data.PS_TYPE_MASK_DATA;
     812    psMaskType **targetData = target->data.PS_TYPE_MASK_DATA;
     813
     814    int numRows = input->numRows;       // Number of rows
     815
     816    for (int x = start; x < stop; x++) {
     817        int min = 0, max = 0;           // Minimum and maximum points to mask
     818        bool masking = false;           // Currently masking?
     819        for (int y = 0; y < numRows; y++) {
     820            if (inputData[y][x]) {
     821                if (!masking) {
     822                    masking = true;
     823                    min = y + yMin;
     824                    max = y + yMax;
     825                } else {
     826                    max++;
     827                }
     828            } else if (masking) {
     829                // Do the masking
     830                masking = false;
     831                min = PS_MAX(0, min);
     832                max = PS_MIN(numRows - 1, max);
     833                for (int i = min; i <= max; i++) {
     834                    targetData[i][x] |= setVal;
     835                }
     836            }
     837        }
     838        if (masking) {
     839            // Mask from the minimum to the end of the column
     840            for (int i = PS_MAX(0, min); i < numRows; i++) {
     841                targetData[i][x] |= setVal;
     842            }
     843        }
     844    }
     845    return true;
     846}
     847
     848static bool imageConvolveMaskThread(const psThreadJob *job)
     849{
     850    PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     851
     852    psArray *args = job->args;          // Arguments for job
     853
     854    psImage *target = args->data[0];       // Output mask image
     855    const psImage *input = args->data[1];// Input mask image
     856    int start = PS_SCALAR_VALUE(args->data[2], S32); // Row/col to start at
     857    int stop = PS_SCALAR_VALUE(args->data[3], S32); // Row/col to stop at
     858    psMaskType maskVal = PS_SCALAR_VALUE(args->data[4], U8); // Value to mask/set
     859    int kernelMin = PS_SCALAR_VALUE(args->data[5], S32); // Minimum range for kernel
     860    int kernelMax = PS_SCALAR_VALUE(args->data[6], S32); // Maximum range for kernel
     861    bool row = PS_SCALAR_VALUE(args->data[7], U8); // Do row (true) or column (false)?
     862
     863    return row ? imageConvolveMaskRows(target, input, start, stop, maskVal, kernelMin, kernelMax) :
     864        imageConvolveMaskColumns(target, input, start, stop, maskVal, kernelMin, kernelMax);
     865}
    759866
    760867
     
    792899    }
    793900
     901    static bool threadsInit = false;    // Threads initialised?
     902    int numThreads = psThreadPoolSize();// Number of threads
     903    if (numThreads > 0 && !threadsInit) {
     904        psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_CONVOLVE_MASK", 8);
     905        task->function = &imageConvolveMaskThread;
     906        psThreadTaskAdd(task);
     907        psFree(task);
     908        threadsInit = true;
     909    }
     910
    794911    int numRows = mask->numRows;        // Number of rows
    795912    int numCols = mask->numCols;        // Number of columns
     
    805922    psImageInit(conv, 0);
    806923
    807     // Dereference mask images
    808     psMaskType **maskData = mask->data.PS_TYPE_MASK_DATA;
    809     psMaskType **convData = conv->data.PS_TYPE_MASK_DATA;
    810     psMaskType **outData = out->data.PS_TYPE_MASK_DATA;
    811 
    812924    // Since we're just masking everything inside a square, it's separable
     925
     926    // Rows
     927    if (numThreads > 0) {
     928        float cols = (float)numCols / (float)numThreads; // Number of cols to do at once
     929        for (int i = 0; i < numThreads; i++) {
     930            int start = i * cols;       // Starting colunms
     931            int stop = (i + 1) * cols;  // Stopping columns
     932
     933            psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK");
     934            psArrayAdd(job->args, 1, conv);
     935            psArrayAdd(job->args, 1, (psImage*)mask); // Casting away const to put on arguments
     936            PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32);
     937            PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32);
     938            PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_MASK);
     939            PS_ARRAY_ADD_SCALAR(job->args, xMin, PS_TYPE_S32);
     940            PS_ARRAY_ADD_SCALAR(job->args, xMax, PS_TYPE_S32);
     941            PS_ARRAY_ADD_SCALAR(job->args, 0x00, PS_TYPE_U8);
     942            if (!psThreadJobAddPending(job)) {
     943                psFree(job);
     944                psFree(conv);
     945                psFree(out);
     946                return NULL;
     947            }
     948            psFree(job);
     949        }
     950    } else if (!imageConvolveMaskColumns(conv, mask, 0, numRows, maskVal, xMin, xMax)) {
     951        psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns.");
     952        psFree(conv);
     953        psFree(out);
     954        return NULL;
     955    }
     956
     957    if (!psThreadPoolWait(true)) {
     958        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
     959        psFree(conv);
     960        psFree(out);
     961        return NULL;
     962    }
     963
     964    // Columns
     965    if (numThreads > 0) {
     966        float cols = (float)numCols / (float)numThreads; // Number of columns to do at once
     967        for (int i = 0; i < numThreads; i++) {
     968            int start = i * cols;       // Starting column
     969            int stop = (i + 1) * cols;  // Stopping column
     970
     971            psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK");
     972            psArrayAdd(job->args, 1, conv);
     973            psArrayAdd(job->args, 1, out);
     974            PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32);
     975            PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32);
     976            PS_ARRAY_ADD_SCALAR(job->args, setVal, PS_TYPE_MASK);
     977            PS_ARRAY_ADD_SCALAR(job->args, xMin, PS_TYPE_S32);
     978            PS_ARRAY_ADD_SCALAR(job->args, xMax, PS_TYPE_S32);
     979            PS_ARRAY_ADD_SCALAR(job->args, 0xff, PS_TYPE_U8);
     980            if (!psThreadJobAddPending(job)) {
     981                psFree(job);
     982                psFree(conv);
     983                psFree(out);
     984                return NULL;
     985            }
     986            psFree(job);
     987        }
     988    } else if (!imageConvolveMaskRows(out, conv, 0, numCols, setVal, yMin, yMax)) {
     989        psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns.");
     990        psFree(conv);
     991        psFree(out);
     992        return NULL;
     993    }
     994
     995    if (!psThreadPoolWait(true)) {
     996        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
     997        psFree(conv);
     998        psFree(out);
     999        return NULL;
     1000    }
     1001
     1002
     1003#if 0
    8131004    for (int y = 0; y < numRows; y++) {
    8141005        int min = 0, max = 0;           // Minimum and maximum points to mask
     
    8661057        }
    8671058    }
     1059#endif
    8681060
    8691061    psFree(conv);
     
    8711063    return out;
    8721064}
     1065
Note: See TracChangeset for help on using the changeset viewer.