IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 21, 2004, 1:39:48 PM (22 years ago)
Author:
desonia
Message:

Beefed up the psImageInterpolate function to support all real types and various methods.

File:
1 edited

Legend:

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

    r1234 r1251  
    1313#include "psImage.h"
    1414#include "psFunctions.h"
    15 #include "float.h"
    16 #include <math.h>
     15#include "psImageStats.h"
    1716
    1817/// This routine must determine the various statistics for the image.
     
    377376linear interpolation is performed on the image.
    378377 *****************************************************************************/
    379 float psImagePixelInterpolation(psImage *input,
    380                                 float x,
    381                                 float y)
    382 {
    383     float floorX = 0.0;
    384     float floorY = 0.0;
    385     float fracX = 0.0;
    386     float fracY = 0.0;
    387     int intFloorX = 0;
    388     int intFloorY = 0;
    389     float x1 = 0.0;
    390     float x2 = 0.0;
    391     float pixel = 0.0;
    392 
    393     if ((x < 0.0) ||
    394             (x > ((float) input->numRows-1)) ||
    395             (y < 0.0) ||
    396             (y > ((float) input->numCols-1))) {
    397         psAbort(__func__,
    398                 "Fractional coordinates (%f %f) outside image range.", x, y);
    399     }
    400 
    401     floorX = floorf(x);
    402     intFloorX = (int) floorX;
    403     fracX = x - floorX;
    404 
    405     floorY = floorf(y);
    406     intFloorY = (int) floorY;
    407     fracY = y - floorY;
    408 
    409     if (intFloorX == (input->numRows-1)) {
    410         pixel = input->data.F32[intFloorX][intFloorY];
    411         if (intFloorY < (input->numCols-1)) {
    412             pixel+= fracY * (input->data.F32[intFloorX][intFloorY+1] -
    413                              input->data.F32[intFloorX][intFloorY]);
    414         }
    415         return(pixel);
    416     } else if (intFloorX == (input->numCols-1)) {
    417         if (intFloorX < (input->numRows-1)) {
    418             pixel+= fracX * (input->data.F32[intFloorX+1][intFloorY] -
    419                              input->data.F32[intFloorX][intFloorY]);
    420         }
    421         return(pixel);
    422     }
    423 
    424 
    425     x1 = input->data.F32[intFloorX][intFloorY];
    426     x1+= fracY * (input->data.F32[intFloorX][intFloorY+1] -
    427                   input->data.F32[intFloorX][intFloorY]);
    428 
    429     x2 = input->data.F32[intFloorX+1][intFloorY];
    430     x2+= fracY * (input->data.F32[intFloorX+1][intFloorY+1] -
    431                   input->data.F32[intFloorX+1][intFloorY]);
    432     pixel = x1;
    433     pixel+= fracX * (x2 - x1);
    434 
    435     return(pixel);
    436 }
    437 
    438 
    439 
    440 
     378psF32 psImagePixelInterpolate(
     379    const psImage *input,
     380    float x,
     381    float y,
     382    psF32 unexposedValue,
     383    psImageInterpolateMode mode)
     384{
     385
     386    if (input == NULL) {
     387        psError(__func__,"Image can not be NULL.");
     388        return unexposedValue;
     389    }
     390
     391    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE) \
     392case PS_TYPE_##TYPE: \
     393    switch (mode) { \
     394    case PS_INTERPOLATE_FLAT: \
     395        return p_psImagePixelInterpolateFLAT_##TYPE(input,x,y,unexposedValue); \
     396        break; \
     397    case PS_INTERPOLATE_BILINEAR: \
     398        return p_psImagePixelInterpolateBILINEAR_##TYPE(input,x,y,unexposedValue); \
     399        break; \
     400    default: \
     401        psError(__func__,"Unsupported interpolation mode (#%d)",mode); \
     402        return unexposedValue; \
     403    } \
     404    break
     405
     406    switch (input->type.type) {
     407        PSIMAGE_PIXEL_INTERPOLATE_CASE(F32);
     408    default:
     409        psError(__func__,"Unsupported image datatype (%d)",input->type.type);
     410    }
     411
     412    return unexposedValue;
     413}
     414
     415#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE) \
     416inline psF64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage *input, \
     417        float x, \
     418        float y, \
     419        psF64 unexposedValue) \
     420{ \
     421    int intX = (int) round((psF64)(x) - 0.5); \
     422    int intY = (int) round((psF64)(y) - 0.5); \
     423    int lastX = input->numCols - 1; \
     424    int lastY = input->numRows - 1; \
     425    \
     426    if ((intX < 0) || \
     427            (intX > lastX) || \
     428            (intY < 0) || \
     429            (intY > lastY)) { \
     430        return unexposedValue; \
     431    } \
     432    \
     433    return input->data.TYPE[intY][intX]; \
     434}
     435
     436PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8)
     437PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16)
     438PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32)
     439PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64)
     440PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8)
     441PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16)
     442PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32)
     443PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64)
     444PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32)
     445PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64)
     446
     447#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE) \
     448inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage *input, \
     449        float x, \
     450        float y, \
     451        psF64 unexposedValue) \
     452{ \
     453    double floorX = floor((psF64)(x) - 0.5); \
     454    double floorY = floor((psF64)(y) - 0.5); \
     455    double fracX = x - 0.5 - floorX; \
     456    double fracY = y - 0.5 - floorY; \
     457    int intFloorX = (int) floorX; \
     458    int intFloorY = (int) floorY; \
     459    int lastX = input->numCols - 1; \
     460    int lastY = input->numRows - 1; \
     461    double rx = 0.0; \
     462    psF64 pixel = 0.0; \
     463    ps##TYPE* currentRow; \
     464    ps##TYPE* nextRow; \
     465    \
     466    if ((intFloorX < 0) || \
     467            (intFloorX > lastX) || \
     468            (intFloorY < 0) || \
     469            (intFloorY > lastY)) { \
     470        return unexposedValue; \
     471    } \
     472    \
     473    currentRow = input->data.TYPE[intFloorY]; \
     474    if (intFloorY == lastY) { \
     475        pixel = currentRow[intFloorX]; \
     476        if (intFloorX < lastX) { \
     477            pixel+= fracY * ((psF64)currentRow[intFloorX+1] - \
     478                             (psF64)currentRow[intFloorX]); \
     479        } \
     480        return(pixel); \
     481    } \
     482    nextRow = input->data.TYPE[intFloorY+1]; \
     483    if (intFloorX == lastX) { \
     484        pixel = currentRow[intFloorX]; \
     485        if (intFloorY < lastY) { \
     486            pixel+= fracX * ((psF64)nextRow[intFloorX] - \
     487                             (psF64)currentRow[intFloorX]); \
     488        } \
     489        return(pixel); \
     490    } \
     491    \
     492    rx = currentRow[intFloorX] + \
     493         fracX * ((psF64)currentRow[intFloorX+1] - \
     494                  (psF64)currentRow[intFloorX]); \
     495    \
     496    pixel = rx + fracY * ((psF64)nextRow[intFloorX] + \
     497                          fracX * ((psF64)nextRow[intFloorX+1] - \
     498                                   (psF64)nextRow[intFloorX]) - rx); \
     499    \
     500    return(pixel); \
     501}
     502
     503PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8)
     504PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16)
     505PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32)
     506PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64)
     507PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8)
     508PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16)
     509PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32)
     510PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64)
     511PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32)
     512PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64)
     513
Note: See TracChangeset for help on using the changeset viewer.