#ifndef IMAGE_H
#define IMAGE_H

#if defined(_WIN64)
    typedef __int64 INT_PTR, *PINT_PTR;
    typedef unsigned __int64 UINT_PTR, *PUINT_PTR;

    typedef __int64 LONG_PTR, *PLONG_PTR;
    typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;

#else
	#if !defined(INT_PTR)
    typedef  int INT_PTR, *PINT_PTR;
	#endif
	#if !defined(UINT_PTR)
    typedef  unsigned int UINT_PTR, *PUINT_PTR;
	#endif

    #if !defined(LONG_PTR)
	typedef  long LONG_PTR, *PLONG_PTR;
	#endif
	#if !defined(ULONG_PTR)
    typedef  unsigned long ULONG_PTR, *PULONG_PTR;
	#endif

#endif

#include <windowsx.h>
#include <windows.h>

#include <memory.h>  // memset()
#include <stdlib.h>  // rand()
#include <tchar.h>

#include <ocidl.h>



int KWIKdecode64(const char *line, BYTE *out, int len =0, int nMax = -1);
int Encode64(const BYTE *src, int srclength, char *target, int targsize);


#include "include\gdiplus.h"
using namespace Gdiplus;

typedef enum {
    DitherTypeNone = 0,
    DitherTypeSolid = 1,
    DitherTypeOrdered4x4 = 2,
    DitherTypeOrdered8x8 = 3,
    DitherTypeOrdered16x16 = 4,
    DitherTypeOrdered91x91 = 5,
    DitherTypeSpiral4x4 = 6,
    DitherTypeSpiral8x8 = 7,
    DitherTypeDualSpiral4x4 = 8,
    DitherTypeDualSpiral8x8 = 9,
    DitherTypeErrorDiffusion = 10
} DitherType;

typedef enum {
    PaletteTypeCustom = 0,
    PaletteTypeOptimal = 1,
    PaletteTypeFixedBW = 2,
    PaletteTypeFixedHalftone8 = 3,
    PaletteTypeFixedHalftone27 = 4,
    PaletteTypeFixedHalftone64 = 5,
    PaletteTypeFixedHalftone125 = 6,
    PaletteTypeFixedHalftone216 = 7,
    PaletteTypeFixedHalftone252 = 8,
    PaletteTypeFixedHalftone256 = 9
} PaletteType;



typedef GpStatus (WINGDIPAPI* PGDIPLUSSTARTUP)(  ULONG_PTR *token, const GdiplusStartupInput *input, GdiplusStartupOutput *output);
typedef GpStatus (WINGDIPAPI* PGDIPLUSSHUTDOWN) (ULONG_PTR token);
typedef GpStatus (WINGDIPAPI* PGDIPGETIMAGEWIDTH) (GpImage *image, UINT *width);
typedef GpStatus (WINGDIPAPI* PGDIPGETIMAGEHEIGHT) (GpImage *image, UINT *height);
typedef GpStatus (WINGDIPAPI* PGDIPLOADIMAGEFROMFILE) (GDIPCONST WCHAR* filename, GpImage **image);
typedef GpStatus (WINGDIPAPI* PGDIPLOADIMAGEFROMSTREAM) (IStream* stream, GpImage **image);
typedef GpStatus (WINGDIPAPI* PGDIBITMAPCONVERTFORMAT)(GpBitmap *pInputBitmap, PixelFormat format, DitherType dithertype, PaletteType palettetype, ColorPalette *palette, REAL alphaThresholdPercent);
typedef GpStatus (WINGDIPAPI* PGDIPDISPOSEIMAGE) (GpImage *image);
typedef GpStatus (WINGDIPAPI* PGDIPCREATEFROMHDC) (HDC hdc, GpGraphics **graphics);
typedef GpStatus (WINGDIPAPI* PGDIPSETINTERPOLATIONMODE) (GpGraphics *graphics, InterpolationMode interpolationMode);
typedef GpStatus (WINGDIPAPI* PGDIPDELETEGRAPHICS)(GpGraphics *graphics);
typedef GpStatus (WINGDIPAPI* PGDIPCREATEBITMAPFROMFILE) (GDIPCONST WCHAR* filename, GpBitmap **bitmap);
typedef GpStatus (WINGDIPAPI* PGDIPCREATEBITMAPFROMSTREAM) (IStream* stream, GpBitmap **bitmap);
typedef GpStatus (WINGDIPAPI* PGDIPBITMAPLOCKBITS) (GpBitmap* bitmap, GDIPCONST GpRect* rect,UINT flags,PixelFormat format, BitmapData* lockedBitmapData);
typedef GpStatus (WINGDIPAPI* PGDIPBITMAPUNLOCKBITS)(GpBitmap* bitmap,BitmapData* lockedBitmapData);
typedef GpStatus (WINGDIPAPI* PGDICREATEBITMAPFROMGRAPHICS) (INT width,INT height,GpGraphics* target, GpBitmap** bitmap);
typedef GpStatus (WINGDIPAPI* PDRAWIMAGERECTRECTI) (GpGraphics *graphics, GpImage *image, INT dstx,
                       INT dsty, INT dstwidth, INT dstheight,
                       INT srcx, INT srcy, INT srcwidth, INT srcheight,
                       GpUnit srcUnit,
                       GDIPCONST GpImageAttributes* imageAttributes,
                       DrawImageAbort callback, VOID * callbackData);

class GDIPlusImage
{
public:
	GDIPlusImage();
	~GDIPlusImage();


public:
	void UnInit();
	BOOL Init();
	BOOL LoadImageFile(LPCTSTR szPath);
	HGLOBAL LoadImageMemory(HANDLE hMem);
	HGLOBAL GetDIB(HDC hdc);
	HGLOBAL DIBFromFace(LPCSTR szFace);



protected:

	PGDIBITMAPCONVERTFORMAT		pGdiBitmapConvertFormat;
	PGDIPGETIMAGEWIDTH			pGdipGetImageWidth;
	PGDIPGETIMAGEHEIGHT			pGdipGetImageHeight;
	PGDIPLOADIMAGEFROMFILE		pGdipLoadImageFromFile;
	PGDIPLOADIMAGEFROMSTREAM    pGdipLoadImageFromStream;
	PDRAWIMAGERECTRECTI			pGdipDrawImageRectRectI;
	PGDIPCREATEFROMHDC			pGdipCreateFromHDC;
	PGDIPSETINTERPOLATIONMODE	pGdipSetInterpolationMode;
	PGDIPDELETEGRAPHICS			pGdipDeleteGraphics;
	PGDIPDISPOSEIMAGE			pGdipDisposeImage;
	PGDIPLUSSTARTUP				pGdiplusStartup;
	PGDIPLUSSHUTDOWN			pGdiplusShutdown;
	PGDIPCREATEBITMAPFROMFILE	pGdipCreateBitmapFromFile;
	PGDIPCREATEBITMAPFROMSTREAM pGdipCreateBitmapFromStream;
	PGDIPBITMAPLOCKBITS			pGdipBitmapLockBits;
	PGDIPBITMAPUNLOCKBITS		pGdipBitmapUnlockBits;
	PGDICREATEBITMAPFROMGRAPHICS pGdipCreateBitmapFromGraphics;

	static HINSTANCE m_hLibGDIPlus;
	GpBitmap* m_pImage;
	ULONG_PTR m_gdiplusToken;
	BOOL	m_bInit;



};

#endif