/*---------------------------------------------------------
   ISImageRotate.h : part of the ImgSource library.
   
   Image processing 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_IMAGEROTATEH
#define is6_IMAGEROTATEH

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

#ifdef __cplusplus
extern "C" {
#endif

/*---------------------------------------------------------
   is6_RotateImage / _is6_RotateImage

   Purpose : 
   Rotate an image. Output buffer must be allocated by the 
   caller. See is6_GetRotatedBufComponents and/or is6_GetRotatedPixelSize 
   to determine the size of the output buffer.


   Note:
   If you have an 8-bit image which uses a palette, it is
   probably _much_ faster to convert the image to RGB-24 with 
   is6_8BitToRGB, rotate that, then convert back to 8-bit with 
   is6_RGBTo8BitBestFit or is6_RGBTo8BitDithered. 

   If you have a 256-color 8-bit grayscale image, however,
   you can use the image as-is, with no performance penalty.

   Param                Use
   ------------------------------------
   pInBuf               source image
   uWidth               width in pixels
   uHeight              height
   
   uComponentsPerPixel  1, 3 or 4
   
   uInRowStride         uComponentsPerPixel per pixel row, input

   pOut                 output buffer. allocated by the caller.

                        the caller should fill this buffer with a
                        color or pattern before calling this function.
                        that color or pattern will appear on the corners
                        of the image (where the rotated image doesn't cover).

   uOutRowStride        number of uComponentsPerPixel in an output pixel row

   pPal                 palette for 8-bit images.
                        this not used when in "fast" mode, or when 
                        input is 8-bit grayscale (see uFlags).

   uPalColors           number of colors in pPal
   
   fRadians             rotation angle, in radians

   uFlags               bit         purpose
                        ---         -------
                        1-0         00 (uFlags = 0) - use a fast but 
                                    sloppy rotation algorithm. 
                                    
                                    01 (uFlags = 1) - use bi-linear interpolation.
                                    the results are far better than the
                                    'fast' method. however, this is much 
                                    slower, especially with 8-bit images 
                                    which require a palette.

                                    10 (uFlags = 2) - use bi-cubic interpolation.
                                    the results are better than bi-linear,
                                    but require even more time to process. this 
                                    method cannot be used with 8-bit images which 
                                    require a palette.

                        2           8-bit images are grayscale. no palette 
                                    required.

                        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_RotateImage)(const void  *inBuf, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel, UINT32 uInRowStride, void *pOut, UINT32 uOutRowStride, RGBQUAD *pPal, UINT32 uPalColors, double radians, UINT32 uFlags);

/*---------------------------------------------------------
   is6_RotateOneBitImage / _is6_RotateOneBitImage

   Purpose : 
   Rotate a one-bit image. Output buffer must be allocated 
   by the caller. See is6_GetRotatedPixelSize to determine the 
   size of the output buffer.

   Param                Use
   ------------------------------------
   pInBuf               source image
   uWidth               width in pixels
   uHeight              height
   
   uInRowStride         bytes per pixel row, input

   pOut                 output buffer. allocated by the caller
   uOutRowStride        number of bytes in an output pixel row

   fRadians             rotation angle, in radians

   uFlags               bit         purpose
                        ---         -------
                        1-0         00 (uFlags = 0) - use bi-linear interpolation.
                                    the results are slightly better than the
                                    fast method. 

                                    01 (uFlags = 1) - use a fast but 
                                    sloppy rotation algorithm. 

                        20          disable multithreaded processing
   Return
   ------
      FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_RotateOneBitImage )(BYTE *inBuf, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pOut, UINT32 uOutRowStride, double radians, UINT32 uFlags);

/*---------------------------------------------------------
   is6_GetRotatedBufComponents / _is6_GetRotatedBufComponents

   Purpose : 
   Determine the number of pixel components required to hold 
   an image rotated by is6_RotateImage. 

   If the image components are doubles, multiply this value
   by 16.

   Param                Use
   ------------------------------------
   fRadians             rotation angle, in radians
   uWidth               source width in pixels
   uHeight              source height
   uComponentsPerPixel  bytes per image pixel

   uFlags               bit         purpose
                        ---         -------
                        10          image components are 64-bit doubles

   Return
   ------
   number of components
---------------------------------------------------------*/
_ISDeclSpec UINT32      _ISCConv _ISFn(is6_GetRotatedBufComponents)(double radians, UINT32 uWidth, UINT32 uHeight, UINT32 uComponentsPerPixel);

