/*---------------------------------------------------------
   ISImageResize.h : part of the ImgSource library.
   
   Image resizing functions

   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

---------------------------------------------------------*/
#ifndef is6_IMAGERESIZEH
#define is6_IMAGERESIZEH

// shut up, stupid compiler!
#pragma warning(disable:4786)

#if !defined is6_SOURCEH && !defined is6_INTERNAL
#error Need to include ISource.h before this file.
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*---------------------------------------------------------
   is6_ResizeImage / _is6_ResizeImage

   Purpose : 
   Resize an image. 
   
   See ISTypes.h for C/C++ #defines for these resize modes.

   Note:
      These are the various resizing algorithms:

      Mode     Name                 Notes
      0        box filter 
      1        triangle filter
      2        Hamming filter
      3        Gaussian filter      min dimension : 2
      4        bell filter          min dimension : 2
      5        B-spline filter      min dimension : 2
      6        cubic 1 filter       min dimension : 2
      7        cubic 2 filter       min dimension : 2
      8        Lanczos3 filter      min dimension : 3
      9        Mitchell filter      min dimension : 2
      10       sinc filter          min dimension : 4
      11       Hermite filter
      12       Hanning filter
      13       Catrom filter        min dimension : 2
      14       area-average (fast)  Reduction only
      15       area-average         Reduction only
      16       bi-linear interpolation
      17       bi-cubic interpolation
      18       nearest neighbor     very fast, very ugly

   In general, modes 14 and up are faster than modes 0 through 13.
   
   Note:
   If images are 32-bit floats or 64-bit doubles, the following resizing 
   modes are avilable: 15, 16, 17, 18.

   Note:
   All modes except #18 have multithreaded processing options. See uFlags.

   Note:
   Only modes 14 and up are available for 16 bpc.

   Note:
   pImgIn != pImgOut

   Param             Use
   ------------------------------------
   pImgSrc           source image
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of components in a row of pixels, input
   pImgDest          destination image
   uOutWidth         output width
   uOutHeight        output height
   uOutRowStride     number of components in a row of pixels, output
   uComponentsPerPixel    components in a pixel (3 for RGB, 4 for RGBA, 1 for grayscale, etc)
   uMode             resize mode (see notes)

   uFlags            bit         use
                     ----         ---
                     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)

                      20         disable multithreaded processing

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
   _ISDeclSpec BOOL         _ISCConv _ISFn(is6_ResizeImage)(const void * pImgSrc, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, void *pImgDest, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, UINT32 uComponentsPerPixel, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeDIB / _is6_ResizeDIB

   Purpose : 
   Resize a DIB. 

   This makes a resized copy of the input DIB, and returns a 
   pointer to a new DIB. The output DIB will have the same bit 
   depth as the input image, and will use the same 
   palette (if the source uses a palette).

   See ISTypes.h for C/C++ #defines for these resize modes.

   Note:
   This for unregistered users, this call will draw a large red "X"
   on the output image.

   Note:
   This function is not available for unregistered users.

   Note:
   This will not resize RLE-compressed DIBs, and it will not
   resize 15,16 bit images that use BI_BITFIELD 'compression'.
   It will set the global error to IS_ERR_DEPTHMISMATCH (28)
   if you pass it a compressed DIB.

   Note:
   The resizing methods that are available depend on the input 
   bit depth:

   Bits Per Pixel       
   --------------

   1                 modes: 14, 15, 16

   4,8               modes 14, 15, 16, 18

   15,16,24,32       All resizing methods are available.


   Note:
   The caller is responsible for calling GlobalFree to release the
   memory associated with the returned DIB handle.

   Note:
   All modes except #18 have multithreaded processing options. See uFlags.

   Param             Use
   ------------------------------------
   pInDIB            input DIB
   uOutWidth         output width
   uOutHeight        output height
   phOutDIB          receives HGLOBAL handle to new DIB

   uMode             see is6_RESIZE_MODE_* flags


   uFlags            bit         use
                     ---         ---
                     20          disable multi-threaded processing (see is6_SetWorkerThreadCount)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
   _ISDeclSpec BOOL      _ISCConv _ISFn(is6_ResizeDIB)(const  BITMAPINFOHEADER *pInDIB, UINT32 uOutW, UINT32 uOutH, HGLOBAL *phOutDIB, UINT32 uMethod, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeImage8To24 / _is6_ResizeImage8To24

   Purpose : 
   Resize an eight-bit image into a 24 bit RGB image.

   This function is faster and less memory-intensive than converting 
   the 8-bit image to 24-bits then resizing.
   
   See ISTypes.h for C/C++ #defines for these resize modes.

   Note:
   Modes 1-13 have multithreaded processing options. See uFlags.

   Param             Use
   ------------------------------------
   pSrc              source image. this is an 8-bit per pixel image.
   uSrcWidthPix      input width in pixels
   uSrcHeight        input height
   uInRowStride      number of bytes per input row. generally uSrcWidthPix
   pDest             destination image (this must be at least uDestWidthPix * uDestHeight bytes)
   uDestWidthPix     output width
   uDestHeight       output height
   uOutRowStride     number of bytes per output row (generally uDestWidthPix * 3)
   pPal              input image palette

   uMode             the following resizing modes are avilable: 0-13, 14, 16. 
                     see is6_RESIZE_MODE_* flags

   uFlags            bit         use
                     ---         ---
                      0          swap red and blue values
                      20          disable multi-threaded processing (see is6_SetWorkerThreadCount)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn(is6_ResizeImage8To24)(const BYTE * pImgSrc, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pImgDest, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, const RGBQUAD *pPal, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeImage1To8Gray / _is6_ResizeImage1To8Gray

   Purpose : 
   Resize a one-bit image into an 8-bit grayscale image.
   
   This function is faster and less memory-intensive than converting 
   the 1-bit image to 8-bits then resizing.
   
   See ISTypes.h for C/C++ #defines for these resize modes.

   Note, for mode 14 only:
      This function is heavily optimized for certain reduction factors:

         1. uSrcWidthPix = uDestWidthPix * 2 AND
            uSrcHeight = uDestHeight * 2 AND
            uDestWidthPix is a multiple of 4

         2. uSrcWidthPix = uDestWidthPix * 4 AND
            uSrcHeight = uDestHeight * 4 AND
            uDestWidthPix is a multiple of 2

         3. uSrcWidthPix = uDestWidthPix * 8 AND 
            uSrcHeight is a multiple of uDestHeight 

         4. uSrcWidthPix = uDestWidthPix * 16 AND 
            uSrcHeight is a multiple of uDestHeight 

         5. uSrcWidthPix = uDestWidthPix * 32 AND 
            uSrcHeight is a multiple of uDestHeight 

   pImgIn != pImgOut

   Note:
   Modes 1-13 have multithreaded processing 
   options. See uFlags.

   Param             Use
   ------------------------------------
   pIn               source image. this is a 1-bit per pixel image. rows
                     must start on a whole byte boundary.

   uSrcWidthPix      input width in pixels
   uSrcHeight        input height
   uInRowStride      number of bytes per input row. generally (uSrcWidthPix + 7) / 8
   pOut              destination image
   uDestWidthPix     output width
   uDestHeight       output height
   uOutRowStride     number of bytes per output row (generally uDestWidthPix)

   uMode             the following resizing modes are avilable: 0-13, 14, 16. 
                     see is6_RESIZE_MODE_* flags

   uFlags            bit         use
                     ---         ---
                      0          if set, input pixels are treated as 0 = black, 1 = white
                                 else 1 = black, 0 = white

                     20          disable multi-threaded processing (see is6_SetWorkerThreadCount)

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ResizeImage1To8Gray )(const BYTE * pImgSrc, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pImgDest, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeImage8 / _is6_ResizeImage8

   Purpose : 
   Resize an eight-bit image.

   This function interpolates between pixels, then uses the image
   palette to find the best match to the interpolated color.
   
   See ISTypes.h for C/C++ #defines for these resize modes.

   pImgIn != pImgOut

   Param             Use
   ------------------------------------
   pSrc              source image. this is an 8-bit per pixel image.
   uSrcWidthPix      input width in pixels
   uSrcHeight        input height
   uInRowStride      number of bytes per input row. generally uSrcWidthPix
   pDest             destination image (this must be at least uDestWidthPix * uDestHeight bytes)
   uDestWidthPix     output width
   uDestHeight       output height
   uOutRowStride     number of bytes per output row
   pPal              input image palette
   uPalColors        number of colors in image palette

   uMode             the following resizing modes are avilable: 14, 16, 18. 
                     see is6_RESIZE_MODE_* flags

   uFlags            unused
            
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ResizeImage8 )(const BYTE * pImgSrc, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pImgDest, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, const RGBQUAD *pPal, UINT32 uPalColors, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeImage1 / _is6_ResizeImage1

   Purpose : 
   Resize a one bit per pixel image.

   Pixel rows must start on whole byte boundaries.

   This function interpolates between pixels, then uses the image
   palette to find the best match to the interpolated color.
   
   See ISTypes.h for C/C++ #defines for these resize modes.

   pImgIn != pImgOut

   Param             Use
   ------------------------------------
   pSrc              source image. this is an 1-bit per pixel image.
   uSrcWidthPix      input width in pixels
   uSrcHeight        input height
   uInRowStride      number of bytes per input row. generally uSrcWidthPix
   pDest             destination image (this must be at least uDestWidthPix * uDestHeight bytes)
   uDestWidthPix     output width
   uDestHeight       output height
   uOutRowStride     number of bytes per output row (generally uDestWidthPix * 3)
                       
   uCutOff           (mode 14 only) 
                     
                     value: 0..255

                     the lower you set this value, the more 
                     output pixels will be set to 0. 

                     If the detail of the image is mostly '0' pixels,
                     you should use higher values for the cutoff (ex. 192).
                     If the detail is mostly '1' pixels, you should use
                     lower values (ex. 64). 
                     
                     Using 128 for all cases will not give good results; 
                     you really must choose a value based on the types 
                     of images you are likely to process. is6_GetOneBitHistogram 
                     can help to determine detail/background colors.

   uMode             the following resizing modes are avilable: 14, 16. 
                     see is6_RESIZE_MODE_* flags

   uFlags            unused
            
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ResizeImage1 )(const BYTE * pImgSrc, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pImgDest, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, UINT32 uCutOff, UINT32 uMode, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ResizeImageMasked / _is6_ResizeImageMasked

   Purpose : 
   Resize an RGB/RGBA image using bi-linear interpolation. 
   Prevent color dithering for one RGB (or RGBA) value.

   pImage != pImageOut

   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uSrcRowStride     number of bytes in input row
   pImageOut         destination image
   uOutWidth         output width
   uOutHeight        output height
   uOutRowStride     number of bytes in output row
   clrMask           mask color
   uBytesPerPixel    3 or 4 (4 for RGBA)

   uFlags            Bit      Purpose
                     ---      -------
                      0       swap red and blue, if set

                      1       ignore A values in RGBA image when 
                              comparing pixel color (ie. only uses RGB values)

                      2       use old style (ImgSource v2) algorithm.
                              see Notes.
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL          _ISCConv _ISFn(is6_ResizeImageMasked)(const BYTE * pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uSrcRowStride, BYTE * pImageOut, UINT32 uOutWidth, UINT32 uOutHeight, UINT32 uOutRowStride, COLORREF clrMask, UINT32 uBytesPerPixel, UINT32 uFlags);

/*---------------------------------------------------------
   is6_Resize8Masked / _is6_Resize8Masked

   Purpose : 
   Resize an 8-bit image using bi-linear interpolation. 
   Prevent color dithering for one color index value.

   This can be useful in cases where one index is the
   "transparent" index and you don't want to blend the 
   transparent color into other colors.

   pIn != pOut

   Param             Use
   ------------------------------------
   pIn               source image
   uSrcWidthPix      width in pixels
   uSrcHeight        height
   uInRowStride      number of bytes per input row. generally uSrcWidthPix
   pOut              destination image
   uDestWidth        output width
   uDestHeight       output height
   uOutRowStride     number of bytes per output row. generally uDestWidth
   pPal              input image palette 
   uPalColors        number of entries in pPal ( < 256)
   clrMask           mask color

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL      _ISCConv _ISFn(is6_Resize8Masked)(const BYTE * pIn, UINT32 uSrcWidthPix, UINT32 uSrcHeight, UINT32 uInRowStride, BYTE * pOut, UINT32 uDestWidthPix, UINT32 uDestHeight, UINT32 uOutRowStride, const RGBQUAD *pPal, UINT32 uColors, BYTE maskIdx);

////////////////////////////////////////////////////////////////

/*---------------------------------------------------------
   is6_SeamCarve

   Purpose : 
   Resize an image horizontally by removing areas of low pixel energy. 
   It can also enlarge an image horizontally, by enlarging areas of
   low energy. The effect is that the overall image is resized but 
   foreground features are not resized at all - it effectively 
   removes (or increases) background area.
   
   It can also be directed to selectively target areas of the image 
   for deletion by use of a mask image. See Notes.

   This uses an algorithm developed by Shai Avidan and Ariel Shamir
   and described in their paper "Seam Carving for Content-Aware 
   Image Resizing". Basically it removes (or enlarges) those areas 
   in an image where the differences between neighboring pixels is 
   lower than it is in other areas - in other words, it looks for 
   contrast changes, edges and noise, assumes this is the important
   part of the image and seeks to remove other areas.

   The results from this function are completely dependent on the
   input image. Images where the background is relatively uniform
   and distinct from the foreground do much better than images
   with lots of edges and details.

   Notes:

   * There is some randomness built into the function, so running
   the function twice on the same image will give slightly different
   images.

   * This is a complex operation, and can take many seconds, for a 
   large image, even on a fast machine.

   * If you want to remove pixels vertically, you should rotate the 
   image 90 degrees.

   * Mask image. A mask image can be used to selectively preserve
   or delete areas of the image. The mask image is an 8-bit image, 
   the same dimensions as the source image. Pixels with mask values 
   below 128 will tend to be removed by the function, the lower the 
   value, the more effect. Pixels with mask values above 128 will 
   tend to be preserved. The higher the value, the more the effect.
   128 is the neutral value.

   Param             Use
   ------------------------------------
   pInRGB            input RGB-24 (or RGBA-32) image
   inW               input width
   inH               input height
   uBPP              bytes per pixel
   uInRowStride      bytes per input row
   pMask8            mask image. NULL if unused.
   uMaskRowStride    bytes per input row, mask
   pOutRGB           output image ((inW + iSeams) * inH pixels)
   uOutRowStride     bytes per image row, output
   iSeams            number of seams (pixels) to add or subtract

   newSeamWeight     when adding seams, this weight is added to the 
                     area around the last added seam, in the internal 
                     contrast map representation of the image, to 
                     discourage the algorithm from  re-using the same 
                     seam over and over.

                     0 to 65000 is possible, but 1000 is a good default.

                     values that are low have less effect, and the 
                     algorithm will tend to stick to the same area,
                     creating ugly banding effects.

                     if the value is too high, the seam-finding algorithm 
                     will be unable to cross previous seams and that could
                     lead to sub-optimal results.

   uFlags            Bit      Use
                     ---      ---
                      0       if set, this will use a single thread
                              to compute the energy map. the energy map
                              computation accounts for 90% of the work in 
                              this function, and for large images, adding
                              another thread to the process can increase 
                              performance. for small images, the single
                              thread is much faster. the exact limit
                              between "large" and "small" will depend on 
                              the CPU in use, but in our testing, "large"
                              is in the range of 2000x2000 pixels.

   

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL _ISCConv _ISFn(is6_SeamCarve) (const BYTE *pInRGB, UINT32 inW, UINT32 inH, UINT32 uBPP, UINT32 uInRowStride, const BYTE *pMask8, UINT32 uMaskRowStride, BYTE *pOutRGB, UINT32 uOutRowStride, int iSeams, ISUINT16 newSeamWeight, UINT32 uFlags);

_ISDeclSpec BOOL     _ISCConv  _ISFn(is6_ResizeScale2X)(const BYTE * pSrc,
                                   UINT32 uSrcWidth,
                                   UINT32 uSrcHeight,
                                   UINT32 uSrcRowStride,
                                   UINT32 uBPP,
                                   BYTE * pDest,
                                   UINT32 uDestRowStride,
                                   UINT32 uFlags);

#ifdef __cplusplus
}
#endif

#endif