
/** @file  psImageExtraction.h
*
*  @brief Contains basic image extraction operations, as specified in the 
*         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
*         Manipulation".
*
*  @ingroup Image
*
*  @author Robert DeSonia, MHPCC
*
*  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
*  @date $Date: 2004-10-27 00:57:31 $
*
*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
*/

#ifndef PSIMAGEEXTRACTION_H
#define PSIMAGEEXTRACTION_H

#include "psImage.h"
#include "psVector.h"
#include "psStats.h"

/// @addtogroup Image
/// @{

/* Cut direction flag.  Used with psImageCut function.
 */
typedef enum {
    PS_CUT_X_POS,                      ///< Cut in the x dimension from left to right
    PS_CUT_X_NEG,                      ///< Cut in the x dimension from rigth to left
    PS_CUT_Y_POS,                      ///< Cut in the y dimension from bottom up
    PS_CUT_Y_NEG,                      ///< Cut in the y dimension from top down.
} psImageCutDirection;

/** Create a subimage of the specified area.
 *
 *  Extracts a subimage starting at (col0,row0) to (col1-1,row1-1).  Note: 
 *  the column col1 and row row1 are NOT included in the resulting subimage.
 *  In the event that x1 or y1 are non-positive, they shall be interpreted as
 *  being relative to the size of the parent image in that dimension.
 *
 *  If the entire specified subimage is not contained within the parent 
 *  image, an error results and the return value will be NULL.
 *
 *  The resulting psImage does not create a copy of the underlying image 
 *  data.  Future changes in the parent may be reflecting in the child
 *  subimage and vis versa.
 *
 *  @return psImage* : Pointer to psImage.
 *
 */
psImage* psImageSubset(
    psImage* image,                    ///< Parent image.
    psS32 col0,                          ///< starting column of subimage
    psS32 row0,                          ///< starting row of subimage
    psS32 col1,                          ///< exclusive end column of subimage.
    psS32 row1                           ///< exclusive end row of subimage
);

/** Create a subimage of the specified area.
 *
 * Uses psLib memory allocation functions to create an image based on a larger
 * one.
 *
 * @return psImage* : Pointer to psImage.
 *
 */
psImage* psImageSubsection(
    psImage* image,                    ///< Parent image.
    const char* section                ///< Subsection in the form '[x1:x2,y1:y2]'
);

/** Trim an image
 *
 *  Trim the specified image in-place, which involves shuffling the pixels 
 *  around in memory.  The pixels in the region [col0:col1,row0:row1] shall consist
 *  the output image.  The column col1 and row row1 are NOT included in the range.
 *  In the event that x1 or y1 are non-positive, they shall be interpreted as
 *  being relative to the size of the parent image in that dimension.
 *
 *  If the entire specified subimage is not contained within the parent 
 *  image, an error results and the return value will be NULL.
 *
 *  N.B. If the input psImage is a child of another psImage, no pixel data 
 *  will be trimmed, rather it equivalent to calling psImageSubset.  If the input 
 *  psImage is, however, a parent psImage, any children will be obliterated,
 *  i.e., freed from memory.
 *
 *  @return psImage*  trimmed image result
 */
psImage* psImageTrim(
    psImage* image,                    ///< image to trim
    psS32 col0,                          ///< column of trim region's left boundary
    psS32 row0,                          ///< row of trim region's lower boundary
    psS32 col1,                          ///< column of trim region's right boundary
    psS32 row1                           ///< row of trim region's upper boundary
);

/** Extract pixels from rectlinear region to a vector (array of floats).
 *
 *  The output vector contains either col1-col0 or row1-row0 elements, based 
 *  on the value of the direction: e.g., if direction is PS_CUT_X_POS, there 
 *  are col1-col0 elements. The region to be  sliced  is defined by the 
 *  lower-left corner, (col0,row0), and the upper-right corner, (col1,row1). 
 *  Note that the row and column of the  upper right-hand corner  are NOT 
 *  included in the region. In the event that col1 or row1 are negative, they
 *  shall be interpreted as being relative to the size of the parent image in 
 *  that dimension. The input region is collapsed in the direction perpendicular 
 *  to that specified by direction, and each element of the output vectors is 
 *  derived from the statistics of the pixels at that direction coordinate. The
 *  statistic used to derive the output vector value is specified by stats. 
 *  If mask is non-NULL, pixels for which the corresponding mask pixel 
 *  matches maskVal are excluded from operations. If coords is not NULL, the 
 *  calculated coordinates along the slice are returned in this vector. Only 
 *  one of the statistics choices may be specified, otherwise the function 
 *  must return an error.
 *
 *  This function is defined for the following types: psS8, psU16, psF32, psF64.
 *
 * @return psVector    the resulting vector
 */
