IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 12741


Ignore:
Timestamp:
Apr 4, 2007, 12:42:02 PM (19 years ago)
Author:
Paul Price
Message:

Reworking image interpolation to work on mask and variance image
simultaneously with the proper image. Working in the idea of having
"good", "bad" and "poor" output mask pixels (taken from Andy Becker),
where "poor" pixels have at least one bad input pixel contributing to
the flux, but the contribution is small (where 'small' is defined by a
user option). To handle all the options, created a
psImageInterpolateOptions structure, which contains all the things
which are constant while looping over an image (including the input
image, variance and mask). Changed function name, and split code out
of psImage.[ch] into its own file. Function returns boolean error
status; output values for image, variance and mask come from pointers
to double. Added interpolation types (GAUSS, LANCZOS2, LANCZOS3,
LANCZOS4). Using a fairly general framework so that additional
interpolation methods might be easily added. Updated tests and other
dependent code. Tests pass (but only test BILINEAR and BICUBE), and
pswarp works (but currently only uses BILINEAR).

Location:
trunk/psLib
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/Makefile.am

    r12588 r12741  
    88        psImageConvolve.c \
    99        psImageGeomManip.c \
     10        psImageInterpolate.c \
    1011        psImagePixelExtract.c \
    1112        psImagePixelManip.c \
     
    2223        psImageConvolve.h \
    2324        psImageGeomManip.h \
     25        psImageInterpolate.h \
    2426        psImagePixelExtract.h \
    2527        psImagePixelManip.h \
  • trunk/psLib/src/imageops/psImageConvolve.c

    r12187 r12741  
    77/// @author Eugene Magnier, IfA
    88///
    9 /// @version $Revision: 1.50 $ $Name: not supported by cvs2svn $
    10 /// @date $Date: 2007-03-02 22:19:21 $
     9/// @version $Revision: 1.51 $ $Name: not supported by cvs2svn $
     10/// @date $Date: 2007-04-04 22:42:02 $
    1111///
    1212/// Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    102102                           const psVector *xShifts,
    103103                           const psVector *yShifts,
    104                            bool tRelative,
     104                           float totalTime,
    105105                           bool xyRelative)
    106106{
     
    113113    PS_ASSERT_VECTOR_TYPE(xShifts, PS_TYPE_S32, NULL);
    114114    PS_ASSERT_VECTOR_TYPE(yShifts, PS_TYPE_S32, NULL);
     115
     116    if (isnan(totalTime)) {
     117        // It's more expensive to check for NAN than 0.0
     118        totalTime = 0.0;
     119    }
    115120
    116121    // If there are no shifts, the kernel is just a 1 at 0,0
     
    153158        }
    154159
    155         if (tRelative) {
     160        if (totalTime <= 0) {
    156161            tSum += tShifts->data.F32[i];
    157162        }
     
    160165    psTrace("psLib.imageops", 5, "Kernel range: %d:%d,%d:%d\n", xMin, xMax, yMin, yMax);
    161166
    162     if (!tRelative) {
     167    if (totalTime > 0) {
    163168        // Then the total time is simply the final value
    164169        // NB: We assume the counter starts at zero!
    165         tSum = tShifts->data.F32[tShifts->n - 1];
     170        tSum = totalTime;
    166171    }
    167172
     
    181186        }
    182187        float t = tShifts->data.F32[i];
    183         if (!tRelative) {
     188        if (totalTime > 0) {
    184189            t -= tLast;
    185190            tLast = tShifts->data.F32[i];
  • trunk/psLib/src/imageops/psImageConvolve.h

    r12187 r12741  
    55 * @author Robert DeSonia, MHPCC
    66 *
    7  * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2007-03-02 22:19:21 $
     7 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2007-04-04 22:42:02 $
    99 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1010 */
     
    9898///
    9999psKernel *psKernelGenerate(
    100     const psVector *tShifts,           ///< list of time shifts (F32)
    101     const psVector *xShifts,           ///< list of x-axis shifts (S32)
    102     const psVector *yShifts,           ///< list of y-axis shifts (S32)
    103     bool tRelative,                    ///< Are times relative (durations) or absolute?
    104     bool xyRelative                    ///< Are x,y positions relative (shifts) or absolute?
     100    const psVector *tShifts,            ///< list of time shifts (F32)
     101    const psVector *xShifts,            ///< list of x-axis shifts (S32)
     102    const psVector *yShifts,            ///< list of y-axis shifts (S32)
     103    float totalTime,                    ///< Total time (relative times if negative)
     104    bool xyRelative                     ///< Are x,y positions relative (shifts) or absolute?
    105105);
    106106
  • trunk/psLib/src/imageops/psImageGeomManip.c

    r12431 r12741  
    1010 *  @author Ross Harman, MHPCC
    1111 *
    12  *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2007-03-14 00:39:50 $
     12 *  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2007-04-04 22:42:02 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    3333#include "psMemory.h"
    3434#include "psAssert.h"
    35 
     35#include "psImageInterpolate.h"
    3636#include "psCoord.h"
    3737
     
    200200    }
    201201
    202     if (mode > PS_INTERPOLATE_LANCZOS4_VARIANCE ) {
    203         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    204                 _("Specified interpolation mode, %d, is unsupported."),
    205                 mode);
    206         psFree(out);
    207         return NULL;
    208     }
    209 
    210202    // create an output image of the same size
    211203    // and type
     
    213205    outCols = in->numCols * scale;
    214206    invScale = 1.0f / (float)scale;
     207
     208    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, in, NULL, NULL, 0,
     209                                                                       NAN, NAN, 0, 0, 0);
    215210
    216211    #define PSIMAGE_RESAMPLE_CASE(TYPE) \
     
    221216            float inRow = (float)row * invScale; \
    222217            for (psS32 col=0;col<outCols;col++) { \
    223                 rowData[col] = psImagePixelInterpolate(in,(float)col*invScale,inRow,NULL,0,0,mode); \
     218                double value; \
     219                if (!psImageInterpolate(&value, NULL, NULL, (float)col*invScale, inRow, interp)) { \
     220                    psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     221                    psFree(interp); \
     222                    psFree(out); \
     223                    return NULL; \
     224                } \
     225                rowData[col] = value; \
    224226            } \
    225227        }  \
     
    249251    }
    250252
     253    psFree(interp);
     254
    251255    return out;
    252256}
     
    492496        float CenterYMinusminXTimesSinT = centerY - minX * sinT;
    493497
    494         #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
     498        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, NULL, 0,
     499                                                                           exposed, NAN, 0, 0, 0.0);
     500
     501        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE)  \
     502          case PS_TYPE_##TYPE: { \
    495503            if (exposed < PS_MIN_##TYPE || \
    496504                    exposed > PS_MAX_##TYPE || \
     
    515523                outRow = out->data.TYPE[y]; \
    516524                for (psS32 x = 0; x < outCols; x++) { \
    517                     outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(input,inX,inY,NULL,0,exposed); \
     525                    double value; \
     526                    if (!psImageInterpolate(&value, NULL, NULL, inX, inY, interp)) { \
     527                        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     528                        psFree(out); \
     529                        psFree(interp); \
     530                        return NULL; \
     531                    } \
     532                    outRow[x] = value; \
    518533                    inX += cosT; \
    519534                    inY -= sinT; \
    520535                } \
    521536            } \
    522         }
    523 
    524         #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
    525     case PS_INTERPOLATE_##MODE: \
    526         switch (type) { \
    527         case PS_TYPE_U8: \
    528             PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
    529537            break; \
    530         case PS_TYPE_U16: \
    531             PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
    532             break; \
    533         case PS_TYPE_U32:   /* Not a requirement */ \
    534             PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
    535             break; \
    536         case PS_TYPE_U64:   /* Not a requirement */ \
    537             PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
    538             break;  \
    539         case PS_TYPE_S8: \
    540             PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
    541             break; \
    542         case PS_TYPE_S16: \
    543             PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
    544             break; \
    545         case PS_TYPE_S32:   /* Not a requirement */ \
    546             PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
    547             break; \
    548         case PS_TYPE_S64:   /* Not a requirement */ \
    549             PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
    550             break; \
    551         case PS_TYPE_F32: \
    552             PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
    553             break; \
    554         case PS_TYPE_F64: \
    555             PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
    556             break; \
    557         default: { \
    558                 char* typeStr; \
    559                 PS_TYPE_NAME(typeStr,type); \
    560                 psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    561                         _("Specified psImage type, %s, is not supported."), \
    562                         typeStr); \
    563                 psFree(out); \
    564                 out = NULL; \
    565             } \
    566         } \
    567         break;
    568 
    569         switch (mode) {
    570             PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
    571             PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
    572             PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR_VARIANCE);
    573         default:
    574             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    575                     _("Specified interpolation mode, %d, is unsupported."),
    576                     mode);
    577             psFree(out);
    578             out = NULL;
    579         }
     538        }
     539
     540        switch (type) {
     541            PSIMAGE_ROTATE_ARBITRARY_LOOP(U8);
     542            PSIMAGE_ROTATE_ARBITRARY_LOOP(U16);
     543            PSIMAGE_ROTATE_ARBITRARY_LOOP(U32);
     544            PSIMAGE_ROTATE_ARBITRARY_LOOP(U64);
     545            PSIMAGE_ROTATE_ARBITRARY_LOOP(S8);
     546            PSIMAGE_ROTATE_ARBITRARY_LOOP(S16);
     547            PSIMAGE_ROTATE_ARBITRARY_LOOP(S32);
     548            PSIMAGE_ROTATE_ARBITRARY_LOOP(S64);
     549            PSIMAGE_ROTATE_ARBITRARY_LOOP(F32);
     550            PSIMAGE_ROTATE_ARBITRARY_LOOP(F64);
     551          default: {
     552              char* typeStr;
     553              PS_TYPE_NAME(typeStr,type);
     554              psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     555                      _("Specified psImage type, %s, is not supported."),
     556                      typeStr);
     557              psFree(out);
     558              psFree(interp);
     559              out = NULL;
     560          }
     561        }
     562
     563        psFree(interp);
     564
    580565    }
    581566
     
    695680    out = psImageRecycle(out, outCols, outRows, type);
    696681
    697     #define PSIMAGE_SHIFT_CASE(MODE,TYPE) \
     682    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, NULL, 0,
     683                                                                       exposed, NAN, 0, 0, 0.0);
     684
     685    #define PSIMAGE_SHIFT_CASE(TYPE) \
    698686case PS_TYPE_##TYPE: \
    699687    if (exposed < PS_MIN_##TYPE || \
     
    719707        for (psS32 col=0;col<outCols;col++) { \
    720708            float x = col + 0.5 - dx; \
    721             outRow[col] = p_psImagePixelInterpolate##MODE##_##TYPE( \
    722                           input,x,y,NULL,0,exposed); \
     709            double value; \
     710            if (!psImageInterpolate(&value, NULL, NULL, x, y, interp)) { \
     711                psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     712                psFree(interp); \
     713                psFree(out); \
     714                return NULL; \
     715            } \
     716            outRow[col] = value; \
    723717        } \
    724718    } \
    725719    break;
    726720
    727     #define PSIMAGE_SHIFT_ARBITRARY_CASE(MODE) \
    728 case PS_INTERPOLATE_##MODE: \
    729     switch (input->type.type) { \
    730         PSIMAGE_SHIFT_CASE(MODE,U8);  \
    731         PSIMAGE_SHIFT_CASE(MODE,U16); \
    732         PSIMAGE_SHIFT_CASE(MODE,U32);     /* Not a requirement */ \
    733         PSIMAGE_SHIFT_CASE(MODE,U64);     /* Not a requirement */ \
    734         PSIMAGE_SHIFT_CASE(MODE,S8);  \
    735         PSIMAGE_SHIFT_CASE(MODE,S16); \
    736         PSIMAGE_SHIFT_CASE(MODE,S32);    /* Not a requirement */ \
    737         PSIMAGE_SHIFT_CASE(MODE,S64);    /* Not a requirement */ \
    738         PSIMAGE_SHIFT_CASE(MODE,F32); \
    739         PSIMAGE_SHIFT_CASE(MODE,F64); \
    740        \
    741     default: { \
    742             char* typeStr; \
    743             PS_TYPE_NAME(typeStr,type); \
    744             psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    745                     _("Specified psImage type, %s, is not supported."), \
    746                     typeStr); \
    747             psFree(out); \
    748             out = NULL; \
    749         } \
    750     } \
    751     break;
    752 
    753     // EAM: added BICUBE
    754     switch (mode) {
    755         PSIMAGE_SHIFT_ARBITRARY_CASE(FLAT);
    756         PSIMAGE_SHIFT_ARBITRARY_CASE(BILINEAR);
    757         PSIMAGE_SHIFT_ARBITRARY_CASE(BILINEAR_VARIANCE);
    758         PSIMAGE_SHIFT_ARBITRARY_CASE(BICUBE);
    759     default:
    760         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    761                 _("Specified interpolation mode, %d, is unsupported."),
    762                 mode);
    763         psFree(out);
    764         out = NULL;
    765     }
    766 
     721    switch (input->type.type) {
     722        PSIMAGE_SHIFT_CASE(U8);
     723        PSIMAGE_SHIFT_CASE(U16);
     724        PSIMAGE_SHIFT_CASE(U32);
     725        PSIMAGE_SHIFT_CASE(U64);
     726        PSIMAGE_SHIFT_CASE(S8);
     727        PSIMAGE_SHIFT_CASE(S16);
     728        PSIMAGE_SHIFT_CASE(S32);
     729        PSIMAGE_SHIFT_CASE(S64);
     730        PSIMAGE_SHIFT_CASE(F32);
     731        PSIMAGE_SHIFT_CASE(F64);
     732      default: {
     733          char* typeStr;
     734          PS_TYPE_NAME(typeStr,type);
     735          psError(PS_ERR_BAD_PARAMETER_TYPE, true, _("Specified psImage type, %s, is not supported."),
     736                  typeStr);
     737          psFree(out);
     738          psFree(interp);
     739          return NULL;
     740        }
     741    }
     742
     743    psFree(interp);
    767744    return out;
    768745}
     
    866843
    867844    // loop through the output image using the domain above and transform
    868     // each output pixel to input coordinates and use psImagePixelInterpolate
     845    // each output pixel to input coordinates and use psImageInterpolate
    869846    // to determine the pixel value.
    870847    psPlane outPosition;
    871848    psPlane* inPosition = NULL;
    872849
    873     #define PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     850    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, inputMask,
     851                                                                       inputMaskVal, NAN, NAN, 0, 0, 0.0);
     852
     853
     854    #define PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE) \
    874855    /* apply the transform to get the position in the input image */ \
    875856    inPosition = psPlaneTransformApply(inPosition, outToIn, &outPosition); \
     
    882863    } \
    883864    /* interpolate the cooresponding input pixel to get the output pixel value. */ \
    884     ps##TYPE value = p_psImagePixelInterpolate##MODE##_##TYPE(input, \
    885                      inPosition->x, inPosition->y, \
    886                      inputMask, inputMaskVal, NAN); \
     865    double value; \
     866    if (!psImageInterpolate(&value, NULL, NULL, inPosition->x, inPosition->y, interp)) { \
     867        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     868        psFree(output); \
     869        psFree(interp); \
     870        return NULL; \
     871    } \
    887872    /*    psFree(inPosition); */\
    888873    if (isnan(value)) { \
     
    893878    } \
    894879
    895     #define PSIMAGE_TRANSFORM_LOOP(TYPE, MODE) { \
     880    #define PSIMAGE_TRANSFORM_CASE(TYPE) \
     881      case PS_TYPE_##TYPE: { \
    896882        for (int row = 0; row < numRows; row++) { \
    897883            outPosition.y = row+row0; \
     
    899885            for (int col = 0; col < numCols; col++) { \
    900886                outPosition.x = col+col0; \
    901                 PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
     887                PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE) \
    902888                outputData[col] = value; \
    903889            } \
    904890        } \
    905     }
    906 
    907     #define PSIMAGE_TRANSFORM_FROMLIST(TYPE, MODE) { \
    908         int n = pixels->n; \
    909         for (int i= 0; i < n; i++) { \
    910             int x = pixels->data[i].x; \
    911             int y = pixels->data[i].y; \
    912             if (x >= col0 && x < col1 && y >= row0 && y < row1) { \
    913                 outPosition.x = x; \
    914                 outPosition.y = y; \
    915                 PSIMAGE_TRANSFORM_DOTRANSFORM(TYPE,MODE) \
    916                 output->data.TYPE[y][x] = value; \
    917             } \
    918         } \
    919     }
    920 
    921     #define PSIMAGE_TRANSFORM_CASE(MODE) \
    922 case PS_INTERPOLATE_##MODE: \
    923     switch (type) { \
    924     case PS_TYPE_F32: \
    925         PSIMAGE_TRANSFORM_LOOP(F32,MODE); \
    926891        break; \
    927     case PS_TYPE_F64: \
    928         PSIMAGE_TRANSFORM_LOOP(F64,MODE); \
    929         break; \
    930     default: { \
    931             char* typeStr; \
    932             PS_TYPE_NAME(typeStr,type); \
    933             psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
    934                     _("Specified psImage type, %s, is not supported."), \
    935                     typeStr); \
    936             psFree(output); \
    937             return NULL; \
    938         } \
    939     } \
    940     break;
    941 
    942     switch (mode) {
    943         PSIMAGE_TRANSFORM_CASE(FLAT);
    944         PSIMAGE_TRANSFORM_CASE(BILINEAR);
    945         PSIMAGE_TRANSFORM_CASE(BILINEAR_VARIANCE);
    946     default:
    947         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    948                 _("Specified interpolation mode, %d, is unsupported."),
    949                 mode);
    950         psFree(output);
    951         return NULL;
     892    }
     893
     894    switch (type) {
     895        PSIMAGE_TRANSFORM_CASE(F32);
     896        PSIMAGE_TRANSFORM_CASE(F64);
     897      default: {
     898          char* typeStr;
     899          PS_TYPE_NAME(typeStr,type);
     900          psError(PS_ERR_BAD_PARAMETER_TYPE, true, _("Specified psImage type, %s, is not supported."),
     901                  typeStr);
     902          psFree(output);
     903          psFree(inPosition);
     904          return NULL;
     905      }
    952906    }
    953907
  • trunk/psLib/src/imageops/psImageGeomManip.h

    r12431 r12741  
    66 * @author Robert DeSonia, MHPCC
    77 *
    8  * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-03-14 00:39:50 $
     8 * @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-04-04 22:42:02 $
    1010 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1111 */
     
    1717
    1818#include "psImage.h"
     19#include "psImageInterpolate.h"
    1920#include "psCoord.h"
    2021#include "psStats.h"
     
    158159 *  coordinates in the input image of a pixel in the output image — note that
    159160 *  this is the reverse of what might be naively expected, but it is what is
    160  *  required in order to use psImagePixelInterpolate. If the pixels array is
     161 *  required in order to use psImageInterpolate. If the pixels array is
    161162 *  non-NULL, it shall consist of psPixelCoords, and only those pixels in the
    162163 *  output image shall be transformed; otherwise, the entire image is
  • trunk/psLib/src/imageops/psImagePixelExtract.c

    r12431 r12741  
    88 *  @author Robert DeSonia, MHPCC
    99 *
    10  *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2007-03-14 00:39:50 $
     10 *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2007-04-04 22:42:02 $
    1212 *
    1313 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2323#include "psMemory.h"
    2424#include "psVector.h"
     25#include "psError.h"
     26#include "psImage.h"
     27#include "psImageInterpolate.h"
    2528#include "psImagePixelExtract.h"
    26 #include "psError.h"
    27 
    28 
    2929
    3030#define VECTOR_STORE_ROW_CASE(TYPE) \
     
    679679    float dY = (endRow - startRow) / (float)(nSamples-1);
    680680
     681    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, input, NULL, mask, maskVal,
     682                                                                       0, 0, 0, 0, 0);
     683
    681684    #define LINEAR_CUT_CASE(TYPE) \
    682685case PS_TYPE_##TYPE: { \
     
    692695                cutRowsData[i] = y; \
    693696            } \
    694             outData[i] = psImagePixelInterpolate(input,x,y,mask,maskVal,0,mode); \
     697            double value; \
     698            if (!psImageInterpolate(&value, NULL, NULL, x, y, interp)) { \
     699                psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); \
     700                psFree(interp); \
     701                psFree(out); \
     702                return NULL; \
     703            } \
     704            outData[i] = value; \
    695705        } \
    696706    } \
     
    709719        LINEAR_CUT_CASE(F32);
    710720        LINEAR_CUT_CASE(F64);
    711 
    712     default: {
    713             char* typeStr;
    714             PS_TYPE_NAME(typeStr,input->type.type);
    715             psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    716                     _("Specified psImage type, %s, is not supported."),
    717                     typeStr);
    718             psFree(out);
    719             out = NULL;
    720         }
    721     }
     721      default: {
     722          char* typeStr;
     723          PS_TYPE_NAME(typeStr,input->type.type);
     724          psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     725                  _("Specified psImage type, %s, is not supported."),
     726                  typeStr);
     727          psFree(interp);
     728          psFree(out);
     729          out = NULL;
     730      }
     731    }
     732
     733    psFree(interp);
    722734
    723735    return out;
  • trunk/psLib/src/mathtypes/psImage.c

    r12527 r12741  
    99 *  @author Ross Harman, MHPCC
    1010 *
    11  *  @version $Revision: 1.127 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2007-03-22 00:11:08 $
     11 *  @version $Revision: 1.128 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2007-04-04 22:42:02 $
    1313 *
    1414 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    572572}
    573573
    574 double psImagePixelInterpolate(const psImage* input,
    575                                        float x,
    576                                        float y,
    577                                        const psImage* mask,
    578                                        psMaskType maskVal,
    579                                        double unexposedValue,
    580                                        psImageInterpolateMode mode)
    581 {
    582     PS_ASSERT_IMAGE_NON_NULL(input, unexposedValue);
    583 
    584     #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE)                             \
    585 case PS_TYPE_##TYPE:                                                 \
    586     switch (mode) {                                                  \
    587     case PS_INTERPOLATE_FLAT:                                        \
    588         return p_psImagePixelInterpolateFLAT_##TYPE(                 \
    589                 input,                                               \
    590                 x,                                                   \
    591                 y,                                                   \
    592                 mask,                                                \
    593                 maskVal,                                             \
    594                 unexposedValue);                                     \
    595         break;                                                       \
    596     case PS_INTERPOLATE_BILINEAR:                                    \
    597         return p_psImagePixelInterpolateBILINEAR_##TYPE(             \
    598                 input,                                               \
    599                 x,                                                   \
    600                 y,                                                   \
    601                 mask,                                                \
    602                 maskVal,                                             \
    603                 unexposedValue);                                     \
    604         break;                                                       \
    605     case PS_INTERPOLATE_BILINEAR_VARIANCE:                           \
    606         return p_psImagePixelInterpolateBILINEAR_VARIANCE_##TYPE(    \
    607                 input,                                               \
    608                 x,                                                   \
    609                 y,                                                   \
    610                 mask,                                                \
    611                 maskVal,                                             \
    612                 unexposedValue);                                     \
    613         break;                                                       \
    614     case PS_INTERPOLATE_BICUBE:                                      \
    615         return p_psImagePixelInterpolateBICUBE_##TYPE(             \
    616                 input,                                               \
    617                 x,                                                   \
    618                 y,                                                   \
    619                 mask,                                                \
    620                 maskVal,                                             \
    621                 unexposedValue);                                     \
    622         break;                                                       \
    623     default:                                                         \
    624         psError(PS_ERR_BAD_PARAMETER_VALUE,true,                     \
    625                 _("Specified interpolation method (%d) is not supported."),     \
    626                 mode);                                               \
    627     }                                                                \
    628     break;
    629 
    630     switch (input->type.type) {
    631         PSIMAGE_PIXEL_INTERPOLATE_CASE(U8);
    632         PSIMAGE_PIXEL_INTERPOLATE_CASE(U16);
    633         PSIMAGE_PIXEL_INTERPOLATE_CASE(U32);
    634         PSIMAGE_PIXEL_INTERPOLATE_CASE(U64);
    635         PSIMAGE_PIXEL_INTERPOLATE_CASE(S8);
    636         PSIMAGE_PIXEL_INTERPOLATE_CASE(S16);
    637         PSIMAGE_PIXEL_INTERPOLATE_CASE(S32);
    638         PSIMAGE_PIXEL_INTERPOLATE_CASE(S64);
    639         PSIMAGE_PIXEL_INTERPOLATE_CASE(F32);
    640         PSIMAGE_PIXEL_INTERPOLATE_CASE(F64);
    641     default: {
    642             char* typeStr;
    643             PS_TYPE_NAME(typeStr,input->type.type);
    644             psError(PS_ERR_BAD_PARAMETER_TYPE,true,
    645                     _("Specified psImage type, %s, is not supported."),
    646                     typeStr);
    647         }
    648     }
    649 
    650     return unexposedValue;
    651 }
    652574
    653575psF64 p_psImageGetElementF64(psImage* image,
     
    699621    }
    700622}
    701 
    702 #define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE,RETURNTYPE) \
    703 inline RETURNTYPE p_psImagePixelInterpolateFLAT_##TYPE( \
    704         const psImage* input, \
    705         float x, \
    706         float y, \
    707         const psImage* mask, \
    708         psMaskType maskVal, \
    709         RETURNTYPE unexposedValue) \
    710 { \
    711     psS32 intX = (psS32) round((psF64)(x) - 0.5 + FLT_EPSILON); \
    712     psS32 intY = (psS32) round((psF64)(y) - 0.5 + FLT_EPSILON); \
    713     psS32 lastX = input->numCols - 1; \
    714     psS32 lastY = input->numRows - 1; \
    715     \
    716     if ((intX < 0) || \
    717             (intX > lastX) || \
    718             (intY < 0) || \
    719             (intY > lastY) || \
    720             ( (mask!=NULL) && \
    721               ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
    722         return unexposedValue; \
    723     } \
    724     \
    725     return input->data.TYPE[intY][intX]; \
    726 }
    727 
    728 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8,psF64)
    729 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16,psF64)
    730 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32,psF64)
    731 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64,psF64)
    732 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8,psF64)
    733 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16,psF64)
    734 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32,psF64)
    735 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64,psF64)
    736 PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32,psF64)
    737 PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64,psF64)
    738 
    739 #define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE, RETURNTYPE, SUFFIX, FRACFUNC) \
    740 inline RETURNTYPE p_psImagePixelInterpolateBILINEAR_##SUFFIX( \
    741         const psImage* input, \
    742         float x, \
    743         float y, \
    744         const psImage* mask, \
    745         psMaskType maskVal, \
    746         RETURNTYPE unexposedValue) \
    747 { \
    748     int floorX = floor((x) - 0.5); \
    749     int floorY = floor((y) - 0.5); \
    750     float fracX = x - 0.5 - floorX; \
    751     float fracY = y - 0.5 - floorY; \
    752     int lastX = input->numCols - 1; \
    753     int lastY = input->numRows - 1; \
    754     ps##TYPE V00 = 0; \
    755     ps##TYPE V01 = 0; \
    756     ps##TYPE V10 = 0; \
    757     ps##TYPE V11 = 0; \
    758     bool valid00; \
    759     bool valid01; \
    760     bool valid10; \
    761     bool valid11; \
    762     \
    763     if (floorY >= 0 && floorY <= lastY) { \
    764         if (floorX >= 0 && floorX <= lastX) { \
    765             V00 = input->data.TYPE[floorY][floorX]; \
    766             valid00 = (mask == NULL) || \
    767                       ((mask->data.PS_TYPE_MASK_DATA[floorY][floorX] & maskVal) == 0); \
    768         } else { \
    769             valid00 = false; \
    770         } \
    771         if (floorX >= -1 && floorX < lastX) { \
    772             V10 = input->data.TYPE[floorY][floorX+1]; \
    773             valid10 = (mask == NULL) || \
    774                       ((mask->data.PS_TYPE_MASK_DATA[floorY][floorX+1] & maskVal) == 0); \
    775         } else { \
    776             valid10 = false; \
    777         } \
    778     } else { \
    779         valid00 = false; \
    780         valid10 = false; \
    781     } \
    782     if (floorY >= -1 && floorY < lastY) { \
    783         if (floorX >= 0 && floorX <= lastX) { \
    784             V01 = input->data.TYPE[floorY+1][floorX]; \
    785             valid01 = (mask == NULL) || \
    786                       ((mask->data.PS_TYPE_MASK_DATA[floorY+1][floorX] & maskVal) == 0); \
    787         } else { \
    788             valid01 = false; \
    789         } \
    790         if (floorX >= -1 && floorX < lastX) { \
    791             V11 = input->data.TYPE[floorY+1][floorX+1]; \
    792             valid11 = (mask == NULL) || \
    793                       ((mask->data.PS_TYPE_MASK_DATA[floorY+1][floorX+1] & maskVal) == 0); \
    794         } else { \
    795             valid11 = false; \
    796         } \
    797     } else { \
    798         valid01 = false; \
    799         valid11 = false; \
    800     } \
    801     \
    802     /* cover likely case of all pixels being valid more efficiently */  \
    803     if (valid00 && valid10 && valid01 && valid11) { \
    804         /* formula from the ADD */ \
    805         return V00*FRACFUNC((1.0-fracX)*(1.0-fracY)) + V10*FRACFUNC(fracX*(1.0-fracY)) + \
    806                V01*FRACFUNC(fracY*(1.0-fracX)) + V11*FRACFUNC(fracX*fracY); \
    807     } \
    808     \
    809     /* OK, at least one pixel is not valid - need to do it piecemeal */ \
    810     \
    811     RETURNTYPE V0 = 0.0; \
    812     bool valid0 = true; \
    813     if (valid00 && valid10) { \
    814         V0 = V00*FRACFUNC(1-fracX)+V10*FRACFUNC(fracX); \
    815     } else if (valid00) { \
    816         V0 = V00; \
    817     } else if (valid10) { \
    818         V0 = V10; \
    819     } else { \
    820         valid0 = false; \
    821     } \
    822     \
    823     RETURNTYPE V1 = 0.0; \
    824     bool valid1 = true; \
    825     if (valid01 && valid11) { \
    826         V1 = V01*FRACFUNC(1-fracX)+V11*FRACFUNC(fracX); \
    827     } else if (valid01) { \
    828         V1 = V01; \
    829     } else if (valid11) { \
    830         V1 = V11; \
    831     } else { \
    832         valid1 = false; \
    833     } \
    834     \
    835     if (valid0 && valid1) { \
    836         return V0*FRACFUNC(1-fracY) + V1*FRACFUNC(fracY); \
    837     } else if (valid0) { \
    838         return V0; \
    839     } else if (valid1) { \
    840         return V1; \
    841     } \
    842     \
    843     return unexposedValue; \
    844 }
    845 
    846 // XXX this would be much faster to use a 3x3 kernel to determine the shift
    847 // the same function can be used for all equivalent (kernel-based) shifts...
    848 #define PSIMAGE_PIXEL_INTERPOLATE_BICUBE(TYPE, RETURNTYPE, SUFFIX, FRACFUNC) \
    849 inline RETURNTYPE p_psImagePixelInterpolateBICUBE_##SUFFIX( \
    850         const psImage* input, \
    851         float x, \
    852         float y, \
    853         const psImage* mask, \
    854         psMaskType maskVal, \
    855         RETURNTYPE unexposedValue) \
    856 { \
    857     int floorX = floor(x); \
    858     int floorY = floor(y); \
    859     psF64 fracX = x - floorX - 0.5; \
    860     psF64 fracY = y - floorY - 0.5; \
    861     psS32 lastX = input->numCols - 1; \
    862     psS32 lastY = input->numRows - 1; \
    863     if (floorX < 1) return unexposedValue; \
    864     if (floorY < 1) return unexposedValue; \
    865     if (floorX >= lastX) return unexposedValue; \
    866     if (floorY >= lastY) return unexposedValue; \
    867     \
    868     /* XXX use care for masked and boundary pixels */ \
    869     psF64 Vmm = input->data.TYPE[floorY-1][floorX-1]; \
    870     psF64 Vom = input->data.TYPE[floorY-1][floorX+0]; \
    871     psF64 Vpm = input->data.TYPE[floorY-1][floorX+1]; \
    872     psF64 Vmo = input->data.TYPE[floorY+0][floorX-1]; \
    873     psF64 Voo = input->data.TYPE[floorY+0][floorX+0]; \
    874     psF64 Vpo = input->data.TYPE[floorY+0][floorX+1]; \
    875     psF64 Vmp = input->data.TYPE[floorY+1][floorX-1]; \
    876     psF64 Vop = input->data.TYPE[floorY+1][floorX+0]; \
    877     psF64 Vpp = input->data.TYPE[floorY+1][floorX+1]; \
    878     \
    879     psF64 Vxm = Vmm + Vmo + Vmp; \
    880     psF64 Vxp = Vpm + Vpo + Vpp; \
    881     psF64 Vym = Vmm + Vom + Vpm; \
    882     psF64 Vyp = Vmp + Vop + Vpp; \
    883     psF64 Vo  = Vym + Vyp + Vmo + Voo + Vpo; \
    884     \
    885     psF64 Z_00 = Vo*(5.0/9.0) - (Vxp + Vxm)/3.0 - (Vyp + Vym)/3.0; \
    886     \
    887     psF64 Z_10 = (Vxp - Vxm)/6.0; \
    888     psF64 Z_01 = (Vyp - Vym)/6.0; \
    889     psF64 Z_20 = (Vxp + Vxm)/2.0 - Vo/3.0; \
    890     psF64 Z_02 = (Vyp + Vym)/2.0 - Vo/3.0; \
    891     psF64 Z_11 = (Vpp + Vmm - Vpm - Vmp)/4.0; \
    892     \
    893     psF64 value = Z_00 + Z_10*fracX + Z_01*fracY + Z_20*fracX*fracX + Z_11*fracX*fracY + Z_02*fracY*fracY; \
    894     return value; \
    895 }
    896 
    897 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,U8,)
    898 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,U16,)
    899 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,U32,)
    900 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,U64,)
    901 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,S8,)
    902 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,S16,)
    903 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,S32,)
    904 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,S64,)
    905 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,F32,)
    906 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,F64,)
    907 
    908 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U8,psF64,U8,)
    909 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U16,psF64,U16,)
    910 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U32,psF64,U32,)
    911 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U64,psF64,U64,)
    912 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S8,psF64,S8,)
    913 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S16,psF64,S16,)
    914 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S32,psF64,S32,)
    915 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S64,psF64,S64,)
    916 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(F32,psF64,F32,)
    917 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(F64,psF64,F64,)
    918 
    919 // Variance Version
    920 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,VARIANCE_U8,PS_SQR)
    921 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,VARIANCE_U16,PS_SQR)
    922 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,VARIANCE_U32,PS_SQR)
    923 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,VARIANCE_U64,PS_SQR)
    924 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,VARIANCE_S8,PS_SQR)
    925 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,VARIANCE_S16,PS_SQR)
    926 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,VARIANCE_S32,PS_SQR)
    927 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,VARIANCE_S64,PS_SQR)
    928 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,VARIANCE_F32,PS_SQR)
    929 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,VARIANCE_F64,PS_SQR)
    930 
    931 psImageInterpolateMode psImageInterpolateModeFromString (char *name) {
    932 
    933     if (!strcasecmp(name, "FLAT"))              return PS_INTERPOLATE_FLAT;
    934     if (!strcasecmp(name, "BILINEAR"))          return PS_INTERPOLATE_BILINEAR;
    935     if (!strcasecmp(name, "BICUBE"))            return PS_INTERPOLATE_BICUBE;
    936     if (!strcasecmp(name, "GAUSS"))             return PS_INTERPOLATE_GAUSS;
    937     if (!strcasecmp(name, "LANCZOS2"))          return PS_INTERPOLATE_LANCZOS2;
    938     if (!strcasecmp(name, "LANCZOS3"))          return PS_INTERPOLATE_LANCZOS3;
    939     if (!strcasecmp(name, "LANCZOS4"))          return PS_INTERPOLATE_LANCZOS4;
    940     if (!strcasecmp(name, "BILINEAR_VARIANCE")) return PS_INTERPOLATE_BILINEAR_VARIANCE;
    941     if (!strcasecmp(name, "LANCZOS2_VARIANCE")) return PS_INTERPOLATE_LANCZOS2_VARIANCE;
    942     if (!strcasecmp(name, "LANCZOS3_VARIANCE")) return PS_INTERPOLATE_LANCZOS3_VARIANCE;
    943     if (!strcasecmp(name, "LANCZOS4_VARIANCE")) return PS_INTERPOLATE_LANCZOS4_VARIANCE;
    944 
    945     psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Unknown interpolate type %s"), name);
    946     return PS_INTERPOLATE_NONE;
    947 }
  • trunk/psLib/src/mathtypes/psImage.h

    r12527 r12741  
    99 * @author Joshua Hoblitt, University of Hawaii
    1010 *
    11  * @version $Revision: 1.91 $ $Name: not supported by cvs2svn $
    12  * @date $Date: 2007-03-22 00:11:08 $
     11 * @version $Revision: 1.92 $ $Name: not supported by cvs2svn $
     12 * @date $Date: 2007-04-04 22:42:02 $
    1313 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1414 */
     
    2424#include "psArray.h"
    2525#include "psConstants.h"
    26 
    27 /** enumeration of options in interpolation
    28  *
    29  */
    30 typedef enum {
    31     PS_INTERPOLATE_NONE,               ///< no interpolate defined (error state)
    32     PS_INTERPOLATE_FLAT,               ///< 'flat' interpolation (nearest pixel)
    33     PS_INTERPOLATE_BILINEAR,           ///< bi-linear interpolation
    34     PS_INTERPOLATE_BICUBE,             ///< bi-cubic interpolation with 3x3 region (EAM)
    35     PS_INTERPOLATE_GAUSS,              ///< bi-cubic interpolation with 3x3 region (EAM)
    36     PS_INTERPOLATE_LANCZOS2,           ///< Sinc interpolation with 4x4 pixel kernel
    37     PS_INTERPOLATE_LANCZOS3,           ///< Sinc interpolation with 6x6 pixel kernel
    38     PS_INTERPOLATE_LANCZOS4,           ///< Sinc interpolation with 8x8 pixel kernel
    39     PS_INTERPOLATE_BILINEAR_VARIANCE,  ///< Variance version of PS_INTERPOLATE_BILINEAR
    40     PS_INTERPOLATE_LANCZOS2_VARIANCE,  ///< Variance version of PS_INTERPOLATE_LANCZOS2
    41     PS_INTERPOLATE_LANCZOS3_VARIANCE,  ///< Variance version of PS_INTERPOLATE_LANCZOS3
    42     PS_INTERPOLATE_LANCZOS4_VARIANCE   ///< Variance version of PS_INTERPOLATE_LANCZOS4
    43     //    PS_INTERPOLATE_NUM_MODES           ///< enum end-marker; does not coorespond to a interpolation mode
    44 } psImageInterpolateMode;
    4526
    4627
     
    226207
    227208
    228 /** Interpolate image pixel value given floating point coordinates.
    229  *
    230  *  @return double    Pixel value interpolated from image or unexposedValue if
    231  *                   given x,y doesn't coorespond to a valid image location
    232  */
    233 double psImagePixelInterpolate(
    234     const psImage* input,              ///< input image for interpolation
    235     float x,                           ///< column location to derive value of
    236     float y,                           ///< row location ot derive value of
    237     const psImage* mask,               ///< if not NULL, the mask of the input image
    238     psMaskType maskVal,                ///< the mask value
    239     double unexposedValue,             ///< return value if x,y location is not in image.
    240     psImageInterpolateMode mode        ///< interpolation mode
    241 );
    242 
    243 // return the mode equivalent to a char string name
    244 psImageInterpolateMode psImageInterpolateModeFromString (char *name);
    245 
    246 
    247 #define PIXEL_INTERPOLATE_FCN_PROTOTYPE(SUFFIX, RETURNTYPE) \
    248 inline RETURNTYPE p_psImagePixelInterpolate##SUFFIX( \
    249         const psImage* input,          /**< input image for interpolation */ \
    250         float x,                       /**< column location to derive value of */ \
    251         float y,                       /**< row location ot derive value of */ \
    252         const psImage* mask,           /**< if not NULL, the mask of the input image */ \
    253         psMaskType maskVal,            /**< the mask value */ \
    254         RETURNTYPE unexposedValue      /**< return value if x,y location is not in image. */ \
    255                                                    );
    256 
    257 #define PIXEL_INTERPOLATE_FCNS(MODE) \
    258 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U8,psF64)  \
    259 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U16,psF64) \
    260 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U32,psF64) \
    261 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U64,psF64) \
    262 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S8,psF64)  \
    263 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S16,psF64) \
    264 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S32,psF64) \
    265 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S64,psF64) \
    266 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_F32,psF64) \
    267 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_F64,psF64)
    268 
    269 #ifndef SWIG
    270 PIXEL_INTERPOLATE_FCNS(FLAT)
    271 PIXEL_INTERPOLATE_FCNS(BILINEAR)
    272 PIXEL_INTERPOLATE_FCNS(BILINEAR_VARIANCE)
    273 PIXEL_INTERPOLATE_FCNS(BICUBE)
    274 #endif // ! SWIG
    275 
    276 #undef PIXEL_INTERPOLATE_FCN_PROTOTYPE
    277 #undef PIXEL_INTERPOLATE_FCNS
     209
    278210
    279211/*****************************************************************************
  • trunk/psLib/src/pslib_strict.h

    r12588 r12741  
    99*  @author Eric Van Alst, MHPCC
    1010*
    11 *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
    12 *  @date $Date: 2007-03-27 02:43:22 $
     11*  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2007-04-04 22:42:02 $
    1313*
    1414*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    4444
    4545#include "psRegion.h"
     46#include "psImageInterpolate.h"
    4647#include "psImageConvolve.h"
    4748#include "psImageGeomManip.h"
  • trunk/psLib/test/mathtypes/tap_psImageInterpolate.c

    r12607 r12741  
    88int main (void)
    99{
    10     plan_tests(47);
     10    plan_tests(88);
    1111
    1212//    diag("psImageInterpolate() tests");
     
    1919
    2020        // generate simple image (x ramp)
    21         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
    22         ok(image != NULL, "psImage successfully allocated");
    23         skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
    24 
    25         image->data.F32[10][10] = 1;
    26 
    27         // center of pixels is 0.5, 0.5
    28         float value;
    29 
    30         value = psImagePixelInterpolate (image, 10.5, 10.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    31         is_float (value, 1.0, "pixel center value - %f", value);
     21        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
     22        ok(image != NULL, "psImage successfully allocated");
     23        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     24
     25        psImageInit(image, 0.0);
     26        image->data.F64[10][10] = 1;
     27
     28        // center of pixels is 0.5, 0.5
     29        double value;
     30
     31        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BILINEAR,
     32                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     33                                                                           0, 0, 0.0);
     34        ok(interp, "Interpolation options set");
     35
     36        ok(psImageInterpolate(&value, NULL, NULL, 10.5, 10.5, interp), "Interpolation");
     37        is_double (value, 1.0, "pixel center value - %f", value);
    3238
    3339//        diag ("why do I need to have tolerances of 4epsilon or so??");
    34         value = psImagePixelInterpolate (image, 10.9, 10.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    35         is_float_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
    36 
    37         value = psImagePixelInterpolate (image, 10.5, 10.9, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    38         is_float_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
    39 
    40         value = psImagePixelInterpolate (image, 10.1, 10.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    41         is_float_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
     40
     41        ok(psImageInterpolate(&value, NULL, NULL, 10.9, 10.5, interp), "Interpolation");
     42        is_double_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
     43
     44        ok(psImageInterpolate(&value, NULL, NULL, 10.5, 10.9, interp), "Interpolation");
     45        is_double_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
     46
     47        ok(psImageInterpolate(&value, NULL, NULL, 10.1, 10.5, interp), "Interpolation");
     48        is_double_tol (value, 0.6, 4.0*FLT_EPSILON, "pixel value - %.20f", value);
     49
     50        psFree(interp);
    4251
    4352        skip_end();
     
    5463
    5564        // generate simple image (x ramp)
    56         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
     65        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
     66        ok(image != NULL, "psImage successfully allocated");
     67        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     68
     69        for (int j = 0; j < image->numRows; j++) {
     70            for (int i = 0; i < image->numCols; i++) {
     71                image->data.F64[j][i] = i + 0.5;
     72            }
     73        }
     74
     75        // center of pixels is 0.5, 0.5
     76        double value;
     77
     78        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BILINEAR,
     79                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     80                                                                           0, 0, 0.0);
     81        ok(interp, "Interpolation options set");
     82
     83        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.5, interp), "Interpolation");
     84        is_double_tol (value, 2.5, 5.0e-8, "pixel center value - %f", value);
     85
     86        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.5, interp), "Interpolation");
     87        is_double_tol (value, 2.2, 5.0e-8, "coord: 2.2, 2.5, value: %f", value);
     88
     89        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.5, interp), "Interpolation");
     90        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     91
     92        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.2, interp), "Interpolation");
     93        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     94
     95        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.8, interp), "Interpolation");
     96        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     97
     98        ok(psImageInterpolate(&value, NULL, NULL, 0.8, 2.8, interp), "Interpolation");
     99        is_double_tol (value, 0.8, 5.0e-8, "coord: 0.8, value: %f", value);
     100
     101        // no extrapolation
     102        ok(psImageInterpolate(&value, NULL, NULL, 0.3, 2.8, interp), "Interpolation");
     103        is_double (value, 0.0, "coord: 0.3, value: %f", value);
     104
     105        ok(psImageInterpolate(&value, NULL, NULL, -0.2, 2.8, interp), "Interpolation");
     106        is_double (value, 0.0, "coord: -0.2, value: %f", value);
     107
     108        psFree(interp);
     109
     110        skip_end();
     111
     112        psFree(image);
     113        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     114    }
     115
     116    // very simple tests: no mask, bilinear mode, yramp image only
     117    {
     118        psMemId id = psMemGetId();
     119
     120//        diag ("interpolate a y-ramp: ");
     121
     122        // generate simple image (y ramp)
     123        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
    57124        ok(image != NULL, "psImage successfully allocated");
    58125        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     
    61128        {
    62129            for (int i = 0; i < image->numCols; i++) {
    63                 image->data.F32[j][i] = i + 0.5;
    64             }
    65         }
    66 
    67         // center of pixels is 0.5, 0.5
    68         float value;
    69 
    70         value = psImagePixelInterpolate (image, 2.5, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    71         is_float (value, 2.5, "pixel center value - %f", value);
    72 
    73         value = psImagePixelInterpolate (image, 2.2, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    74         is_float (value, 2.2, "coord: 2.2, 2.5, value: %f", value);
    75 
    76         value = psImagePixelInterpolate (image, 2.8, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    77         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    78 
    79         value = psImagePixelInterpolate (image, 2.8, 2.2, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    80         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    81 
    82         value = psImagePixelInterpolate (image, 2.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    83         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    84 
    85         value = psImagePixelInterpolate (image, 0.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    86         is_float (value, 0.8, "coord: 0.8, value: %f", value);
    87 
    88         // no extrapolation
    89         value = psImagePixelInterpolate (image, 0.3, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    90         is_float (value, 0.5, "coord: 0.3, value: %f", value);
    91 
    92         value = psImagePixelInterpolate (image, -0.2, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    93         is_float (value, 0.5, "coord: -0.2, value: %f", value);
    94 
    95         skip_end();
    96 
    97         psFree(image);
    98         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    99     }
    100 
    101     // very simple tests: no mask, bilinear mode, yramp image only
    102     {
    103         psMemId id = psMemGetId();
    104 
    105 //        diag ("interpolate a y-ramp: ");
    106 
    107         // generate simple image (y ramp)
    108         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
     130                image->data.F64[j][i] = j + 0.5;
     131            }
     132        }
     133
     134        // center of pixels is 0.5, 0.5
     135        double value;
     136
     137        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BILINEAR,
     138                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     139                                                                           0, 0, 0.0);
     140        ok(interp, "Interpolation options set");
     141
     142        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.5, interp), "Interpolation");
     143        is_double_tol (value, 2.5, 5.0e-8, "pixel center value - %f", value);
     144
     145        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.2, interp), "Interpolation");
     146        is_double_tol (value, 2.2, 5.0e-8, "coord: 2.2, 2.2, value: %f", value);
     147
     148        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.8, interp), "Interpolation");
     149        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     150
     151        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.8, interp), "Interpolation");
     152        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     153
     154        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.8, interp), "Interpolation");
     155        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     156
     157        psFree(interp);
     158
     159        skip_end();
     160
     161        psFree(image);
     162        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     163    }
     164
     165    // very simple tests: no mask, bicube mode, xramp image only
     166    {
     167        psMemId id = psMemGetId();
     168
     169//        diag ("interpolate an x-ramp (bicube)");
     170
     171        // generate simple image (x ramp)
     172        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
    109173        ok(image != NULL, "psImage successfully allocated");
    110174        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     
    113177        {
    114178            for (int i = 0; i < image->numCols; i++) {
    115                 image->data.F32[j][i] = j + 0.5;
    116             }
    117         }
    118 
    119         // center of pixels is 0.5, 0.5
    120         float value;
    121 
    122         value = psImagePixelInterpolate (image, 2.5, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    123         is_float (value, 2.5, "pixel center value - %f", value);
    124 
    125         value = psImagePixelInterpolate (image, 2.2, 2.2, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    126         is_float (value, 2.2, "coord: 2.2, 2.5, value: %f", value);
    127 
    128         value = psImagePixelInterpolate (image, 2.5, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    129         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    130 
    131         value = psImagePixelInterpolate (image, 2.2, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    132         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    133 
    134         value = psImagePixelInterpolate (image, 2.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
    135         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    136 
    137         skip_end();
    138 
    139         psFree(image);
    140         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    141     }
    142 
    143     // very simple tests: no mask, bicube mode, xramp image only
    144     {
    145         psMemId id = psMemGetId();
    146 
    147 //        diag ("interpolate an x-ramp (bicube)");
    148 
    149         // generate simple image (x ramp)
    150         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
     179                image->data.F64[j][i] = i + 0.5;
     180            }
     181        }
     182
     183        // center of pixels is 0.5, 0.5
     184        double value;
     185
     186        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BICUBE,
     187                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     188                                                                           0, 0, 0.0);
     189        ok(interp, "Interpolation options set");
     190
     191        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.5, interp), "Interpolation");
     192        is_double_tol (value, 2.5, 5.0e-8, "coord; 2.5, 2.5, value - %f", value);
     193
     194        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.5, interp), "Interpolation");
     195        is_double_tol (value, 2.2, 5.0e-8, "coord: 2.2, 2.5, value: %f", value);
     196
     197        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.5, interp), "Interpolation");
     198        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, 2.5, value: %f", value);
     199
     200        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.2, interp), "Interpolation");
     201        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, 2.2, value: %f", value);
     202
     203        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.8, interp), "Interpolation");
     204        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, 2.8, value: %f", value);
     205
     206//        diag ("coords outside of nominal range (1 < x < Nx - 2) return 'uncover'");
     207
     208        // no extrapolation: these return the 'uncover' value
     209        ok(psImageInterpolate(&value, NULL, NULL, 0.8, 2.8, interp), "Interpolation");
     210        is_double (value, 0.0, "coord: 0.8, 2.8, value: %f", value);
     211
     212        ok(psImageInterpolate(&value, NULL, NULL, 0.3, 2.8, interp), "Interpolation");
     213        is_double (value, 0.0, "coord: 0.3, 2.8, value: %f", value);
     214
     215        ok(psImageInterpolate(&value, NULL, NULL, -0.2, 2.8, interp), "Interpolation");
     216        is_double (value, 0.0, "coord: -0.2, 2.8, value: %f", value);
     217
     218        psFree(interp);
     219
     220        skip_end();
     221
     222        psFree(image);
     223        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     224    }
     225
     226    // very simple tests: no mask, bilinear mode, yramp image only
     227    {
     228        psMemId id = psMemGetId();
     229
     230//        diag ("interpolate a y-ramp (bicube)");
     231
     232        // generate simple image (y ramp)
     233        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
    151234        ok(image != NULL, "psImage successfully allocated");
    152235        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     
    155238        {
    156239            for (int i = 0; i < image->numCols; i++) {
    157                 image->data.F32[j][i] = i + 0.5;
    158             }
    159         }
    160 
    161         // center of pixels is 0.5, 0.5
    162         float value;
    163 
    164         value = psImagePixelInterpolate (image, 2.5, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    165         is_float (value, 2.5, "coord; 2.5, 2.5, value - %f", value);
    166 
    167         value = psImagePixelInterpolate (image, 2.2, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    168         is_float (value, 2.2, "coord: 2.2, 2.5, value: %f", value);
    169 
    170         value = psImagePixelInterpolate (image, 2.8, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    171         is_float (value, 2.8, "coord: 2.8, 2.5, value: %f", value);
    172 
    173         value = psImagePixelInterpolate (image, 2.8, 2.2, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    174         is_float (value, 2.8, "coord: 2.8, 2.2, value: %f", value);
    175 
    176         value = psImagePixelInterpolate (image, 2.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    177         is_float (value, 2.8, "coord: 2.8, 2.8, value: %f", value);
    178 
    179 //        diag ("coords outside of nominal range (1 < x < Nx - 2) return 'uncover'");
    180 
    181         // no extrapolation: these return the 'uncover' value
    182         value = psImagePixelInterpolate (image, 0.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    183         is_float (value, 0.0, "coord: 0.8, 2.8, value: %f", value);
    184 
    185         value = psImagePixelInterpolate (image, 0.3, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    186         is_float (value, 0.0, "coord: 0.3, 2.8, value: %f", value);
    187 
    188         value = psImagePixelInterpolate (image, -0.2, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    189         is_float (value, 0.0, "coord: -0.2, 2.8, value: %f", value);
    190 
    191         skip_end();
    192 
    193         psFree(image);
    194         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    195     }
    196 
    197     // very simple tests: no mask, bilinear mode, yramp image only
    198     {
    199         psMemId id = psMemGetId();
    200 
    201 //        diag ("interpolate a y-ramp (bicube)");
    202 
    203         // generate simple image (y ramp)
    204         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
     240                image->data.F64[j][i] = j + 0.5;
     241            }
     242        }
     243
     244        // center of pixels is 0.5, 0.5
     245        double value;
     246
     247        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BICUBE,
     248                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     249                                                                           0, 0, 0.0);
     250        ok(interp, "Interpolation options set");
     251
     252        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.5, interp), "Interpolation");
     253        is_double_tol (value, 2.5, 5.0e-8, "pixel center value - %f", value);
     254
     255        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.2, interp), "Interpolation");
     256        is_double_tol (value, 2.2, 5.0e-8, "coord: 2.2, 2.5, value: %f", value);
     257
     258        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.8, interp), "Interpolation");
     259        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     260
     261        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.8, interp), "Interpolation");
     262        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     263
     264        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.8, interp), "Interpolation");
     265        is_double_tol (value, 2.8, 5.0e-8, "coord: 2.8, value: %f", value);
     266
     267        psFree(interp);
     268
     269        skip_end();
     270
     271        psFree(image);
     272        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     273    }
     274
     275    // very simple tests: no mask, bilinear mode, x,y 2nd order shape
     276    {
     277        psMemId id = psMemGetId();
     278
     279//        diag ("interpolate a quadratic shape (bicube)");
     280
     281        // generate simple image (x ramp)
     282        psImage *image = psImageAlloc(32, 32, PS_TYPE_F64);
    205283        ok(image != NULL, "psImage successfully allocated");
    206284        skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
     
    209287        {
    210288            for (int i = 0; i < image->numCols; i++) {
    211                 image->data.F32[j][i] = j + 0.5;
    212             }
    213         }
    214 
    215         // center of pixels is 0.5, 0.5
    216         float value;
    217 
    218         value = psImagePixelInterpolate (image, 2.5, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    219         is_float (value, 2.5, "pixel center value - %f", value);
    220 
    221         value = psImagePixelInterpolate (image, 2.2, 2.2, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    222         is_float (value, 2.2, "coord: 2.2, 2.5, value: %f", value);
    223 
    224         value = psImagePixelInterpolate (image, 2.5, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    225         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    226 
    227         value = psImagePixelInterpolate (image, 2.2, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    228         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    229 
    230         value = psImagePixelInterpolate (image, 2.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    231         is_float (value, 2.8, "coord: 2.8, value: %f", value);
    232 
    233         skip_end();
    234 
    235         psFree(image);
    236         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    237     }
    238 
    239     // very simple tests: no mask, bilinear mode, x,y 2nd order shape
    240     {
    241         psMemId id = psMemGetId();
    242 
    243 //        diag ("interpolate a quadratic shape (bicube)");
    244 
    245         // generate simple image (x ramp)
    246         psImage *image = psImageAlloc(32, 32, PS_TYPE_F32);
    247         ok(image != NULL, "psImage successfully allocated");
    248         skip_start(image == NULL, 5, "Skipping tests because psImageAlloc() failed");
    249 
    250         for (int j = 0; j < image->numRows; j++)
    251         {
    252             for (int i = 0; i < image->numCols; i++) {
    253                 image->data.F32[j][i] = 0.25*PS_SQR(i + 0.5) + j + 0.5;
    254             }
    255         }
    256 
    257         // center of pixels is 0.5, 0.5
    258         float value;
    259 
    260         value = psImagePixelInterpolate (image, 2.5, 2.5, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    261         is_float (value, 4.0625, "pixel center value - %f", value);
    262 
    263         value = psImagePixelInterpolate (image, 2.2, 2.2, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    264         is_float (value, 3.41, "coord: 2.2, 2.5, value: %f", value);
    265 
    266         value = psImagePixelInterpolate (image, 2.5, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    267         is_float (value, 4.3625002, "coord: 2.5, 2.8, value: %f", value);
    268 
    269         value = psImagePixelInterpolate (image, 2.2, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    270         is_float (value, 4.010000229, "coord: 2.2, 2.8, value: %f", value);
    271 
    272         value = psImagePixelInterpolate (image, 2.8, 2.8, NULL, 0, 0.0, PS_INTERPOLATE_BICUBE);
    273         is_float (value, 4.75999975, "coord: 2.8, 2.8, value: %f", value);
     289                image->data.F64[j][i] = 0.25*PS_SQR(i + 0.5) + j + 0.5;
     290            }
     291        }
     292
     293        // center of pixels is 0.5, 0.5
     294        double value;
     295
     296        psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BICUBE,
     297                                                                           image, NULL, NULL, 0, 0.0, 0.0,
     298                                                                           0, 0, 0.0);
     299        ok(interp, "Interpolation options set");
     300
     301        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.5, interp), "Interpolation");
     302        is_double_tol (value, 4.0625, 2.0e-7, "pixel center value - %f", value);
     303
     304        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.2, interp), "Interpolation");
     305        is_double_tol (value, 3.41, 2.0e-7, "coord: 2.2, 2.5, value: %f", value);
     306
     307        ok(psImageInterpolate(&value, NULL, NULL, 2.5, 2.8, interp), "Interpolation");
     308        is_double_tol (value, 4.3625, 2.0e-7, "coord: 2.5, 2.8, value: %f", value);
     309
     310        ok(psImageInterpolate(&value, NULL, NULL, 2.2, 2.8, interp), "Interpolation");
     311        is_double_tol (value, 4.01, 2.0e-7, "coord: 2.2, 2.8, value: %f", value);
     312
     313        ok(psImageInterpolate(&value, NULL, NULL, 2.8, 2.8, interp), "Interpolation");
     314        is_double_tol (value, 4.76, 2.0e-7, "coord: 2.8, 2.8, value: %f", value);
     315
     316        psFree(interp);
    274317
    275318        skip_end();
Note: See TracChangeset for help on using the changeset viewer.