/*---------------------------------------------------------
   is6_GetRotatedPixelSize / _is6_GetRotatedPixelSize

   Purpose : 
   Determine the number of pixels required to hold an image
   rotated by is6_RotateImage. 

   ex.
      UINT32 rotatedWidth = 0;
      UINT32 rotatedHeight = 0 ;
      is6_GetRotatedPixelSize(rads, sourceW, sourceH, &rotatedWidth, &rotatedHeight);

      UINT32 rotatedRowStride = rotatedWidth * uBytesPerPixel;

      // alloc output
      BYTE *p = new ISNEWSPEC BYTE[rotatedRowStride * rotatedHeight];

      // fill the buffer at "p" with 0's (black)
      memset(p, 0, rotatedRowStride * rotatedHeight);

      // rotate
      is6_RotateImage(pSource, sourceW, sourceH, 3, sourceW * 3, 
                     p, rotatedRowStride, 
                     NULL, 0, rads, 0);

   Param                Use
   ------------------------------------
   fRadians             rotation angle, in radians
   uWidth               source width in pixels
   uHeight              source height
   pWidth               receives output width (in pixels)
   pHeight              recieves output height

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_GetRotatedPixelSize )(double radians, UINT32 uWidth, UINT32 uHeight, UINT32 *pWidth, UINT32 *pHeight);

/*---------------------------------------------------------
   is6_QuickRotateImageInPlace / _is6_QuickRotateImageInPlace

   Purpose : 
   Rotate an image in multiples of 90 degrees
   This performs the rotation in-place. Be sure to 
   note that the image dimensions will change when
   rotating 90 or 270 degrees! (width and height will 
   reverse)

   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height

   uRotate           rotation selector
                           0 - 90 degrees cw
                           1 - 180 deg
                           2 - 270 deg cw

   uChannelsPerPixel components per image pixel

   uFlags            bit      purpose
                     ---      -------
                     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_QuickRotateImageInPlace )(void *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uRotate, UINT32 uChannels, UINT32 uFlags);

/*---------------------------------------------------------
   is6_QuickRotateImage / _is6_QuickRotateImage

   Purpose : 
   Rotate an image in multiples of 90 degrees.
   
     
   Be sure to note that the image dimensions will change 
   when rotating 90 or 270 degrees! (width and height will 
   reverse)

   Param                Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uInRowStride      components per input pixel row
   pOutput           output image, allocated by the caller
   uOutRowStride     components per pixel row, output

   uRotate           rotation selector
                           0 - 90 degrees cw
                           1 - 180 deg
                           2 - 270 deg cw

   uChannelsPerPixel components per image pixel

   uFlags            bit      purpose
                     ---      -------
                     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_QuickRotateImage )(const void *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, void *pOutput, UINT32 uOutRowStride, UINT32 uRotate, UINT32 uChannelsPerPixel, UINT32 uFlags);


/*---------------------------------------------------------
   is6_QuickRotate1Bit / _is6_QuickRotate1Bit

   Purpose : 
   Rotate a 1-bit image multiples of 90 degrees.

   Note:
   When rotating 90 or 270 degrees, output width
   and height are swapped, with respect to input
   width & height.

   Note:
   The source and destination image buffers will not
   be the same size.
   

   Param                Use
   ------------------------------------
   pInBuf               source image
   uWidth               source width in pixels
   uHeight              source height
   uInRowStride         bytes per input pixel row
   pOutBuf              output image
   uOutRowStride        bytes per output pixel row

   uRotate              rotation mode
                           0 - 90 degrees cw
                           1 - 180 deg
                           2 - 270 deg cw

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_QuickRotate1Bit )(BYTE *pInBuf, UINT32 nInWidth, UINT32 nInHeight, UINT32 uInRowStride, BYTE *pOutBuf, UINT32 uOutRowStride, UINT32 uRotate);

/*---------------------------------------------------------
   is6_ShearImageX / _is6_ShearImageX

   Purpose : 
   Shear an image. This slides the top (or bottom)
   of an image by xOffset pixels. (width increases)

   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uBytesPerPixel    bytes per pixel in source image (1, 3 or 4)
   uInRowStride      number of bytes in source image row

   pOut              output buffer - allocated by caller
                     buffer must be at least (uWidth + abs(xOffset)) * uHeight * uBytesPerPixel  BYTEs 

   xOffset           if > 0, the top of the image is offset and this value is
                     the distance to offset the top row of the output 
                     image from the top-left corner.
                     if < 0, the bottom of the image is offset and this value 
                     is the distance to offset the bottom row from the 
                     bottom-left corner.

   uOutRowStride     number of bytes in output image row

   clrBack           color to fill the background
   bFast             if TRUE, use a fast but less accurate method
   pPal              palette, for 8-bit images. ignored if bFast is TRUE
   uPalColors        colors in pPal

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ShearImageX )(BYTE *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uBytesPerPixel, UINT32 uInRowStride, BYTE *pOut, __int32 xOffset, UINT32 uOutRowStride, COLORREF clrBack, BOOL bFast, RGBQUAD *pPal, UINT32 uPalColors);

/*---------------------------------------------------------
   is6_ShearImageY / _is6_ShearImageY

   Purpose : 
   Shear an image. This slides the left (or right)
   of an image by yOffset pixels. (height increases)


   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uBytesPerPixel    bytes per pixel in source image (1, 3 or 4)
   uInRowStride      number of bytes in source image row

   pOut              output buffer - allocated by caller
                     buffer must be uInRowStride * (uHeight + abs(yOffset)) BYTEs 

   yOffset           if > 0, the left of the image is offset and this value is
                     the distance to offset the leftmost column of the output 
                     image from the top-left corner.

                     if < 0, the right of the image is offset and this value 
                     is the distance to offset the rightmost column from the 
                     top-right corner.
               
   uOutRowStride     number of bytes in output image row

   clrBack           color to fill the background
   bFast             if TRUE, use a fast but less accurate method
   pPal              palette, for 8-bit images. ignored if bFast is TRUE
   uPalColors        colors in pPal

   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ShearImageY )(BYTE *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uBytesPerPixel, UINT32 uInRowStride, BYTE *pOut, __int32 yOffset, UINT32 uOutRowStride, COLORREF clrBack, BOOL bFast, RGBQUAD *pPal, UINT32 uPalColors);

/*---------------------------------------------------------
   is6_ShearOneBitX / _is6_ShearOneBitX

   Purpose : 
   Shear an image. This slides the top (or bottom)
   of an image by xOffset pixels. (width increases)

   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of bytes in source image row

   pOut              output buffer - allocated by caller
                     buffer must be at least (uWidth + abs(xOffset)) * uHeight * uBytesPerPixel  BYTEs 

   xOffset           if > 0, the top of the image is offset and this value is
                     the distance to offset the top row of the output 
                     image from the top-left corner.
                     if < 0, the bottom of the image is offset and this value 
                     is the distance to offset the bottom row from the 
                     bottom-left corner.

   uOutRowStride     number of bytes in output image row

   uFlags            bit         purpose
                     ---         -------
                      0          value to put in image background
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ShearOneBitX )(BYTE *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pOut, __int32 xOffset, UINT32 uOutRowStride, UINT32 uFlags);

/*---------------------------------------------------------
   is6_ShearOneBitY / _is6_ShearOneBitY

   Purpose : 
   Shear a one bit per pixel image. This slides the left (or right) side
   of an image by yOffset pixels. (height increases)

   Param             Use
   ------------------------------------
   pImage            source image
   uWidth            width in pixels
   uHeight           height
   uInRowStride      number of bytes in source image row

   pOut              output buffer - allocated by caller
                     buffer must be uInRowStride * (uHeight + abs(yOffset)) BYTEs 

   yOffset           if > 0, the left of the image is offset and this value is
                     the distance to offset the leftmost column of the output 
                     image from the top-left corner.

                     if < 0, the right of the image is offset and this value 
                     is the distance to offset the rightmost column from the 
                     top-right corner.
               
   uOutRowStride     number of bytes in output image row

   uFlags            bit         purpose
                     ---         -------
                      0          value to put in image background
   Return
   ------
   FALSE on failure
---------------------------------------------------------*/
_ISDeclSpec BOOL         _ISCConv _ISFn( is6_ShearOneBitY )(BYTE *pImage, UINT32 uWidth, UINT32 uHeight, UINT32 uInRowStride, BYTE *pOut, __int32 yOffset, UINT32 uOutRowStride, UINT32 uFlags);

#ifdef __cplusplus
}
#endif
#endif