/*
 * This file is part of the ESO SINFONI Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */
/*---------------------------------------------------------------------------
   
   File name     :    sinfo_median.h
   Author         :    N. Devillard
   Created on    :    1998
   Description    :    Fast sinfo_median finding routines
 *--------------------------------------------------------------------------*/
/*
    $Id: sinfo_median.h,v 1.3 2007-06-06 07:10:45 amodigli Exp $
    $Author: amodigli $
    $Date: 2007-06-06 07:10:45 $
    $Revision: 1.3 $
*/
#ifndef SINFO_MEDIAN_H
#define SINFO_MEDIAN_H


/*---------------------------------------------------------------------------
                                   Includes
 ---------------------------------------------------------------------------*/

/* Get the definition of a pixelvalue */
#include "sinfo_local_types.h"

/*---------------------------------------------------------------------------
                               Function prototypes
 ---------------------------------------------------------------------------*/
/**
  @name     sinfo_kth_smallest
  @memo     Find the kth smallest element in an array.
  @param    a   Array to consider for sinfo_median search.
  @param    n   Number of elements in the array.
  @param    k   Rank of the element to find (between 0 and n-1).
  @return   One element from the array.
  @doc
 
  Provide an array of n pixelvalues and the rank of the value you want
  to find. A rank of 0 means the minimum element, a rank of n-1 is the
  maximum element, and a rank of n/2 is the sinfo_median. Use the
  median_WIRTH macro to find the sinfo_median directly.
 
  NB: The input array is modified. Some elements are swapped, until
  the requested value is found. The array is left in an undefined
  sorted state.
 
  This algorithm was taken from the following book:
  \begin{verbatim}
                Author: Wirth, Niklaus
                 Title: Algorithms + data structures = programs
             Publisher: Englewood Cliffs: Prentice-Hall, 1976
  Physical description: 366 p.
                Series: Prentice-Hall Series in Automatic Computation
  \end{verbatim}
 */
/*--------------------------------------------------------------------------*/

pixelvalue 
sinfo_kth_smallest(pixelvalue a[], int n, int k);

/**
  @name     sinfo_kth_smallest_double
  @memo     Find the kth smallest element in a double array.
  @param    a   Array to consider for sinfo_median search.
  @param    n   Number of elements in the array.
  @param    k   Rank of the element to find (between 0 and n-1).
  @return   One element from the array.
  @doc
 
  See sinfo_kth_smallest() function in the same file.
 
  NB: THE INPUT ARRAY IS MODIFIED.
 */

double 
sinfo_kth_smallest_double(double a[], int n, int k) ;

#define median_double(a,n) \
sinfo_kth_smallest_double(a,n,(((n)&1)?((n)/2):(((n)/2)-1)))

/**
  @name     sinfo_opt_med3
  @memo     Optimized search of the sinfo_median of 3 values.
  @param    p   Array of 3 pixelvalues
  @return   Median of the input values.
  @doc
 
  Found on sci.image.processing. Cannot go faster unless some
  assumptions are made about the nature of the input signal, or the
  underlying hardware.
 
  The input array is modified.
 */

pixelvalue
sinfo_opt_med3(
    pixelvalue  *   p
) ;

/**
  @name     sinfo_opt_med5
  @memo     Optimized search of the sinfo_median of 5 values.
  @param    p   Array of 5 pixelvalues
  @return   Median of the input values.
  @doc
 
  Found on sci.image.processing. Cannot go faster unless some
  assumptions are made about the nature of the input signal, or the
  underlying hardware.
 
  The input array is modified.
 */

pixelvalue
sinfo_opt_med5(
    pixelvalue  *   p
);


/**
  @name     sinfo_opt_med7
  @memo     Optimized search of the sinfo_median of 7 values.
  @param    p   Array of 7 pixelvalues
  @return   Median of the input values.
  @doc
 
  Found on sci.image.processing. Cannot go faster unless some
  assumptions are made about the nature of the input signal, or the
  underlying hardware.
 
  The input array is modified.
 */

pixelvalue
sinfo_opt_med7(
    pixelvalue  *   p
) ;

/**
  @name     sinfo_opt_med9
  @memo     Optimized search of the sinfo_median of 9 values.
  @param    p   Array of 9 pixelvalues
  @return   Median of the input values.
  @doc
 
  Formula from:
  \begin{verbatim}
  XILINX XCELL magazine, vol. 23 by John L. Smith
  \end{verbatim}
 
  The result array is guaranteed to contain the sinfo_median value in middle
  position, but other elements are NOT sorted.
 
  The input array is modified.
 */

pixelvalue
sinfo_opt_med9(
    pixelvalue  *   p
) ;

/**
  @name     sinfo_opt_med25
  @memo     Optimized search of the sinfo_median of 25 values.
  @param    p   Array of 25 pixelvalues
  @return   Median of the input values.
  @doc
 
  Formula from:
  \begin{verbatim}
  Graphic Gems source code
  \end{verbatim}
 
  The result array is guaranteed to contain the sinfo_median value in middle
  position, but other elements are NOT sorted.
 
  The input array is modified.
 */

pixelvalue
sinfo_opt_med25(
    pixelvalue  *   p
) ;


/**
  @name     sinfo_median_pixelvalue
  @memo     Compute the sinfo_median pixel value of an array.
  @param    a   Array to consider.
  @param    n   Number of pixels in the array.
  @return   The sinfo_median of the array.
  @doc
 
  This is the generic method that should be called to get the sinfo_median
  out of an array of pixelvalues. It calls in turn the most efficient
  method depending on the number of values in the array.
 
  The input array is always modified.
 */

pixelvalue 
sinfo_median_pixelvalue(pixelvalue * a, int n);

#endif