psVector* psImageSlice(
    psVector* out,                     ///< psVector to recycle, or NULL.
    psVector* slicePositions,
    ///< If not NULL, it is populated with the coordinate in the slice dimension
    ///< coorsponding to the output vector's value of the same position in the
    ///< vector.  This vector maybe resized and retyped as appropriate.
    const psImage* restrict input,     ///< the input image in which to perform the slice
    const psImage* restrict mask,      ///< the mask for the input image.
    psU32 maskVal,              ///< the mask value to apply to the mask
    psS32 col0,                          ///< the leftmost column of the slice region
    psS32 row0,                          ///< the bottommost row of the slice region
    psS32 col1,                          ///< exclusive end column of the slice region
    psS32 row1,                           ///< exclusive end row of the slice region
    psImageCutDirection direction,     ///< the slice dimension and direction
    const psStats* stats               ///< the statistic to perform in slice operation
);

/** Extract pixels from an image along a line to a vector (array of floats).
 *
 *  The vector (xs,ys) - (xe,ye) forms the basis of the output vector. Pixels 
 *  are considered in a rectangular region of width dw about this vector. The 
 *  input region is collapsed in the perpendicular direction, and each element 
 *  of the output vector represents pixel-sized boxes, where the value is 
 *  derived from the statistics of the pixels interpolated along the 
 *  perpendicular direction. The specific algorithm which must be used is 
 *  described in the PSLib ADD (PSDC-430-006). The statistic used to derive 
 *  the output vector value is specified by stats. Only one of the statistics 
 *  choices may be specified, otherwise the function must return an error. 
 *  This function must be defined for the following types: psS8, psU16, psF32, 
 *  psF64.
 *
 *  @return psVector    resulting vector
 */
psVector* psImageCut(
    psVector* out,                     ///< psVector to recycle, or NULL.
    psVector* cutCols,                 ///< if not NULL, the calculated column values along the slice (output)
    psVector* cutRows,                 ///< if not NULL, the calculated row values along the slice (output)
    const psImage* input,              ///< the input image in which to perform the cut
    const psImage* restrict mask,      ///< the mask for the input image.
    psU32 maskVal,              ///< the mask value to apply to the mask
    float startCol,                    ///< the column of the start of the cut line
    float startRow,                    ///< the row of the start of the cut line
    float endCol,                      ///< the column of the end of the cut line
    float endRow,                      ///< the row of the end of the cut line
    psU32 nSamples,             ///< the number of samples along the cut
    psImageInterpolateMode mode        ///< the interpolation method to use
);

/** Extract radial region data to a vector. A vector is constructed where each
 *  vector elements is derived from the statistics of the pixels which land 
 *  within one of a sequence of radii. The radii are centered on the image 
 *  pixel coordinate x,y, and are defined by the sequence of values in the
 *  vector radii. The specific algorithm which must be used is described in 
 *  the PSLib ADD (PSDC-430-006). The statistic used to derive the output 
 *  vector value is specified by stats. Only one of the statistics choices 
 *  may be specified, otherwise the function must return an error. This 
 *  function must be defined for the following types: psS8, psU16, psF32, 
 *  psF64.
 *
 *  @return psVector    resulting vector
 */
psVector* psImageRadialCut(
    psVector* out,                     ///< psVector to recycle, or NULL.
    const psImage* input,              ///< the input image in which to perform the cut
    const psImage* restrict mask,      ///< the mask for the input image.
    psU32 maskVal,              ///< the mask value to apply to the mask
    float centerCol,                   ///< the column of the center of the cut circle
    float centerRow,                   ///< the row of the center of the cut circle
    const psVector* radii,             ///< the radii of the cut circle
    const psStats* stats               ///< the statistic to perform in operation
);

/// @}

#endif
