IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 10, 2005, 4:19:05 PM (21 years ago)
Author:
desonia
Message:

beefed up psImageTransform

File:
1 edited

Legend:

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

    r4211 r4214  
    1010 *  @author Ross Harman, MHPCC
    1111 *
    12  *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2005-06-10 21:26:47 $
     12 *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2005-06-11 02:19:05 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    688688}
    689689
    690 
    691 // XXX: implementation is awaiting working psPlaneTransform functions like
    692 // invert.  Also, the next SDRS should have a different signature.
    693690psImage* psImageTransform(psImage *output,
    694                           psArray** blankPixels,
     691                          psPixels* blankPixels,
    695692                          const psImage *input,
    696693                          const psImage *inputMask,
     
    705702        psError(PS_ERR_BAD_PARAMETER_NULL, true,
    706703                PS_ERRORTEXT_psImage_IMAGE_NULL);
    707         return NULL;
     704        psFree(output);
     705        return NULL;
     706    }
     707    psElemType type = input->type.type;
     708
     709    if (inputMask != NULL) {
     710        if (input->numRows != inputMask->numRows || input->numCols != inputMask->numCols) {
     711            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     712                    PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
     713                    input->numCols, input->numRows,
     714                    inputMask->numCols, inputMask->numRows );
     715            psFree(output);
     716            return NULL;
     717        }
     718        if (inputMask->type.type != PS_TYPE_MASK) {
     719            char* typeStr;
     720            PS_TYPE_NAME(typeStr,inputMask->type.type);
     721            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     722                    PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
     723                    typeStr, PS_TYPE_MASK_NAME);
     724            psFree(output);
     725            return NULL;
     726        }
    708727    }
    709728
     
    714733    }
    715734
    716     int row0 = region.y0;
    717     int row1 = region.y1;
    718     int col0 = region.x0;
    719     int col1 = region.x1;
    720     if (col1 < 1) {
    721         col1 += input->numCols;
    722     }
    723 
    724     if (row1 < 1) {
    725         row1 += input->numRows;
    726     }
    727 
    728     int numRows = row1 - row0;
    729     int numCols = col1 - col0;
    730 
    731     if (numRows < 1 || numCols < 1) {
    732         psError(PS_ERR_BAD_PARAMETER_SIZE, true,
    733                 "The specified region is invalid.");
    734         psFree(output);
    735         return NULL;
    736     }
    737 
    738     // create the output image.
    739     output = psImageRecycle(output, numCols, numRows, input->type.type);
    740     *(psS32*)&output->col0 = region.x0;
    741     *(psS32*)&output->row0 = region.y0;
    742 
     735    int row0;
     736    int row1;
     737    int col0;
     738    int col1;
     739    int numRows;
     740    int numCols;
     741    if (output == NULL) { // output image size is determined by psRegion
     742        row0 = region.y0;
     743        row1 = region.y1;
     744        col0 = region.x0;
     745        col1 = region.x1;
     746        if (col1 < 1) {
     747            col1 += input->numCols;
     748        }
     749
     750        if (row1 < 1) {
     751            row1 += input->numRows;
     752        }
     753
     754        numRows = row1 - row0;
     755        numCols = col1 - col0;
     756
     757        if (numRows < 1 || numCols < 1) {
     758            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
     759                    "The specified region is invalid.");
     760            psFree(output);
     761            return NULL;
     762        }
     763        // create the output image.
     764        output = psImageRecycle(output, numCols, numRows, input->type.type);
     765        *(psS32*)&output->col0 = region.x0;
     766        *(psS32*)&output->row0 = region.y0;
     767    } else { // size of output is determined by output parameter
     768        numRows = output->numRows;
     769        numCols = output->numCols;
     770        row0 = output->row0;
     771        col0 = output->col0;
     772        row1 = row0+numRows;
     773        col1 = col0+numCols;
     774    }
    743775
    744776    // loop through the output image using the domain above and transform
     
    747779    psPlane outPosition;
    748780    psPlane* inPosition = NULL;
    749     for (int row = 0; row < numRows; row++) {
    750         outPosition.y = row+row0;
    751         psF32* outputData=output->data.F32[row];
    752         for (int col = 0; col < numCols; col++) {
    753             outPosition.x = col+col0;
    754             // apply the transform to get the position in the input image
    755             inPosition = psPlaneTransformApply(inPosition, outToIn, &outPosition);
    756 
    757             if (inPosition == NULL) {
    758                 psError(PS_ERR_UNKNOWN, false,
    759                         "Failed to apply the transform");
    760                 psFree(output);
    761                 return NULL;
    762             }
    763             // interpolate the cooresponding input pixel to get the output pixel value.
    764             outputData[col] = (psF32)psImagePixelInterpolate(input,
    765                               inPosition->x, inPosition->y,
    766                               inputMask, inputMaskVal, exposedValue,
    767                               mode);
    768 
    769         }
     781
     782    #define PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     783    /* apply the transform to get the position in the input image */ \
     784    inPosition = psPlaneTransformApply(inPosition, outToIn, &outPosition); \
     785    \
     786    if (inPosition == NULL) { \
     787        psError(PS_ERR_UNKNOWN, false, \
     788                "Failed to apply the transform"); \
     789        psFree(output); \
     790        return NULL; \
     791    } \
     792    /* interpolate the cooresponding input pixel to get the output pixel value. */ \
     793    ps##TYPE value = p_psImagePixelInterpolate##MODE##_##TYPE(input, \
     794                     inPosition->x, inPosition->y, \
     795                     inputMask, inputMaskVal, NAN); \
     796    if (isnan(value)) { \
     797        if (blankPixels != NULL) { \
     798            p_psPixelsAppend(blankPixels, blankPixels->nalloc, outPosition.x, outPosition.y); \
     799        } \
     800        value = exposedValue; \
     801    } \
     802
     803    #define PSIMAGE_TRANSFORM_LOOP(TYPE, MODE) { \
     804        for (int row = 0; row < numRows; row++) { \
     805            outPosition.y = row+row0; \
     806            ps##TYPE* outputData=output->data.TYPE[row]; \
     807            for (int col = 0; col < numCols; col++) { \
     808                outPosition.x = col+col0; \
     809                PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     810                outputData[col] = value; \
     811            } \
     812        } \
     813    }
     814
     815    #define PSIMAGE_TRANSFORM_FROMLIST(TYPE, MODE) { \
     816        int n = pixels->n; \
     817        for (int i= 0; i < n; i++) { \
     818            int x = pixels->data[i].x; \
     819            int y = pixels->data[i].y; \
     820            if (x >= col0 && x < col1 && y >= row0 && y < row1) { \
     821                outPosition.x = x; \
     822                outPosition.y = y; \
     823                PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     824                output->data.TYPE[y][x] = value; \
     825            } \
     826        } \
     827    }
     828
     829    #define PSIMAGE_TRANSFORM_CASE(MODE) \
     830case PS_INTERPOLATE_##MODE: \
     831    switch (type) { \
     832    case PS_TYPE_F32: \
     833        PSIMAGE_TRANSFORM_LOOP(F32,MODE); \
     834        break; \
     835    case PS_TYPE_F64: \
     836        PSIMAGE_TRANSFORM_LOOP(F64,MODE); \
     837        break; \
     838    default: { \
     839            char* typeStr; \
     840            PS_TYPE_NAME(typeStr,type); \
     841            psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
     842                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED, \
     843                    typeStr); \
     844            psFree(output); \
     845            return NULL; \
     846        } \
     847    } \
     848    break;
     849
     850    switch (mode) {
     851        PSIMAGE_TRANSFORM_CASE(FLAT);
     852        PSIMAGE_TRANSFORM_CASE(BILINEAR);
     853        PSIMAGE_TRANSFORM_CASE(BILINEAR_VARIANCE);
     854    default:
     855        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     856                PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
     857                mode);
     858        psFree(output);
     859        return NULL;
    770860    }
    771861
Note: See TracChangeset for help on using the changeset viewer.