#include "ImgLoader.h"

#ifdef SUPPORT_SVG_TYPE
#pragma warning(disable:4996)
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"
#endif

#ifdef SUPPORT_FREEIMAGE
#include "FreeImage.h"
#endif

Gdiplus::Image* CImgLoaderByGdiplus::LoadImage(wchar_t * szImgPath)
{
	return CGdiplusWrapper::GetInstance().LoadImage(szImgPath);
}

void CImgLoaderByGdiplus::Print()
{
	printf("支持加载[bmp|png|jpg|jpeg|gif|tiff]格式\n");
}

const wchar_t* CImgLoaderByGdiplus::GetImgType()
{
	return L"bmp|png|jpg|jpeg|gif|tiff";
}

#ifdef SUPPORT_SVG_TYPE
static std::string UTF16ToMBCS(const wchar_t * szUtf16, int utf16Len)
{
	int MBLen = WideCharToMultiByte(CP_ACP, 0, szUtf16, utf16Len, NULL, 0, NULL, NULL);
	if (MBLen <= 0)
		return "";

	std::string szMbcs;
	szMbcs.resize(MBLen);
	int nRtn = WideCharToMultiByte(CP_ACP, 0, szUtf16, utf16Len, &szMbcs[0], MBLen, NULL, NULL);

	if (nRtn != MBLen)
		szMbcs.resize(0);

	return szMbcs;
}

Gdiplus::Image* CImgLoaderByNanoSvg::LoadImage(wchar_t * szImgPath)
{
	Gdiplus::Image* pImage = NULL;
	NSVGimage *image = NULL;
	NSVGrasterizer *rast = NULL;
	unsigned char* img = NULL;
	int w, h;
	std::string filename = UTF16ToMBCS(szImgPath, wcslen(szImgPath));

	image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
	if (image == NULL) {
		printf("Could not open SVG image.\n");
		goto error;
	}
	w = (int)image->width;
	h = (int)image->height;

	rast = nsvgCreateRasterizer();
	if (rast == NULL) {
		printf("Could not init rasterizer.\n");
		goto error;
	}

	img = (unsigned char*)malloc(w*h * 4);
	if (img == NULL) {
		printf("Could not alloc image buffer.\n");
		goto error;
	}

	nsvgRasterize(rast, image, 0, 0, 1, img, w, h, w * 4);

	int outSize;
	unsigned char* outData = stbi_write_png_to_mem(img, w * 4, w, h, 4, &outSize);

	HGLOBAL hMemBmp = GlobalAlloc(GMEM_FIXED, outSize);
	IStream* pStmBmp = NULL;
	CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmBmp);
	unsigned char* pbyBmp = (unsigned char*)GlobalLock(hMemBmp);
	memcpy(pbyBmp, outData, outSize);
	pImage = new Gdiplus::Image(pStmBmp, NULL);
	GlobalUnlock(hMemBmp);

	free(img); img = NULL;
	free(outData); outData = NULL;
error:
	nsvgDeleteRasterizer(rast);
	nsvgDelete(image);

	return pImage;
}

void CImgLoaderByNanoSvg::Print()
{
	printf("支持加载svg格式\n");
}

const wchar_t* CImgLoaderByNanoSvg::GetImgType()
{
	return L"svg";
}
#endif

#ifdef SUPPORT_FREEIMAGE
Gdiplus::Image* CImgLoaderByFreeImage::LoadImage(wchar_t * szImgPath)
{
	std::string szPath = UTF16ToMBCS(szImgPath, wcslen(szImgPath));
	FREE_IMAGE_FORMAT type = FreeImage_GetFileType(szPath.c_str());
	FIBITMAP* fibitmap = FreeImage_Load(type, szPath.c_str());
	BYTE * pByteData = FreeImage_GetBits(fibitmap);
	BITMAPINFO *bitmapInfo = FreeImage_GetInfo(fibitmap);
	Gdiplus::Image* pImage = new Gdiplus::Bitmap(bitmapInfo, pByteData);
	return pImage;
}

void CImgLoaderByFreeImage::Print()
{
	printf("支持加载[bmp|png|jpg|jpeg|gif|tiff|psd]格式\n");
}

const wchar_t* CImgLoaderByFreeImage::GetImgType()
{
	return L"bmp|png|jpg|jpeg|gif|tiff|psd";
}
#endif

CImageFactory::CImageFactory()
{
	CGdiplusWrapper::GetInstance();
}
