IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 30, 2004, 4:27:43 PM (22 years ago)
Author:
desonia
Message:

fixed various bugs found in testing.

File:
1 edited

Legend:

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

    r1292 r1359  
    11/** @file  psImageManip.h
    2  *
    3  *  @brief Contains basic image extraction operations, as specified in the
    4  *         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
    5  *         Manipulation".
    6  *
    7  *  @ingroup Image
    8  *
    9  *  @author Robert DeSonia, MHPCC
    10  *
    11  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-07-24 02:00:21 $
    13  *
    14  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    15  *
    16  */
     2*
     3*  @brief Contains basic image extraction operations, as specified in the
     4*         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
     5*         Manipulation".
     6*
     7*  @ingroup Image
     8*
     9*  @author Robert DeSonia, MHPCC
     10*
     11*  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2004-07-31 02:27:43 $
     13*
     14*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     15*
     16*/
    1717
    1818#include <string.h>
     
    2222#include "psError.h"
    2323
    24 psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
    25                        unsigned int numRows, unsigned int col0,
    26                        unsigned int row0)
     24psImage *psImageSubset( psImage *out, psImage *image, unsigned int numCols,
     25                        unsigned int numRows, unsigned int col0,
     26                        unsigned int row0 )
    2727{
    2828    unsigned int elementSize;           // size of image element in bytes
    2929    unsigned int outputRowSize;         // output row size in bytes
    3030    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
    31 
    32     if (image == NULL || image->data.V == NULL) {
    33         psError(__func__,"Can not subset image because input image or its pixel buffer is NULL.");
    34         return NULL;
    35     }
    36 
    37     if (image->type.dimen != PS_DIMEN_IMAGE) {
    38         psError(__func__,"Can not subset image because input image is not an image.");
    39         return NULL;
    40     }
    41 
    42     if (numCols < 1 || numRows < 1) {
    43         psError(__func__,"Can not subset image because number of rows or columns are zero (%dx%d).",
    44                 numCols, numRows);
    45         return NULL;
    46     }
    47 
    48     if (col0 >= image->numCols || row0 >= image->numRows) {
    49         psError(__func__,"Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",
    50                 col0,row0);
    51         return NULL;
    52     }
    53 
     31   
     32    if ( image == NULL || image->data.V == NULL ) {
     33            psError( __func__, "Can not subset image because input image or its pixel buffer is NULL." );
     34            return NULL;
     35        }
     36       
     37    if ( image->type.dimen != PS_DIMEN_IMAGE ) {
     38            psError( __func__, "Can not subset image because input image is not an image." );
     39            return NULL;
     40        }
     41       
     42    if ( numCols < 1 || numRows < 1 ) {
     43            psError( __func__, "Can not subset image because number of rows or columns are zero (%dx%d).",
     44                     numCols, numRows );
     45            return NULL;
     46        }
     47       
     48    if ( col0 >= image->numCols || row0 >= image->numRows ) {
     49            psError( __func__, "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",
     50                     col0, row0 );
     51            return NULL;
     52        }
     53       
    5454    /* validate subimage size */
    55     if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
    56         psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
    57                 "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,col0,
    58                 col0+numCols, row0, row0+numRows);
    59         return NULL;
    60     }
    61 
    62 
    63     elementSize = PSELEMTYPE_SIZEOF(image->type.type);
    64 
    65     out = psImageRecycle(out,numCols,numRows,image->type.type);
    66 
     55    if ( col0 + numCols >= image->numCols || row0 + numRows >= image->numRows ) {
     56            psError( __func__, "Can not subset image outside of image boundaries (size=%dx%d, "
     57                     "subset=[%d:%d,%d:%d]).", image->numCols, image->numRows, col0,
     58                     col0 + numCols, row0, row0 + numRows );
     59            return NULL;
     60        }
     61       
     62       
     63    elementSize = PSELEMTYPE_SIZEOF( image->type.type );
     64   
     65    out = psImageRecycle( out, numCols, numRows, image->type.type );
     66   
    6767    // set the parent information into the child output image
    68     *(int*)&out->row0 = row0;
    69     *(int*)&out->col0 = col0;
    70     *(psImage**)&out->parent = (psImage*)image;
    71 
     68    *( int* ) & out->row0 = row0;
     69    *( int* ) & out->col0 = col0;
     70    *( psImage** ) & out->parent = ( psImage* ) image;
     71   
    7272    // add output image as a child of the input image.
    7373    image->nChildren++;
    74     image->children = (psImage **) psRealloc(image->children,
    75                       image->nChildren * sizeof(psImage*) );
    76     image->children[image->nChildren-1] = out;
    77 
    78     inputColOffset = elementSize*col0;
    79     outputRowSize = elementSize*numCols;
    80 
    81     for (int row = 0; row < numRows; row++) {
    82         memcpy(out->data.V[row],image->data.U8[row0+row] + inputColOffset,
    83                outputRowSize);
    84     }
    85 
    86     return (out);
     74    image->children = ( psImage ** ) psRealloc( image->children,
     75                      image->nChildren * sizeof( psImage* ) );
     76    image->children[ image->nChildren - 1 ] = out;
     77   
     78    inputColOffset = elementSize * col0;
     79    outputRowSize = elementSize * numCols;
     80   
     81    for ( int row = 0; row < numRows; row++ ) {
     82            memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset,
     83                    outputRowSize );
     84        }
     85       
     86    return ( out );
    8787}
    8888
    8989
    90 psImage *psImageCopy(psImage* restrict output, const psImage *input,
    91                      psElemType type)
     90psImage *psImageCopy( psImage* restrict output, const psImage *input,
     91                      psElemType type )
    9292{
    9393    psElemType inDatatype;
     
    9696    int numRows;
    9797    int numCols;
    98 
    99     if (input == NULL || input->data.V == NULL) {
    100         psError(__func__,"Can not copy image because input image or its pixel buffer is NULL.");
    101         psFree(output);
    102         return NULL;
    103     }
    104 
    105     if (input == output) {
    106         psError(__func__,"Can not copy image because given input and output "
    107                 "parameter reference the same psImage struct.");
    108         psFree(output);
    109         return NULL;
    110     }
    111 
    112     if (input->type.dimen != PS_DIMEN_IMAGE) {
    113         psError(__func__,"Can not copy image because input image is not actually an image.");
    114         psFree(output);
    115         return NULL;
    116     }
    117 
     98   
     99    if ( input == NULL || input->data.V == NULL ) {
     100            psError( __func__, "Can not copy image because input image or its pixel buffer is NULL." );
     101            psFree( output );
     102            return NULL;
     103        }
     104       
     105    if ( input == output ) {
     106            psError( __func__, "Can not copy image because given input and output "
     107                     "parameter reference the same psImage struct." );
     108            psFree( output );
     109            return NULL;
     110        }
     111       
     112    if ( input->type.dimen != PS_DIMEN_IMAGE ) {
     113            psError( __func__, "Can not copy image because input image is not actually an image." );
     114            psFree( output );
     115            return NULL;
     116        }
     117       
    118118    inDatatype = input->type.type;
    119119    numRows = input->numRows;
    120120    numCols = input->numCols;
    121     elements = numRows*numCols;
    122     elementSize = PSELEMTYPE_SIZEOF(inDatatype);
    123 
    124     if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
    125         psError(__func__,"Can not copy image to/from a void* matrix");
    126         psFree(output);
    127         return NULL;
    128     }
    129 
    130     output = psImageRecycle(output,numCols,numRows,type);
    131 
     121    elements = numRows * numCols;
     122    elementSize = PSELEMTYPE_SIZEOF( inDatatype );
     123   
     124    if ( inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR ) {
     125            psError( __func__, "Can not copy image to/from a void* matrix" );
     126            psFree( output );
     127            return NULL;
     128        }
     129       
     130    output = psImageRecycle( output, numCols, numRows, type );
     131   
    132132    // cover the trival case of copy of the same datatype.
    133     if (type == inDatatype) {
    134         memcpy(output->data.V[0],input->data.V[0],elementSize*elements);
    135         return output;
    136     }
    137 
     133    if ( type == inDatatype ) {
     134            memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements );
     135            return output;
     136        }
     137       
    138138    #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \
    139139        ps##INTYPE *in = IN->data.INTYPE[0]; \
    140140        ps##OUTTYPE *out = OUT->data.OUTTYPE[0]; \
    141141        for (int e=0;e<ELEMENTS;e++) { \
    142             *(out++) = *(in++); \
    143         } \
     142                *(out++) = *(in++); \
     143            } \
    144144    }
    145 
     145   
    146146    #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) \
    147147    switch (inDatatype) { \
    148     case PS_TYPE_S8: \
    149         PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
    150         break; \
    151     case PS_TYPE_S16: \
    152         PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
    153         break; \
    154     case PS_TYPE_S32: \
    155         PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
    156         break; \
    157     case PS_TYPE_S64: \
    158         PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
    159         break; \
    160     case PS_TYPE_U8: \
    161         PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
    162         break; \
    163     case PS_TYPE_U16: \
    164         PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
    165         break; \
    166     case PS_TYPE_U32: \
    167         PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
    168         break; \
    169     case PS_TYPE_U64: \
    170         PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
    171         break; \
    172     case PS_TYPE_F32: \
    173         PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
    174         break; \
    175     case PS_TYPE_F64: \
    176         PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
    177         break; \
    178     case PS_TYPE_C32: \
    179         PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
    180         break; \
    181     case PS_TYPE_C64: \
    182         PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
    183         break; \
    184     default: \
    185         break; \
    186     }
    187 
    188     switch (type) {
    189     case PS_TYPE_S8:
    190         PSIMAGE_COPY_CASE(output,S8);
    191         break;
    192     case PS_TYPE_S16:
    193         PSIMAGE_COPY_CASE(output,S16);
    194         break;
    195     case PS_TYPE_S32:
    196         PSIMAGE_COPY_CASE(output,S32);
    197         break;
    198     case PS_TYPE_S64:
    199         PSIMAGE_COPY_CASE(output,S64);
    200         break;
    201     case PS_TYPE_U8:
    202         PSIMAGE_COPY_CASE(output,U8);
    203         break;
    204     case PS_TYPE_U16:
    205         PSIMAGE_COPY_CASE(output,U16);
    206         break;
    207     case PS_TYPE_U32:
    208         PSIMAGE_COPY_CASE(output,U32);
    209         break;
    210     case PS_TYPE_U64:
    211         PSIMAGE_COPY_CASE(output,U64);
    212         break;
    213     case PS_TYPE_F32:
    214         PSIMAGE_COPY_CASE(output,F32);
    215         break;
    216     case PS_TYPE_F64:
    217         PSIMAGE_COPY_CASE(output,F64);
    218         break;
    219     case PS_TYPE_C32:
    220         PSIMAGE_COPY_CASE(output,C32);
    221         break;
    222     case PS_TYPE_C64:
    223         PSIMAGE_COPY_CASE(output,C64);
    224         break;
    225     default:
    226         break;
    227     }
     148            case PS_TYPE_S8: \
     149            PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
     150            break; \
     151            case PS_TYPE_S16: \
     152            PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
     153            break; \
     154            case PS_TYPE_S32: \
     155            PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
     156            break; \
     157            case PS_TYPE_S64: \
     158            PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
     159            break; \
     160            case PS_TYPE_U8: \
     161            PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
     162            break; \
     163            case PS_TYPE_U16: \
     164            PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
     165            break; \
     166            case PS_TYPE_U32: \
     167            PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
     168            break; \
     169            case PS_TYPE_U64: \
     170            PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
     171            break; \
     172            case PS_TYPE_F32: \
     173            PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
     174            break; \
     175            case PS_TYPE_F64: \
     176            PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
     177            break; \
     178            case PS_TYPE_C32: \
     179            PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
     180            break; \
     181            case PS_TYPE_C64: \
     182            PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
     183            break; \
     184            default: \
     185            break; \
     186        }
     187       
     188    switch ( type ) {
     189            case PS_TYPE_S8:
     190            PSIMAGE_COPY_CASE( output, S8 );
     191            break;
     192            case PS_TYPE_S16:
     193            PSIMAGE_COPY_CASE( output, S16 );
     194            break;
     195            case PS_TYPE_S32:
     196            PSIMAGE_COPY_CASE( output, S32 );
     197            break;
     198            case PS_TYPE_S64:
     199            PSIMAGE_COPY_CASE( output, S64 );
     200            break;
     201            case PS_TYPE_U8:
     202            PSIMAGE_COPY_CASE( output, U8 );
     203            break;
     204            case PS_TYPE_U16:
     205            PSIMAGE_COPY_CASE( output, U16 );
     206            break;
     207            case PS_TYPE_U32:
     208            PSIMAGE_COPY_CASE( output, U32 );
     209            break;
     210            case PS_TYPE_U64:
     211            PSIMAGE_COPY_CASE( output, U64 );
     212            break;
     213            case PS_TYPE_F32:
     214            PSIMAGE_COPY_CASE( output, F32 );
     215            break;
     216            case PS_TYPE_F64:
     217            PSIMAGE_COPY_CASE( output, F64 );
     218            break;
     219            case PS_TYPE_C32:
     220            PSIMAGE_COPY_CASE( output, C32 );
     221            break;
     222            case PS_TYPE_C64:
     223            PSIMAGE_COPY_CASE( output, C64 );
     224            break;
     225            default:
     226            break;
     227        }
    228228    return output;
    229229}
    230230
    231 psVector* 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)
     231psVector* psImageSlice( psVector* out,
     232                        const psImage* restrict 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 )
    241241{
    242242    double statVal;
     
    247247    int delta = 1;
    248248    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 
     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    if ( numRows == 0 || numCols == 0 ) {
     257            psError( __func__, "The specified region contains no data (%dx%d)",
     258                     numCols, numRows );
     259            psFree( out );
     260            return NULL;
     261        }
     262       
    256263    type = in->type.type;
    257264    inRows = in->numRows;
    258265    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 
     266   
     267    if ( direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG ) {
     268            delta = -1;
     269        }
     270       
     271    // if numRows/numCols is negative, invert the problem to give positive
     272    // numRows/numCols (and cut in opposite direction).
     273    if ( numRows < 0 ) {
     274            numRows = -numRows;
     275            row -= ( numRows - 1 );
     276            delta = -delta;
     277        }
     278       
     279    if ( numCols < 0 ) {
     280            numCols = -numCols;
     281            col -= ( numCols - 1 );
     282            delta = -delta;
     283        }
     284       
     285    if ( mask != NULL ) {
     286            if ( inRows != mask->numRows || inCols != mask->numCols ) {
     287                    psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)",
     288                             mask->numCols, mask->numRows, in->numCols, in->numRows );
     289                    psFree( out );
     290                }
     291            if ( mask->type.type != PS_TYPE_MASK ) {
     292                    psError( __func__, "The mask datatype (%d) must be %s.",
     293                             mask->type.type, PS_TYPE_MASK_NAME );
     294                    psFree( out );
     295                }
     296        }
     297       
     298    if ( row >= inRows || col >= inCols ||
     299            col + numCols > in->numCols || row + numRows > in->numRows ) {
     300            psError( __func__, "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).",
     301                     col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1 );
     302            psFree( out );
     303            return NULL;
     304        }
     305       
    281306    // 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 
     307    if ( stats == NULL || p_psGetStatValue( stats, &statVal ) == false ) {
     308            psError( __func__, "The stat options didn't specify a single supported statistic type." );
     309            psFree( out );
     310            return NULL;
     311        }
     312       
    288313    // since stats input is const, I need to create a 'scratch' stats struct
    289     myStats = psAlloc(sizeof(psStats));
     314    myStats = psAlloc( sizeof( psStats ) );
    290315    *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; \
     316   
     317   
     318   
     319    if ( direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG ) {
     320            psVector * imgVec = psVectorAlloc( numRows, type );
     321            psVector* maskVec = NULL;
     322            psMaskType* maskData = NULL;
     323           
     324            // recycle output to make a proper sized/type output structure
     325            // n.b. type is double as that is the type given for all stats in psStats.
     326            out = psVectorRecycle( out, PS_TYPE_F64, numCols );
     327            outData = out->data.F64;
     328            if ( delta < 0 ) {
     329                    outData += numCols - 1;
     330                }
     331               
     332            if ( mask != NULL ) {
     333                    maskVec = psVectorAlloc( numRows, mask->type.type );
     334                }
     335               
     336            #define PSIMAGE_CUT_VERTICAL(TYPE) \
     337            case PS_TYPE_##TYPE: { \
     338                psMaskType* maskVecData = NULL; \
     339                for (int c=0;c<numCols;c++) { \
     340                        ps##TYPE *imgData = in->data.TYPE[row] + col + c; \
     341                        ps##TYPE *imgVecData = imgVec->data.TYPE; \
     342                        if (maskVec != NULL) { \
     343                                maskVecData = maskVec->data.V; \
     344                                maskData = (psMaskType*)(mask->data.V[row]) + col + c; \
     345                            } \
     346                        for (int r=0;r<numRows;r++) { \
     347                                *(imgVecData++) = *imgData; \
     348                                imgData += inCols; \
     349                                if (maskVecData != NULL) { \
     350                                        *(maskVecData++) = *maskData; \
     351                                        maskData += inCols; \
     352                                    } \
     353                            } \
     354                        myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \
     355                        (void)p_psGetStatValue(myStats,&statVal); \
     356                        *outData = statVal; \
     357                        outData += delta; \
    332358                    } \
    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);
     359                break; \
     360            }
     361           
     362            switch ( type ) {
     363                    PSIMAGE_CUT_VERTICAL( U8 );
     364                    PSIMAGE_CUT_VERTICAL( U16 );
     365                    PSIMAGE_CUT_VERTICAL( U32 );
     366                    PSIMAGE_CUT_VERTICAL( U64 );
     367                    PSIMAGE_CUT_VERTICAL( S8 );
     368                    PSIMAGE_CUT_VERTICAL( S16 );
     369                    PSIMAGE_CUT_VERTICAL( S32 );
     370                    PSIMAGE_CUT_VERTICAL( S64 );
     371                    PSIMAGE_CUT_VERTICAL( F32 );
     372                    PSIMAGE_CUT_VERTICAL( F64 );
     373                    PSIMAGE_CUT_VERTICAL( C32 );
     374                    PSIMAGE_CUT_VERTICAL( C64 );
     375                    default:
     376                    psError( __func__, "Unsupported datatype (%d)", type );
     377                    psFree( out );
     378                    out = NULL;
     379                }
     380            psFree( imgVec );
     381            psFree( maskVec );
     382        } else if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction
     383            psVector * imgVec = NULL;
     384            psVector* maskVec = NULL;
     385            int elementSize = PSELEMTYPE_SIZEOF( type );
     386           
     387            // fill in psVectors to fake out the statistics functions.
     388            imgVec = psAlloc( sizeof( psVector ) );
     389            imgVec->type = in->type;
     390            imgVec->n = imgVec->nalloc = numCols;
     391            if ( mask != NULL ) {
     392                    maskVec = psAlloc( sizeof( psVector ) );
     393                    maskVec->type = mask->type;
     394                    maskVec->n = maskVec->nalloc = numCols;
     395                }
     396               
     397            // recycle output to make a proper sized/type output structure
     398            // n.b. type is double as that is the type given for all stats in psStats.
     399            out = psVectorRecycle( out, PS_TYPE_F64, numRows );
     400            outData = out->data.F64;
     401            if ( delta < 0 ) {
     402                    outData += numRows - 1;
     403                }
     404               
     405            for ( int r = 0;r < numRows;r++ ) {
     406                    // point the vector struct to the data to calculate the stats
     407                    imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize );
     408                    if ( maskVec != NULL ) {
     409                            maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) );
     410                        }
     411                    myStats = psVectorStats( myStats, imgVec, maskVec, maskVal );
     412                    ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above
     413                    *outData = statVal;
     414                    outData += delta;
     415                }
     416            psFree( imgVec );
     417            psFree( maskVec );
     418        } else { // don't know what the direction flag is
     419            psError( __func__, "Invalid direction flag (%d)", direction );
     420            psFree( out );
    358421            out = NULL;
    359422        }
    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 
     423       
     424    psFree( myStats );
     425   
    398426    return out;
    399427}
Note: See TracChangeset for help on using the changeset viewer.