/* @file  psImageInterpolate.h
 * @brief Functions for interpolating an image
 *
 * @author Robert DeSonia, MHPCC
 * @author Ross Harman, MHPCC
 * @author Joshua Hoblitt, University of Hawaii
 * @author Paul Price, Institute for Astronomy
 *
 * @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
 * @date $Date: 2007-04-04 22:42:02 $
 * Copyright 2004-2007 Institute for Astronomy, University of Hawaii
 */

#ifndef PS_IMAGE_PIXEL_INTERPOLATE_H
#define PS_IMAGE_PIXEL_INTERPOLATE_H


/// Enumeration of options in interpolation
typedef enum {
    PS_INTERPOLATE_NONE,               ///< no interpolate defined (error state)
    PS_INTERPOLATE_FLAT,               ///< Flat interpolation (nearest pixel)
    PS_INTERPOLATE_BILINEAR,           ///< Bilinear interpolation
    PS_INTERPOLATE_BICUBE,             ///< Bicubic interpolation with 3x3 region
    PS_INTERPOLATE_GAUSS,              ///< Gaussian inteprolation with 3x3 region
    PS_INTERPOLATE_LANCZOS2,           ///< Sinc interpolation with 4x4 pixel kernel
    PS_INTERPOLATE_LANCZOS3,           ///< Sinc interpolation with 6x6 pixel kernel
    PS_INTERPOLATE_LANCZOS4,           ///< Sinc interpolation with 8x8 pixel kernel
} psImageInterpolateMode;


/// Options for general interpolation.
///
/// We stuff in here all the constant values when doing interpolation, so that not all of it has to be pushed
/// onto the stack in the middle of a tight loop.  For this reason, even the image, mask and variance map are
/// included.
typedef struct {
    psImageInterpolateMode mode;        // Interpolation mode
    const psImage *image;               // Input image for interpolation
    const psImage *variance;            // Variance image for interpolation
    const psImage *mask;                // Mask image for interpolation
    psMaskType maskVal;                 // Value to mask
    double badImage;                    // Image value if x,y location is not good
    double badVariance;                 // Variance value if x,y location is not good
    psMaskType badMask;                 // Mask value to give bad pixels
    psMaskType poorMask;                // Mask value to give poor pixels
    float poorFrac;                     // Fraction of flux in bad pixels before output is marked bad
} psImageInterpolateOptions;


/// Allocator
psImageInterpolateOptions *psImageInterpolateOptionsAlloc(psImageInterpolateMode mode, // Interpolation mode
                                                          const psImage *image, // Input image
                                                          const psImage *variance,  // Variance image
                                                          const psImage *mask, // Mask image
                                                          psMaskType maskVal, // Value to mask
                                                          double badImage, // Value for image if bad
                                                          double badVariance, // Value for variance if bad
                                                          psMaskType badMask, // Mask value for bad pixels
                                                          psMaskType poorMask, // Mask value for poor pixels
                                                          float poorFrac // Fraction of flux for question
    );



/// Interpolate image pixel value given floating point coordinates.
bool psImageInterpolate(double *imageValue, ///< Return value for image
                        double *varianceValue, ///< Return value for variance
                        psMaskType *maskValue, ///< Return value for mask
                        float x, float y, ///< Location to which to interpolate
                        const psImageInterpolateOptions *options ///< Options for interpolation
    );


// Return the appropriate interpolation mode given a char string name for that mode
psImageInterpolateMode psImageInterpolateModeFromString(const char *name // Mode name
    );


#endif
