/*---------------------------------------------------------

   ISImageFilter.h : part of the ImgSource library.

   Image filters

    This code copyright (c) 2000-2016, Smaller Animals Software, Inc..

    No portion of this code may be copied or distributed without 
    permission of Smaller Animals Software, Inc..
    http://www.smalleranimals.com

---------------------------------------------------------*/

#pragma once

#if !defined is6_SOURCEH && !defined is6_INTERNAL
#error Do not include this file directly. Include ISource.h
#endif

#ifdef __cplusplus
extern "C" {
#endif

    
/*---------------------------------------------------------
   is6_GaussianBlurImage / _is6_GaussianBlurImage

   Purpose : 
   Apply a Gaussian blur to an image.

   Note:
   This should only be used on continuous-tone images (RGBA,
   grayscale, RGB, BGR, etc.) 

   Note: 
   By default, this function will use an approximation of a Gaussian 
   filter. This runs in constant time with respect to fSigma, as 
   compared to linear time with the traditional method which does a 
   2x1D convolution on the image. In other words, fSigma has no effect 
   on the execution time with the default method. So, you can use high 
   values for fSigma (large blurs) and there is no performance penalty.

   Note:
   If fSigmaX or fSigmaY is greater than half the width or 
   height (respectively) of the image, an alternate approximation will 
   be used. This is an infinite impulse response approximation of a 
   Gaussian blur (as described by Rachid Deriche, 1993). This also runs 
   in constant time with respect to sigma, but is slightly slower and 
   uses significantly more memory than the default method. 

   Note:
   The two approximations are not identical in their output.

   Note:
   If you need the traditional 2x1D convolution version, you can force 
   this call to use it by setting bit 8 in uFlags. The 2x1D convolution
   results are much more accurate, but the function is much slower.

   Note:
   If you select the 2x1D method, fSigmaX is used for both directions.
   
   pInput != pOutput

   Note:
   Callback is called twice per color channel.

   Param             Use
   ------------------------------------
   pInput            source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel color components per pixel. max 8.
   uInRowStride      number of components in an input pixel row
   pOutput           destination image
   uOutRowStride     number of components in an output pixel row

   fSigmaX           horizontal standard dev. of the gaussian kernel.
                     in practical terms, this controls the
                     amount of blur in the horiontal direction. 
                     good values to start with are between 
                     0.6 and 2.4.

   fSigmaY           vertical standard dev. of the gaussian kernel.

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                      8       force 2x1D convolution, using fSigmaX in both directions.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)

                     11       do not round results up (2x1d convolution, only)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_GaussianBlurImage)(const void *pInput, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOutput, UINT32 uOutRowStride, double fSigmaX, double fSigmaY, UINT32 uFlags);

/*---------------------------------------------------------
   is6_UnsharpMaskImage / _is6_UnsharpMaskImage

   Purpose : 
   Apply an unsharp mask effect to an image. This is a 
   high-frequency enhancement effect. Similar in effect 
   to a sharpening filter, it brings out edges
   and point details. 
   
   This should only be used on continuous-tone images (RGBA,
   grayscale, RGB, BGR, etc.) 
   
   pInput != pOutput

   This function works by first doing a Gaussian blur on 
   the image, then finding the difference between pixels
   in the blurred image and in the original. For each pixel
   in the blurred and the original images, if the pixel 
   differs by greater than a given threshold value, a 
   percentage of the difference is added to the original 
   pixel.

   Param             Use
   ------------------------------------
   pInput            source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel color components per pixel. max 8.
   uInRowStride      number of components in an input pixel row
   pOutput           destination image
   uOutRowStride     number of components in an output pixel row

   
   uThreshold        controls the depth of the effect. 
                     any value between 0 and 255 is valid.
                     the lower the value, the greater the effect.

   fAmount           controls the intensity of the effect.
                     values should be between 0.0 (no effect) 
                     and 1.0 (full effect). higher values will 
                     give unpredictable results.

   fSigma            standard dev. of the gaussian kernel.
                     this has an effect similar to the uThreshold 
                     value, but much broader (effects more pixels).
                     good values to start with are between 0.6 
                     and 2.4. 

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_UnsharpMaskImage)(const void *pInput, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOutput, UINT32 uOutRowStride, UINT32 uThreshold, double fAmount, double fSigma, UINT32 uFlags);

/*---------------------------------------------------------
	is6_Convolve / _is6_Convolve

   Purpose :
   Apply a convolution to an image. 
   
   This should only be used on continuous-tone images (RGBA,
   grayscale, RGB, etc.)

   The number of columns and the number of rows in the
   matrix must both be odd.

   The filter is applied as follows :

      M = matrix ( 3 x 3, in this example)

      M =
      1  1  1
      1 -8  1       this is a sharpening matrix
      1  1  1

      the matrix is centered on the current pixel. in
      this example, M[4] is the center of the matrix.

      k is a scaling factor.

      P = pixels . since the matrix is centered on the
      current pixel, P(x,y), the pixels used in this
      calculation will be :

         P(x-1,y-1),    P(x, y-1),     P(x+1, y-1)
         P(x-1,y),      P(x, y),       P(x+1, y)
         P(x-1,y+1),    P(x, y+1),     P(x+1, y+1)

      t = sum ( M[i] * P[i] )  [for all elements of the matrix]


      if uMode = 0:
         outPixel = k * t
      else if uMode = 1:
         outPixel = outPixel * (1.0 - k) + (k * t)
      else if uMode = 2
         outPixel = curPixel - (k * t)

   outPixel is then clipped to the min/max values specified

   Matrix M in this example demonstrates the sharpening filter
   used by this library, if mode = 2


   Param             Use
   ------------------------------------
   pImage            input image
   uWidth            width in pixels
   uHeight           height
   uChannelsPerPixel number of components in a pixel
   uInRowStride      number of components in an input pixel row
   pImageOut         output image
   uOutRowStride     number of components in an output pixel row
   uMode             see notes above
   uFilterCols       columns in filter matrix
   uFilterRows       rows in filter matrix
   pFilter           filter matrix
   k                 filter level

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex.
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2
                              (R, G and B) will be processed.

                              If uFlags = 1 | 4 , channels 0 and 2
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.


                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/ 
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_Convolve)(const void *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pImageOut, UINT32 uOutRowStride, UINT32 uMode, double fK, double *pMatrix, UINT32 nX, UINT32 nY, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ApplyLUTAndCrossoverMatrixToRGB / _is6_ApplyLUTAndCrossoverMatrixToRGB

   Purpose : 
   Apply a crossover matrix and LUT to an RGB image.

   The matrix is a 12 item (3 rows, 4 columns) array of
   floating point values. 

   The LUT is an array of 3 * 256 BYTEs. 

   LUT[0]   -> LUT[255] are the values for the red channel (LUT_rd).
   LUT[256] -> LUT[511] are the values for the green channel (LUT_gr).
   LUT[512] -> LUT[767] are the values for the blue channel (LUT_bl).

   If pLUT is NULL, an identity LUT will be used.


   The matrix and LUT are applied as follows :

     -------------

     For each pixel, "cur", 

     // LUT
     cur.rd = LUT_rd[cur.rd]
     cur.gr = LUT_gr[cur.gr]
     cur.bl = LUT_bl[cur.bl]

     // matrix
     out.rd =(cur.rd * matrix[0, 0] + 
            cur.gr * matrix[0, 1] +
            cur.bl * matrix[0, 2])
         
     out.rd = out.rd + matrix[0, 3]

     out.gr =(cur.rd * matrix[1, 0] + 
            cur.gr * matrix[1, 1] +
            cur.bl * matrix[1, 2]) 

     out.gr = out.gr + matrix[1, 3]

     out.bl =(cur.rd * matrix[2, 0] + 
            cur.gr * matrix[2, 1] +
            cur.bl * matrix[2, 2])

     out.bl = out.bl + matrix[2, 3]
     
     ------------

     Matrix samples : 

     This matrix has no effect on the image :
       1.0, 0.0, 0.0, 0.0
       0.0, 1.0, 0.0, 0.0
       0.0, 0.0, 1.0, 0.0

     Increase the saturation :
        1.2, -0.1, -0.1, 0.0
       -0.1,  1.2, -0.1, 0.0
       -0.1, -0.1,  1.2, 0.0

     Increases the brightness :
       1.0, 0.0, 0.0, 20.0
       0.0, 1.0, 0.0, 20.0
       0.0, 0.0, 1.0, 20.0

     Change to grayscale :
       1/3, 1/3, 1/3, 0
       1/3, 1/3, 1/3, 0
       1/3, 1/3, 1/3, 0

     General rule : the sum of the first 3 items in 
     a row should add to 1. 

   Param             Use
   ------------------------------------
   pRGB              RGB image
   uWidth            width in pixels
   uHeight           height 
   uRowStride        bytes per pixel row
   pLUT              look-up table (LUT) - 768 values
   pMatrix           12 element crossover matrix

   Return
   ------
      FALSE on failure
---------------------------------------------------------*/ 
_ISDeclSpec BOOL        _ISCConv _ISFn( is6_ApplyLUTAndCrossoverMatrixToRGB )(BYTE *pRGB, UINT32 uWidth, UINT32 uHeight, UINT32 uRowStride, BYTE *pLUT, double *pMatrix);

/*---------------------------------------------------------
   is6_CannyEdgeDetector

   Purpose : 
   Find edges in an image, using the Canny algorithm
   
   Param             Use
   ------------------------------------
   pIn               source image (8-bit grayscale)
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of pixels in input image row
   pOut              output image (8-bit grayscale)
   uOutRowStride     number of pixels in output image row

   fSigma            standard dev. of the gaussian kernel.
                            controls pre-detection smoothing.
                            larger values increase smoothing and 
                            decrease the amount of edges found.

                     good values to start with are 
                     between 0.6 and 2.4. 

                            larger values increase processing time.

   tlow              Specifies the low value to use in hysteresis. This is a 
                     fraction (0-1) of the computed high threshold edge 
                     strength value. (0.20-0.50 are good starting values)

   tHigh             Specifies the high value to use in hysteresis. 
                     This fraction (0-1) specifies the percentage point 
                     in a histogram of the gradient of the magnitude. 
                     Magnitude values of zero are not counted in the histogram.
                     (0.60-0.90 are good starting values)

   uFlags            bit      purpose
                     ---      -------
                      0       if set, use IIR method for the Gaussian blur
                              portion of the algorithm. this is faster, but 
                              gives slightly different results than the 
                              default (2 x 1D convultion) method.

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_CannyEdgeDetector )(const BYTE *pIn, UINT32 w, UINT32 h, UINT32 uInRowStride, BYTE *pOut, UINT32 uOutRowStride, double fSigma, double tLow, double tHigh, UINT32 uFlags);

/*---------------------------------------------------------
   is6_MotionBlur

   Purpose : 
   Apply a motion blur effect to an image. This is a linear
    blur.
    
    See also is6_RadialBlur, is6_ZoomBlur.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uBpp              number of bytes per pixel
   uInRowStride      bytes per input pixel row
   pOut              output image
   uOutRowStride     bytes per output pixel row
   fAngle            angle of motion (radians)
   fSigma            controls the amount of blur (try 2, to start)

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

                     12       use box filter instead of Gaussian. gives 
                              sharper edges at the ends of the blur.

                     20       disable multithreaded processing
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_MotionBlur )(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uBpp, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, double fAngle, double fSigma, UINT32 uFlags);

/*---------------------------------------------------------
   is6_RadialBlur

   Purpose : 
   Apply a radial blur effect to an image.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uBpp              number of bytes per pixel
   uInRowStride      bytes per input pixel row
   pOut              output image
   uOutRowStride     bytes per output pixel row

   fAngle            angle of motion in radians. also, 
                     length of the blur arcs. larger values
                     seriously increase processing time.

   quality           0 - 1. controls resoultion of the blur.
                     lower is faster but will show steps.
                     higher is slower, but gives better quality.

   pCenter           center of rotation

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

                      12      use box filter instead of Gaussian. gives 
                              sharper edges at the ends of the blur.

                      20      disable multithreaded processing

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_RadialBlur )(const void *pIn, UINT32 inW, UINT32 inH, UINT32 bpp, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, double fAngle, double quality, POINT * pCenter, UINT32 uFlags) ;

/*---------------------------------------------------------
   is6_ZoomBlur

   Purpose : 
   Apply a zoom blur effect to an image.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uBpp              number of bytes per pixel
   uInRowStride      bytes per input pixel row
   pOut              output image
   uOutRowStride     bytes per output pixel row

   amount            0 - 1. controls the size of the blur.
                     smaller values give smaller blur.
                    
   pCenter           center of zoom

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

                      12      use box filter instead of Gaussian. gives 
                              sharper edges at the ends of the blur.

                      20      disable multithreaded processing

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_ZoomBlur )(const void *pIn, UINT32 inW, UINT32 inH, UINT32 bpp, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, double amount, POINT *pCenter, UINT32 uFlags);

/*---------------------------------------------------------
   is6_Filter

   Purpose :
   Apply a filter to an image.

   Notes:
   *  pIn != pOut.
   *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      bytes per input pixel row
   pOut              destination image
   uOutRowStride     bytes per output pixel row
   uFilterSize       larger filter yields stronger effect

   uMode             0 : arithmetic mean
                     1 : geometric mean
                     2 : harmonic mean
                     3 : yp mean. k controls power.
                     4 : midpoint
                     5 : maximum
                     6 : minimun

   k                 for yp mean, this controls power:
                           k < 0, removes positive outliers
                           k > 0, removes negative outliers

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex.
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2
                              (R, G and B) will be processed.

                              If uFlags = 1 | 4 , channels 0 and 2
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_Filter)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, UINT32 uMode, int k, UINT32 uFlags);

/*---------------------------------------------------------
   is6_SharpenImage

   Purpose : 
   Sharpen an image.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      bytes per input pixel row
   pOut              destination image
   uOutRowStride     bytes per output pixel row
   uFilterSize       convnolution kernel size. larger filter yields stronger effect.
   fK                filter intensity (0 to 1)

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

   

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_SharpenImage)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, double fK, UINT32 uFlags);

/*---------------------------------------------------------
   is6_BlurImage

   Purpose : 
   Blur an image using a box filter.

   Note: 
    If fOpacity = 1.0, this funstion is equivalent to is6_Filter mode 0.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      bytes per input pixel row
   pOut              destination image
   uOutRowStride     bytes per output pixel row
   uFilterSize       convolution kernel size. larger filter yields stronger effect
   fK                filter intensity (0 to 1)

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
   

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_BlurImage)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, double fK, UINT32 uFlags);

/*---------------------------------------------------------
   is6_MedianFilterImage

   Purpose : 
   Apply a median filter to an image.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      components per input pixel row
   pOut              destination image
   uOutRowStride     components per output pixel row
   uFilterSize       larger filter yields stronger effect
   fAmount           controls opacity of effect (0=no effect, 1.0 = full effect)

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_MedianFilterImage)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, double fAmount, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ThresholdFilter

   Purpose:
   Set pixel components above a high threshold value to 255, set pixels
   below a low threshold value to 0.

   Param             Use
   ------------------------------------
   pIn               input image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      bytes per input pixel row
   uMinVal           pixel values below this will be set to 0
   uMaxVal           pixel values above this will be set to 255

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
  

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_ThresholdFilter )(void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, UINT32 uMinVal, UINT32 uMaxVal, UINT32 uFlags);

/*---------------------------------------------------------
   is6_AdaptiveUnsharpMask

   Purpose:
   Perform an adaptive unsharp mask on the input image. This
   is a sophisticated sharpening function.

   Param             Use
   ------------------------------------
   pIn               input image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image
   uInRowStride      bytes per input pixel row
   pOut              output image
   uOutRowStride     bytes per output pixel row
   uThreshold        0 to 255. lower numbers yiled greater effect
   fAmount           amount of sharpened signal to add to the output image.
                     0 = no change. 1 = full change. you can use any number
                     (even negative), but the intended use is between 0 and 1.0.

   uMode              0: fast, less accurate
                      1: good results, slower
                      2: best results, very slow

   uFlags             bit     use
                      ---     ---
                       2      if set, skip alpha channel
                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
  

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_AdaptiveUnsharpMask)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uThreshold, double fAmount, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_FindImageMean

   Purpose:
   Find the mean (arithmetic average) pixel value for one
   or more channels in an image.

   Param             Use
   ------------------------------------
   pIn               input image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image (max 8)

   pMeans            array of doubles, uBytesPerPixel elements.
                     these receive the calculated mean values.

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)  

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_FindImageMean)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, double *pMean, UINT32 uFlags);

/*---------------------------------------------------------
   is6_FindImageStandardDeviation

   Purpose:
   Find the standard deviation of the pixel values for one
   or more channels in an image.

   Param             Use
   ------------------------------------
   pIn               input image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image (max 8)

   pStdDeviation     array of doubles, uBytesPerPixel elements.
                     these receive the calculated values.

   pMean             optional array of doubles, uBytesPerPixel elements.
                     these receive the calculated mean values. pass NULL,
                     if you don't want these.

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_FindImageStandardDeviation)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, double *pStdDeviation, double *pMean, UINT32 uFlags);

/*---------------------------------------------------------
   is6_LocalHistogramEnhancement

   Purpose:
   Adjust the relative brightness of local region areas
   based on global image statistics. This can be used to
   raise or darken image areas with brightness levels that 
   differ significantly from the overall image.

   This locates areas of the image where the local brightness 
   is different (either above or below) from the global 
   brightness and adjusts the brightness accordingly. "Difference"
   is determined by calculating the mean and standard deviation for
   pixels under the filter and comparing them to the mean and 
   std dev for the entire image. The input parameters allow you
   to adjust the sensitivity and range of the comparison.

   Each output pixel is determined in this fashion:

   if ((local_mean <= k0 * global_mean) AND
       (k1 * global_std_dev <= local_std_dev <= k2 * global_std_dev))
   then
      out = input * k3
   else
      out = input

   When you have selected the "decrease brightness" option (via uFlags),
   the calculation becomes:

   if ((local_mean >= k0 * global_mean) AND
       (k1 * global_std_dev <= local_std_dev <= k2 * global_std_dev))
   then
      out = input * k3
   else
      out = input


   The local_mean and local_std_dev are calculated for each local 
   region of size uFliterSize x uFliterSize. Global mean and standard
   deviation are calculated with is6_FindImageMean and 
   is6_FindImageStandardDeviation. These calculation only need to be done
   once, if the input image is not changed. 

   Note:
   Use of this function will almost always require user input, as it 
   is extremely sensitive to image statistics and the parameters given.
   
   Reasonable starting values for k0, k1, k2 and k3 are :

      k0 : 0.5
      k1 : 0.02
      k2 : 0.5
      k3 : 3.0

   Param             Use
   ------------------------------------
   pIn               input image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image (max 8)
   uInRowStride      bytes per pixel row, input
   pOut              output image
   uOutRowStride     bytes per output row

   uFilterSize       must be odd. controls the size of the local area
                     inspected for adjustment. 3 is a good starting value.

   pStdDeviation     array of doubles, uBytesPerPixel elements.
                     these receive the calculated values.

   pMeans            array of mean values calculated in advance. see
                     is6_FindImageMean. 

   pStdDeviations    array of standard deviation values calculated in 
                     advance. see is6_FindImageStandardDeviation.

   k0                positive with a value generally less than 1.
                     this determines the lower limit for affected 
                     pixel values. 

   k1                this determines the lower limit with respect to the
                     local standard deviation for affected pixels. 0 < k1 < k2.

   k2                determines the upper limit with respect to the
                     local standard deviation for affected pixels. 0 < k1 < k2.

   k3                factor that determines the strength of the effect.

  uFlags             bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
   

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_LocalHistogramEnhancement)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, double *pMeans, double *pStdDeviations, double k0, double k1, double k2, double k3, UINT32 uFlags);

// experimental
_ISDeclSpec BOOL _ISCConv _ISFn( is6_AdaptiveDWMTMFilter )(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uBytesPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, double fNSTD, double fK, UINT32 uFlags);

/*---------------------------------------------------------
   is6_MedianFilter1Bit

   Purpose : 
   Apply a median filter to a 1-bit image.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uInRowStride      bytes per input pixel row
   pOut              destination image
   uOutRowStride     bytes per output pixel row
   N                 larger filter yields stronger effect (start with 3)
   uFlags            unused

   

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_MedianFilter1Bit)(const BYTE *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pOut, UINT32 uOutRowStride, UINT32 N, UINT32 uFlags);

/*---------------------------------------------------------
   is6_DustAndScratches

   Purpose : 
   Removes dust and scratches (or any other small sharp 
   details) from the image. This is similar in effect
   to Photoshop's "Dust and Scratches" filter.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of bytes per pixel in the image. max 8.
   uInRowStride      bytes per input pixel row
   pOut              destination image
   uOutRowStride     bytes per output pixel row
   uFilterSize       larger filter yields stronger effect

   uThreshold        0 to 255. controls the minimum detail
                     intensity required to trigger removal.

   fAmount           0.0 to 1.0. controls blending of original
                     image with the removed image detail. 
                     higher values obscure more of the source image.

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)
                              10 - images have 64 bits per component (double) (val=0x400)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_DustAndScratches)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFilterSize, UINT32 uThreshold, double fAmount, UINT32 uFlags);

/*---------------------------------------------------------
   is6_BilateralFilterImage

   Purpose : 
   Apply a bilateral filter to the image. 

   A bilateral filter is a detail-preserving denoising filter.
   It tends to reduce noise in smooth areas while leaving strong
   image details unaffected.

   Because this can be a very slow process, we have implemented a 
   quick and dirty approximation of the bilateral filter that
   runs at least an order of magnitude faster than the default 
   method while providing results that are similar to a true 
   bilateral filter. See uFlags, bit 8.

   Callback is called once per channel for the fast method, and
   one per row per channel, for the true bilateral method.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of components per pixel in the image. max 8.
   uInRowStride      components per input pixel row
   pOut              destination image
   uOutRowStride     components per output pixel row

   uFilterSize       larger filter yields stronger effect, but 
                     requires more processing time. try 15 to start.

   uFilterType       select one of the following shapes for 
                     the smoothing kernel:
                        0 = Gaussian
                        1 = linear
                        2 = cosine
                        3 = constant

   fSigma            controls intensity of the effect. try 20 to start.

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                      8       use the quick-and-dirty method. this is
                              not strictly a bi-lateral filter, but the results
                              are very close, and the function can be over 
                              ten times faster than the true bi-lateral filter.

                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              01 - images have 16 bits per component (ISUINT16) (val=0x200)

                      20      disable multithreaded processing


   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_BilateralFilterImage)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride,
                                                            void *pOut, UINT32 uRowOutStride, 
                                                            UINT32 uFilterSize, UINT32 uFilterType, double fSigma, UINT32 uFlags);

/*---------------------------------------------------------
   is6_CrossBilateralFilterImage

   Purpose : 
   Apply a cross bilateral filter to a single channel image. 

   A cross bilateral filter (aka 'joint bilateral') is a bilateral
   filter which uses the details from one image to control the
   filtering of another image. 

   This is based on Paris and Durand's cross bilateral filter, and 
   the results are somewhat differentl than those from 
   is6_BilateralFilterImage.

   This can also be used as a traditional bilateral filter by using 
   the same image for pIn1 and pIn2.

   Callback is called three times.

   Notes:
      * pIn1 and pIn2 can point to the same image. 
      * pIn1 != pOut. pIn2 != pOut
      * Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn1              source image to be filtered
   uWidth            width in pixels of all images
   uHeight           height of all images
   uInRowStride      components per input pixel row (pin1 and pIn2)
   pIn2              source image which supplies the details.
   pOut              destination image
   uOutRowStride     components per output pixel row

   fSpaceSigma       try small positive values (ex 10.0)

   fRangeSigma       try positive fractional values (ex. 0.125)
                     this is related to the dimensions of the 
                     image - smaller images should use smaller values.

   uFlags            bit      purpose
                     ---      -------
                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              10 - images have 64 bits per component (double) (val=0x400)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_CrossBilateralFilterImage)(const void *pIn1, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, const void *pIn2, void *pOut, UINT32 uOutRowStride, double fSpaceSigma, double fRangeSigma, UINT32 uFlags);

/*---------------------------------------------------------
   is6_GuidedFilter / _is6_GuidedFilter

   Purpose : 
   Apply a guided filter to a single channel image. 

   A guided filter is an edge-preserving smoothing filter 
   which uses the details from one image to control the
   filtering of another image. The results are similar to 
   a cross bilateral filter, but it is generally faster.

   Callback is not called.

   Notes:
      * best results are when input values are between 0 and 1
      * Output is allocated by the caller.
      * pInImg may be the same as pOutImg
      * this only works on floating point images

   Param             Use
   ------------------------------------
   pInImg            source image to be filtered
   uWidth            width in pixels of all images
   uHeight           height of all images
   uInRowStride      components per input pixel row (pInImg)
   pGuideImg         source image which supplies the details
   uInGuideStride    components per input pixel row (pGuideImg)
   pOutImg           destination image
   uOutRowStride     components per output pixel row

   uRadius           size of filter (start with 10)

   fDepth            depth of effect. 0..1 . larger values will start
                     to blur the output image.

   uFlags            bit      purpose
                     ---      -------
                     9-10     10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_GuidedFilter)(const void *pInImg, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel,UINT32 uInRowStride, const void *pGuideImg, UINT32 uGuideRowStride, void *pOutImg, UINT32 uOutRowStride, UINT32 uRadius, double fDepth, UINT32 uFlags);

/*---------------------------------------------------------
   is6_RetinexImage

   Purpose : 
   Perform a retinex operation on a single-channel image.

   This is a powerful detail and contrast enhancement algorithm.

   Generally, you would apply this to a grayscale image or to 
   the brightness/luminance channel of a multicolor image (ex.
   to the Y channel of a YCC image, or to the L or V channel of 
   an HSL or HSV image). See is6_SplitImage / is6_CombineImageChannels.

   You can apply it to all three channels of an RGB image, but 
   there is a potential for color distortion.

   This function has three distinct modes, selected by uModes. 
   The first mode uses the standard multi-scale algorithm, based 
   on a Gaussian blur. The second mode uses a guided filter. 
   The third mode uses a variation of Paris and Durand's 
   cross-bilateral filter. 
   
   The guided filter and the bilateral filter generally give 
   similar results (though the parameters will be different), and 
   both show far fewer haloes/ringing around edges, compared 
   to the Gaussian method. 

   The guided filter is generally faster than the bilateral method. 
   
   Note:

   Gaussian:
      This is the traditional multi-scale retinex, using a fixed
      set of surround scales (aka blur radii): 3, 15, 80. There
      are four parameters to adjust:

      fA: gain. try 40 to start with.
      fB: output Gain. controls final histogram adjustment. try 2.
      fC: offset. lower values increase contrast. try 20, to start.
      fD: alpha. controls dynamic range. this is extremley sensitive in the range 1.0 to 1.05

   Guided filter:
      fA is the size of the filter. Start with 10.
      fB is the depth of the filter. Start with small fractional values (0.01 to 0.5)

   Bilateral:
      For the bilateral filter mode, two passes through 
      the bilateral filter are used, and so you need to specify two 
      sets of range/space sigmas. The first set of sigmas (fA and fB) 
      generally are larger than the second (fC and fD). Optimal 
      values will vary from image to image.

      for fA, range sigma A. try small positive values (ex 10.0).
      for fB, space sigma A. try positive fractional values (ex. 0.15)
      for fC, range sigma B. try small positive values (ex 5.0)
      for fD, space sigma B. try positive fractional values (ex. 0.02)


   Guided and bilateral:
      If the input data has a small range of values, noise will
      be increased in the output. To avoid this, you should scale the 
      input data up to at least 0..255 before calling this function.
   
      Note:
      fMaxVal is the maximum value allowed in the input range (and
      subsequently, the output range). This is not necessarily the same 
      as the maximum value present in the actual input. 

      Ex.
         input data is in the range 0..1
         multiply all values by 255
         pass 255 as fMaxVal when you call this
         after completion, divide all your values by 255

      Callback is called 6 times.

   Notes:
      * pIn != pOut
      * Output is allocated by the caller.

   Param             Use
   ------------------------------------
   pIn               source image to be filtered
   uWidth            width in pixels
   uHeight           height
   uInRowStride      components per input pixel row
   pOut              destination image
   uOutRowStride     components per output pixel row

   uMode             0 - gaussian
                     1 - guided filter
                     2 - bilateral

   fA                use depends on mode
   fB                use depends on mode
   fC                use depends on mode
   fD                use depends on mode

   fGamma            controls brightness of output (try 1 to 3).
                     unused in Gaussian mode

   fMaxVal           maxiumum value allowed in the input.
                     unused in Gaussian mode

   uFlags            bit      purpose
                     ---      -------
                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              10 - images have 64 bits per component (double) (val=0x400)
                              11 - images have 32 bits per component (float) (val=0x600)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_RetinexImage)(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uMode, double fA, double fB, double fC, double fD, double fGamma, double maxVal, UINT32 uFlags);

/*---------------------------------------------------------
   is6_SobelFilter

   Purpose : 
   Apply a Sobel filter to the image. 

   This is an edge-highlighting filter.

   Because the output of this filter can be larger than the input 
   components can hold, BYTE inputs require ISUINT16 outputs and
   ISUINT16 inputs require UINT32 outputs. 
   
   If the input is floats, output must be floats. If the input is 
   doubles, output must be doubles.

   This function has two modes: Separate and Combined.
   The "Separate" mode will filter up to 8 channels of data, each 
   channel processed independently of the others - as is typical of
   ImgSource filters.
   
   The "Combined" mode will process three input channels (RGB or RGBA, 
   ignoring alpha) into a single output channel; it does this by 
   finding the individual Sobel result for the 3 input channels, 
   then outputs the average of the three channels' results. In effect, 
   it does a simple RGB -> grayscale conversion on-the-fly. 
   
   See uFlags, bit 8.
    
   Callback is called once per row.

   Notes:
      *  pIn != pOut.
      *  Output is allocated by the caller.
      *  Combined mode can only work on 3 or 4 cpp pixels (does not use the alpha channel)

   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of components per pixel in the images 
   uInRowStride      components per input pixel row

   pOut              destination image. for Separate mode, this
                     must have the number of components as the input image.
                     for Combined mode, this is a single channel image.

   uOutRowStride     components per output pixel row

   uFlags            bit      purpose
                     ---      -------
                     0-7      Used only in "Separate" mode.

                              These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.

                      8       If clear, use 8->16, Separate processing.
                              If set, use 3x8->16, Combined processing.

                      9-10    00 - input is 8 bits per component  (BYTE) (val=0)
                                   output is 16 bits per component (ISUINT16)
                                    
                              01 - input is 16 bits per component (ISUINT16) (val=0x200)
                                   output is 32 bits per component (int)

                              10 - input and output is 64 bits per component (double) (val=0x400)
                              11 - input and output is 32 bits per component (float) (val=0x600)

                      20      disable multithreaded processing

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn( is6_SobelFilter )(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ApplyWindow

   Purpose : 
   Apply a windowing function to an image. This fades the image
   to 0s on the edges.
   
   Param             Use
   ------------------------------------
   pIn               source image
   uWidth            width in pixels
   uHeight           height
   uComponentsPerPixel    number of components per pixel in the images 
   uInRowStride      bytes per input pixel row

   uWindowType       0 : Hamming
                     1 : Hanning
                     2 : Blackman
                     3 : Nuttall
                     4 : Blackman-Nuttall
                     5 : Blackman-Harris

   uFlags            bit      purpose
                     ---      -------
                     0-7      These bits control which channels to
                              process. If bit N is set, channel N is 
                              processed. If bit N is not set, channel
                              N is skipped (nothing is written to
                              the output for that channel).

                              Ex. 
                              If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                              (R, G and B) will be processed. 

                              If uFlags = 1 | 4 , channels 0 and 2 
                              (R and B) will be processed. Channel 1 (Green)
                              will be skipped.
   
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn( is6_ApplyWindow )(const void *pIn, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, UINT32 uWindowType, UINT32 uFlags);


/*---------------------------------------------------------
   is6_MultiscaleDenoise

   Purpose : 
   Filter high frequency noise from an image using a multi-scale
   Lagrangian 'a trous' wavelet transform. This uses an 
   algorithm derived from the "wavelet_denoise" function in 
   dcraw (www.cybercom.net/~dcoffin/dcraw/).
   
   Param             Use
   ------------------------------------
   pInImg               source image
   uWidth               width in pixels
   uHeight              height
   uComponentsPerPixel  number of components per pixel (max 5)
   uInRowStride         number of components per input pixel row
   pOutImg              output image
   uOutRowStride        number of components per output pixel row
   
   fThreshold           max pixel difference allowed between passes. 
                        for 8-bit images, start with low values (~10)
                     
   fCurve               controls the intensity of the effect on
                        lower frequency bands. the lower the value
                        the more the lower frequencies are affected.

   uFlags               bits     purpose
                        ---      -------
                        0-7      These bits control which channels to
                                 process. If bit N is set, channel N is 
                                 processed. If bit N is not set, channel
                                 N is skipped (nothing is written to
                                 the output for that channel).

                                 Ex. 
                                 If uFlags = 1 | 2 | 4, channels 0, 1 and 2 
                                 (R, G and B) will be processed. 

                                 If uFlags = 1 | 4 , channels 0 and 2 
                                 (R and B) will be processed. Channel 1 (Green)
                                 will be skipped.

                        9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                                 11 - images have 32 bits per component (float) (val=0x600)
   
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_MultiscaleDenoise)(const void *pInImg, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOutImg, UINT32 uOutRowStride, double fThreshold, double fCurve, UINT32 uFlags);

/*---------------------------------------------------------
   is6_MultiscaleDecompose

   Purpose : 
   Decopose a single-channel image into a series of sub-images.
   These sub-images represent the various frequency bands used in the
   denoising process of is6_MultiscaleDenoise. They can be edited 
   idividually and then put back together with is6_MultiscaleRecompose. 
   
   Note:
   The final image returned is everything that's left over after the
   last high/low split. 

   Note: 
   If the input image is 8-bit, the sub-frequency images (but not the 
   residual image) will be biased so that 128 is neutral, and details will 
   appear as lighter or darker than that. So, if you want to remove a 
   detail, set it to 128. If you want to add detail, add it lighter
   or darker than 128. This is to account for the fact that 8-bit
   components are unsigned. The residual image will not be rebiased - 
   it will remain in the same range as the input.

   If the input image is 32-bit floating point, the neutral point is 0
   and details will appear as greater or less than 0.

   Note:
   The number of images returned (and the number of buffers you must
   allocate) is uPasses + 1. The "+1" is for the residual image.

   Note:
   The first image will contain the highest-frequency details. Each
   image after that will contain lower and lower frequencies. The
   final image is the residual image.

   Example:
       // input is in pRGB. w,h pixels
       BYTE *pRGBOut = new BYTE[w * h * 3];

       BYTE *pCh[3];
       pCh[0] = new BYTE[w * h];
       pCh[1] = new BYTE[w * h];
       pCh[2] = new BYTE[w * h];

       const int levels = 6;

       is6_SplitImage(pRGB, w, h, 3, w * 3, (void**)pCh, w, 0);

       for (int c=0;c<3;c++)
       {
          BYTE *pL[levels];
          for (int i=0;i<levels;i++)
          {
             pL[i] = new BYTE[w * h];
          }

          is6_MultiscaleDecompose(pCh[c], w, h, w, levels-1, (void**)pL, w, 0);

          // blur level #2
          is6_GaussianBlurImage(pL[2], w, h, 1, w, p8, w, 50, 1);
          memcpy(pL[2],p8,w*h);

          // blur level #1 by a little less
          is6_GaussianBlurImage(pL[1], w, h, 1, w, p8, w, 15, 1);
          memcpy(pL[1],p8,w*h);

          is6_MultiscaleRecompose((void**)pL, w, h, w, levels, pCh[c], w, 0);

          for (int i=0;i<levels;i++)
          {
             delete [] pL[i];
          }
       }

       is6_CombineImageChannels((void**)pCh, w, h, 3, w, pRGBOut, w * 3, 0);


   Param             Use
   ------------------------------------
   pInImg            source image (BYTEs or 32-bit floats)
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of components per input pixel row
   uPasses           the number of high/low splits to make. See Notes.

   pOutImages        array of pointers to the buffers (BYET or float) which 
                     will receive the output images.

   uOutRowStride     number of components per output pixel row
   
   uFlags            bits     purpose
                     ---      -------
                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              11 - images have 32 bits per component (float) (val=0x600)
   
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_MultiscaleDecompose)(const void *pInImg, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, UINT passes, void **pOutImages, UINT32 uOutRowStride, UINT32 uFlags);


/*---------------------------------------------------------
   is6_MultiscaleRecompose

   Purpose : 
   Combine the images from is6_MultiscaleDecompose into a 
   single image.

   Param             Use
   ------------------------------------
   pInImages         source images
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of components per input pixel row

   uImages           number of images in pInImages, including
                     the residual image.

   pOutImg           receives the output image
   uOutRowStride     number of components per output pixel row
   
   uFlags            bits     purpose
                     ---      -------
                     9-10     00 - images have 8 bits per component  (BYTE) (val=0)
                              11 - images have 32 bits per component (float) (val=0x600)
   
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL        _ISCConv _ISFn(is6_MultiscaleRecompose)(const void **pInImages, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, UINT uImages, void *pOutImg, UINT32 uOutRowStride, UINT32 uFlags);

// currently these only apply to is6_SobelFilter and is6_BilateralFilterImage
#define IS_FILTER_NO_LEFT_BOUNDSCHECK    (1<<20)
#define IS_FILTER_NO_RIGHT_BOUNDSCHECK   (1<<21)
#define IS_FILTER_NO_TOP_BOUNDSCHECK     (1<<22)
#define IS_FILTER_NO_BOTTOM_BOUNDSCHECK  (1<<23)


#ifdef __cplusplus
}
#endif
