IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 23, 2004, 4:00:21 PM (22 years ago)
Author:
desonia
Message:

initial coding of psImageSlice and changed psImageRotate to be more inline
with ADD (mathematically equivalent).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/image/psImageExtraction.c

    r1267 r1292  
    99 *  @author Robert DeSonia, MHPCC
    1010 *
    11  *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-07-22 20:48:44 $
     11 *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-07-24 02:00:21 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    9999    if (input == NULL || input->data.V == NULL) {
    100100        psError(__func__,"Can not copy image because input image or its pixel buffer is NULL.");
     101        psFree(output);
    101102        return NULL;
    102103    }
     
    105106        psError(__func__,"Can not copy image because given input and output "
    106107                "parameter reference the same psImage struct.");
     108        psFree(output);
    107109        return NULL;
    108110    }
     
    110112    if (input->type.dimen != PS_DIMEN_IMAGE) {
    111113        psError(__func__,"Can not copy image because input image is not actually an image.");
     114        psFree(output);
    112115        return NULL;
    113116    }
     
    121124    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
    122125        psError(__func__,"Can not copy image to/from a void* matrix");
     126        psFree(output);
    123127        return NULL;
    124128    }
     
    225229}
    226230
     231psVector* psImageSlice(psVector* out,
     232                       const psImage* in,
     233                       const psImage* restrict mask,
     234                       unsigned int maskVal,
     235                       unsigned int col,
     236                       unsigned int row,
     237                       unsigned int numCols,
     238                       unsigned int numRows,
     239                       psImageCutDirection direction,
     240                       const psStats* stats)
     241{
     242    double statVal;
     243    psStats* myStats;
     244    psElemType type;
     245    int inRows;
     246    int inCols;
     247    int delta = 1;
     248    psF64* outData;
     249
     250    if (in == NULL || in->data.V == NULL) {
     251        psError(__func__,"Input image can not be NULL.");
     252        psFree(out);
     253        return NULL;
     254    }
     255
     256    type = in->type.type;
     257    inRows = in->numRows;
     258    inCols = in->numCols;
     259
     260    if (mask != NULL) {
     261        if (inRows!=mask->numRows || inCols!=mask->numCols) {
     262            psError(__func__,"The mask and image dimensions did not match (%dx%d vs %dx%d)",
     263                    mask->numCols,mask->numRows,in->numCols,in->numRows);
     264            psFree(out);
     265        }
     266        if (mask->type.type != PS_TYPE_MASK) {
     267            psError(__func__,"The mask datatype (%d) must be %s.",
     268                    mask->type.type, PS_TYPE_MASK_NAME);
     269            psFree(out);
     270        }
     271    }
     272
     273    if (row >= inRows || col >= inCols ||
     274            col+numCols > in->numCols || row+numRows > in->numRows) {
     275        psError(__func__,"The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).",
     276                col, row, col+numCols-1, row+numRows-1, in->numCols-1, in->numRows-1);
     277        psFree(out);
     278        return NULL;
     279    }
     280
     281    // verify that the stats struct specifies a single stats operation
     282    if (p_psGetStatValue(stats,&statVal) == false) {
     283        psError(__func__,"The stat options didn't specify a single supported statistic type.");
     284        psFree(out);
     285        return NULL;
     286    }
     287
     288    // since stats input is const, I need to create a 'scratch' stats struct
     289    myStats = psAlloc(sizeof(psStats));
     290    *myStats = *stats;
     291
     292
     293    if (direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG) {
     294        delta = -1;
     295    }
     296
     297    if (direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG) {
     298        psVector* imgVec = psVectorAlloc(numRows,type);
     299        psVector* maskVec = NULL;
     300        psMaskType* maskData = NULL;
     301
     302        // recycle output to make a proper sized/type output structure
     303        // n.b. type is double as that is the type given for all stats in psStats.
     304        out = psVectorRecycle(out,numCols,PS_TYPE_F64);
     305        outData = out->data.F64;
     306        if (delta < 0) {
     307            outData += numCols - 1;
     308        }
     309
     310        if (mask != NULL) {
     311            maskVec = psVectorAlloc(numRows,mask->type.type);
     312        }
     313
     314        #define PSIMAGE_CUT_VERTICAL(TYPE) \
     315    case PS_TYPE_##TYPE: { \
     316            ps##TYPE *imgVecData = imgVec->data.TYPE; \
     317            psMaskType* maskVecData = NULL; \
     318            if (maskVec != NULL) { \
     319                maskVecData = maskVec->data.V; \
     320            } \
     321            for (int c=0;c<numCols;c++) { \
     322                ps##TYPE *imgData = in->data.TYPE[row] + col + c; \
     323                if (maskVec != NULL) { \
     324                    maskData = (psMaskType*)(mask->data.V[row]) + col + c; \
     325                } \
     326                for (int r=0;r<numRows;r++) { \
     327                    *(imgVecData++) = *imgData; \
     328                    imgData += inCols; \
     329                    if (maskVecData != NULL) { \
     330                        *(maskVecData++) = *maskData; \
     331                        maskData += inCols; \
     332                    } \
     333                } \
     334                myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \
     335                (void)p_psGetStatValue(myStats,&statVal); \
     336                *outData = statVal; \
     337                outData += delta; \
     338            } \
     339            break; \
     340        }
     341
     342        switch (type) {
     343            PSIMAGE_CUT_VERTICAL(U8);
     344            PSIMAGE_CUT_VERTICAL(U16);
     345            PSIMAGE_CUT_VERTICAL(U32);
     346            PSIMAGE_CUT_VERTICAL(U64);
     347            PSIMAGE_CUT_VERTICAL(S8);
     348            PSIMAGE_CUT_VERTICAL(S16);
     349            PSIMAGE_CUT_VERTICAL(S32);
     350            PSIMAGE_CUT_VERTICAL(S64);
     351            PSIMAGE_CUT_VERTICAL(F32);
     352            PSIMAGE_CUT_VERTICAL(F64);
     353            PSIMAGE_CUT_VERTICAL(C32);
     354            PSIMAGE_CUT_VERTICAL(C64);
     355        default:
     356            psError(__func__,"Unsupported datatype (%d)",type);
     357            psFree(out);
     358            out = NULL;
     359        }
     360        psFree(imgVec);
     361        psFree(maskVec);
     362    } else { // Cut in Y direction
     363        psVector* imgVec = NULL;
     364        psVector* maskVec = NULL;
     365        int elementSize = PSELEMTYPE_SIZEOF(type);
     366
     367        // fill in psVectors to fake out the statistics functions.
     368        imgVec = psAlloc(sizeof(psVector));
     369        imgVec->type = in->type;
     370        imgVec->n = imgVec->nalloc = numCols;
     371        if (mask != NULL) {
     372            maskVec = psAlloc(sizeof(psVector));
     373            maskVec->type = mask->type;
     374            maskVec->n = maskVec->nalloc = numCols;
     375        }
     376
     377        // recycle output to make a proper sized/type output structure
     378        // n.b. type is double as that is the type given for all stats in psStats.
     379        out = psVectorRecycle(out,numRows,PS_TYPE_F64);
     380        outData = out->data.F64;
     381        if (delta < 0) {
     382            outData += numCols - 1;
     383        }
     384
     385        for (int r=0;r<numRows;r++) {
     386            // point the vector struct to the data to calculate the stats
     387            imgVec->data.V = (void*)(in->data.U8[row+r]+col*elementSize);
     388            if (maskVec!=NULL) {
     389                maskVec->data.V = (void*)(mask->data.U8[row+r]+col*sizeof(psMaskType));
     390            }
     391            myStats = psVectorStats(myStats,imgVec,maskVec,maskVal);
     392            (void)p_psGetStatValue(myStats,&statVal); // we know it works cause we tested it above
     393            *outData = statVal;
     394            outData += delta;
     395        }
     396    }
     397
     398    return out;
     399}
     400
Note: See TracChangeset for help on using the changeset viewer.