//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
#ifndef _id3FaceImage_h
#define _id3FaceImage_h

#include <id3Face/id3FaceExports.h>
#include <id3Face/id3FacePixelFormat.h>
#include <id3Face/id3FaceImage.h>
#include <id3Face/id3FaceRectangle.h>
#include <id3Face/id3FaceImageFormat.h>
#include <id3Face/id3FaceImageBuffer.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C"
{
#endif

/**
 * Represents an image.
 */

/**
 * Handle to a Image object of the Face module.
 */
typedef struct id3FaceImage *ID3_FACE_IMAGE;

/**
 * @brief Initializes a Image object.
 * @param phImage [in] Handle to the Image object.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Initialize(ID3_FACE_IMAGE *phImage);

/**
 * @brief Releases the memory allocated for a Image.
 * @param phImage [in] Handle to the Image object.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Dispose(ID3_FACE_IMAGE *phImage);

/**
 * @brief Checks if the handle object is valid.
 * @param hImage [in] Handle to the Image object.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_CheckHandle(ID3_FACE_IMAGE hImage);

/**
 * @brief Copies an instance of Image object to another.
 * @param hImageSrc [in] Handle to the source Image object.
 * @param hImageDst [in] Handle to the destination Image object.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_CopyTo(ID3_FACE_IMAGE hImageSrc, ID3_FACE_IMAGE hImageDst);

/**
 * Gets the raw data buffer of the image.
 * @param hImage [in] Handle to the Image object.
 * @param data [out] Raw data buffer of the image.
 * @param dataSize [in,out] Size of the 'data' buffer. Receives the number of elements in the 'data' array.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetData(ID3_FACE_IMAGE hImage, unsigned char *data, int *dataSize);

/**
 * Gets the height in pixels.
 * @param hImage [in] Handle to the Image object.
 * @param height [out] Height in pixels.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetHeight(ID3_FACE_IMAGE hImage, int *height);

/**
 * Gets the pixel depth.
 * @param hImage [in] Handle to the Image object.
 * @param pixelDepth [out] Pixel depth.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetPixelDepth(ID3_FACE_IMAGE hImage, int *pixelDepth);

/**
 * Gets the pixel format.
 * @param hImage [in] Handle to the Image object.
 * @param ePixelFormat [out] Pixel format.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetPixelFormat(ID3_FACE_IMAGE hImage, id3FacePixelFormat *ePixelFormat);

/**
 * Gets the stride in bytes.
 * @param hImage [in] Handle to the Image object.
 * @param stride [out] Stride in bytes.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetStride(ID3_FACE_IMAGE hImage, int *stride);

/**
 * Gets the width in pixels.
 * @param hImage [in] Handle to the Image object.
 * @param width [out] Width in pixels.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetWidth(ID3_FACE_IMAGE hImage, int *width);

/**
 * Computes the difference with another image.
 * @param hImage [in] Handle to the Image object.
 * @param hCmpImage [in] The image to compare.
 * @param result [out] Comparison result in percent (0% is same, 100% is full different).
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Compare(ID3_FACE_IMAGE hImage, ID3_FACE_IMAGE hCmpImage, float *result);

/**
 * Applies a gamma correction to the image.
 * @param hImage [in] Handle to the Image object.
 * @param contrast [in] Contrast coefficient, from -255 to 255, to be applied to the image.
 * @param brightness [in] Brightness coefficient, from -255 to 255, to be applid to the image.
 * @param gamma [in] Gamma coefficient, from 0.25 to 2.50, to be applied to the image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_CorrectGamma(ID3_FACE_IMAGE hImage, int contrast, int brightness, float gamma);

/**
 * Crop a rectangular region of interest in the image according to the given bounds.
 * @param hImage [in] Handle to the Image object.
 * @param left [in] Left bound of the crop to extract.
 * @param top [in] Top bound of the crop to extract.
 * @param width [in] Width of the crop to extract.
 * @param height [in] Height of the crop to extract.
 * @param hImageCrop [out] The extracted region of interest.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Crop(ID3_FACE_IMAGE hImage, int left, int top, int width, int height, ID3_FACE_IMAGE hImageCrop);

/**
 * Downscales the image in-place so that its maximum dimension is equal to the given maximum size, while preserving the aspect ratio.
 * Note: If the maximum dimension is already smaller than the given maximum size, the function does nothing and the scaling ration returned is 1.
 * @param hImage [in] Handle to the Image object.
 * @param maxSize [in] Maximum image size, in pixels. The value must be greater than 0.
 * @param scaleRatio [out] The scaling ratio applied to the image. Range is ]0:1].
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Downscale(ID3_FACE_IMAGE hImage, int maxSize, float *scaleRatio);

/**
 * Downscales the image so that its maximum dimension equals the given maximum size, while preserving the aspect ratio.
 * Note: If the maximum dimension is already smaller than the given maximum size, the function does nothing and the returned scale ratio is 1.
 * @param hImage [in] Handle to the Image object.
 * @param hDstImage [in] Destination image.
 * @param maxSize [in] Maximum image size, in pixels. The value must be greater than 0.
 * @param scaleRatio [out] The scaling ratio applied to the image. Range is ]0:1].
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_DownscaleTo(ID3_FACE_IMAGE hImage, ID3_FACE_IMAGE hDstImage, int maxSize, float *scaleRatio);

/**
 * Extracts a region of interest in the image according to the given bounds.
 * @param hImage [in] Handle to the Image object.
 * @param sBounds [in] Bounds of the crop to extract.
 * @param hImageRoi [out] The extracted region of interest.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ExtractRoi(ID3_FACE_IMAGE hImage, const id3FaceRectangle *sBounds, ID3_FACE_IMAGE hImageRoi);

/**
 * Extracts a region of interest in the image according to the given bounds.
 * @param hImage [in] Handle to the Image object.
 * @param sBounds [in] Bounds of the crop to extract.
 * @param colorRed [in] Background color red (from 0 to 255)
 * @param colorGreen [in] Background color green (from 0 to 255)
 * @param colorBlue [in] Background color blue (from 0 to 255)
 * @param hImageRoi [out] The extracted region of interest.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ExtractRoiWithColor(ID3_FACE_IMAGE hImage, const id3FaceRectangle *sBounds, int colorRed, int colorGreen, int colorBlue, ID3_FACE_IMAGE hImageRoi);

/**
 * Flips the image in-place.
 * @param hImage [in] Handle to the Image object.
 * @param flipHorizontally [in] Value indicating whether the image should be flipped horizontally.
 * @param flipVertically [in] Value indicating whether the image should be flipped vertically.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Flip(ID3_FACE_IMAGE hImage, bool flipHorizontally, bool flipVertically);

/**
 * Flips the image.
 * @param hImage [in] Handle to the Image object.
 * @param flipHorizontally [in] Value indicating whether the image should be flipped horizontally.
 * @param flipVertically [in] Value indicating whether the image should be flipped vertically.
 * @param hDstImage [in] The destination Image object that receives the flipped image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_FlipTo(ID3_FACE_IMAGE hImage, bool flipHorizontally, bool flipVertically, ID3_FACE_IMAGE hDstImage);

/**
 * Creates an Image from the specified data buffer.
 * @param hImage [in] Handle to the Image object.
 * @param data [in] A buffer that contains the image data.
 * @param dataSize [in] Size of the 'data' buffer.
 * @param ePixelFormat [in] The destination pixel format to convert the input to.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_FromBuffer(ID3_FACE_IMAGE hImage, unsigned char *data, int dataSize, id3FacePixelFormat ePixelFormat);

/**
 * Creates an Image from the specified file.
 * @param hImage [in] Handle to the Image object.
 * @param filepath [in] A string that contains the name of the file from which to create the Image.
 * @param ePixelFormat [in] The pixel format into which to convert the input image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_FromFile(ID3_FACE_IMAGE hImage, const char *filepath, id3FacePixelFormat ePixelFormat);

/**
 * Creates an Image from the specified raw data buffer.
 * @param hImage [in] Handle to the Image object.
 * @param pixels [in] A buffer that contains image pixels.
 * @param pixelsSize [in] Size of the 'pixels' buffer.
 * @param width [in] The width, in pixels, of the image.
 * @param height [in] The height, in pixels, of the image.
 * @param stride [in] The stride, in pixels, of the image.
 * @param eSrcPixelFormat [in] The pixel format of the input image.
 * @param eDstPixelFormat [in] The pixel format into which to convert the input image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_FromRawBuffer(ID3_FACE_IMAGE hImage, unsigned char *pixels, int pixelsSize, int width, int height, int stride, id3FacePixelFormat eSrcPixelFormat, id3FacePixelFormat eDstPixelFormat);

/**
 * Creates an Image from the specified YUV planes.
 * @param hImage [in] Handle to the Image object.
 * @param yPlane [in] A buffer that contains the Y plane.
 * @param yPlaneSize [in] Size of the 'yPlane' buffer.
 * @param uPlane [in] A buffer that contains the U plane.
 * @param uPlaneSize [in] Size of the 'uPlane' buffer.
 * @param vPlane [in] A buffer that contains the V plane.
 * @param vPlaneSize [in] Size of the 'vPlane' buffer.
 * @param yWidth [in] The width, in pixels, of the Y plane.
 * @param yHeight [in] The height, in pixels, of the Y plane.
 * @param uvPixelStride [in] The pixel-level stride, in pixels, of the U and V planes.
 * @param uvRowStride [in] The row-level stride, in pixels, of the U and V planes.
 * @param eDstPixelFormat [in] The pixel format into which to convert the input image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_FromYuvPlanes(ID3_FACE_IMAGE hImage, unsigned char *yPlane, int yPlaneSize, unsigned char *uPlane, int uPlaneSize, unsigned char *vPlane, int vPlaneSize, int yWidth, int yHeight, int uvPixelStride, int uvRowStride, id3FacePixelFormat eDstPixelFormat);

/**
 * Gets a pointer to the image pixels.
 * Warning: This method is unsafe! The user must handle the pixels pointer carefully.
 * @param hImage [in] Handle to the Image object.
 * @param pixels [out] Pointer to the image pixels.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_GetPixels(ID3_FACE_IMAGE hImage, void **pixels);

/**
 * Add padding around the image
 * Only works for BGR 24 bits, RGB 24 bits and Grayscale 8bits images.
 * For grayscale image, the padding color is the red component.
 * @param hImage [in] Handle to the Image object.
 * @param top [in] Padding on top.
 * @param left [in] Padding on left.
 * @param bottom [in] Padding on bottom.
 * @param right [in] Padding on right.
 * @param colorRed [in] Padding color red (from 0 to 255)
 * @param colorGreen [in] Padding color green (from 0 to 255)
 * @param colorBlue [in] Padding color blue (from 0 to 255)
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Pad(ID3_FACE_IMAGE hImage, int top, int left, int bottom, int right, int colorRed, int colorGreen, int colorBlue);

/**
 * Reallocates the internal memory of the Image from parameters.
 * Note: If the given parameters are the same as the ones of the object, then there is nothing done in this function.
 * @param hImage [in] Handle to the Image object.
 * @param width [in] The new width, in pixels.
 * @param height [in] The new height, in pixels.
 * @param ePixelFormat [in] The new pixel format.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Reallocate(ID3_FACE_IMAGE hImage, int width, int height, id3FacePixelFormat ePixelFormat);

/**
 * Resizes the image in-place to the required width and height.
 * @param hImage [in] Handle to the Image object.
 * @param width [in] The new width, in pixels.
 * @param height [in] The new height, in pixels.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Resize(ID3_FACE_IMAGE hImage, int width, int height);

/**
 * Resizes the image to the specified width and height.
 * @param hImage [in] Handle to the Image object.
 * @param width [in] The new width, in pixels.
 * @param height [in] The new height, in pixels.
 * @param hDstImage [in] The destination image that receives the resized image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ResizeTo(ID3_FACE_IMAGE hImage, int width, int height, ID3_FACE_IMAGE hDstImage);

/**
 * Rotates the image in-place to the specified angle.
 * Note: The rotation is performed counter-clockwise.
 * @param hImage [in] Handle to the Image object.
 * @param angle [in] The rotation angle, in degree. Supported values are [0, 90, 180, 270].
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Rotate(ID3_FACE_IMAGE hImage, int angle);

/**
 * Rotates the image to the specified angle.
 * Note: The rotation is performed counter-clockwise.
 * @param hImage [in] Handle to the Image object.
 * @param angle [in] The rotation angle, in degree. Supported values are [0, 90, 180, 270].
 * @param hDstImage [in] The destination Image that receives the rotated image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_RotateTo(ID3_FACE_IMAGE hImage, int angle, ID3_FACE_IMAGE hDstImage);

/**
 * Sets the Image object fields.
 * Warning: This function does not allocate any memory and is unsafe! The user must handle the pixels pointer carefully.
 * @param hImage [in] Handle to the Image object.
 * @param width [in] The width, in pixels, of the image.
 * @param height [in] The height, in pixels, of the image.
 * @param ePixelFormat [in] The pixel format of the image.
 * @param pixels [in] A pointer to the image pixels of the image.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Set(ID3_FACE_IMAGE hImage, int width, int height, id3FacePixelFormat ePixelFormat, void *pixels);

/**
 * Exports the image to a buffer.
 * The compression level meaning depends on the algorithm used:
 * - For JPEG compression, the value is the expected quality and may vary from 1 to 100.
 * - For JPEG2000 compression, the value is the compression rate and may vary from 1 to 512.
 * - For PNG compression, the value is the compression rate and may vary from 1 to 10.
 * - For all other formats, the value is ignored.
 * @param hImage [in] Handle to the Image object.
 * @param eImageFormat [in] The image format to export the image to.
 * @param compressionLevel [in] The compression level to be applied.
 * @param data [out] Buffer that receives the image data.
 * @param dataSize [in,out] Size of the 'data' buffer. Receives the number of elements in the 'data' array.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ToBuffer(ID3_FACE_IMAGE hImage, id3FaceImageFormat eImageFormat, float compressionLevel, unsigned char *data, int *dataSize);

/**
 * Copies the image to a buffer in the specified format.
 * The compression level meaning depends on the algorithm used:
 * - For JPEG compression, the value is the expected quality and may vary from 1 to 100.
 * - For JPEG2000 compression, the value is the compression rate and may vary from 1 to 512.
 * - For PNG compression, the value is the compression rate and may vary from 1 to 10.
 * - For all other formats, the value is ignored.
 * @param hImage [in] Handle to the Image object.
 * @param eImageFormat [in] The output image format.
 * @param compressionLevel [in] The compression level to be applied.
 * @param hBuffer [in] The image buffer that receives the image data.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ToBufferObject(ID3_FACE_IMAGE hImage, id3FaceImageFormat eImageFormat, float compressionLevel, ID3_FACE_IMAGE_BUFFER hBuffer);

/**
 * Saves the image to the specified file.
 * The compression level meaning depends on the algorithm used:
 * - For JPEG compression, the value is the expected quality and may vary from 1 to 100.
 * - For JPEG2000 compression, the value is the compression rate and may vary from 1 to 512.
 * - For PNG compression, the value is the compression rate and may vary from 1 to 10.
 * - For all other formats, the value is ignored.
 * @param hImage [in] Handle to the Image object.
 * @param filepath [in] A string that contains the name of the file to which to save the image.
 * @param compressionLevel [in] The compression level to be applied.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ToFile(ID3_FACE_IMAGE hImage, const char *filepath, float compressionLevel);

/**
 * Copies image pixels in the specified format into a buffer.
 * @param hImage [in] Handle to the Image object.
 * @param ePixelFormat [in] The pixel format.
 * @param hBuffer [in] Buffer that receives the raw image data.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_ToRawBuffer(ID3_FACE_IMAGE hImage, id3FacePixelFormat ePixelFormat, ID3_FACE_IMAGE_BUFFER hBuffer);

/**
 * Transposes the image object.
 * @param hImage [in] Handle to the Image object.
 * @return An error code. See id3FaceError file for the list of possible error codes.
 * @retval id3FaceError_Success The function succeeded.
 */
ID3FACE_C_API int ID3_CDECL id3FaceImage_Transpose(ID3_FACE_IMAGE hImage);

#ifdef __cplusplus
}
#endif

#endif
