Esempio n. 1
0
	bool Init(struct CET_Init* pInit)
	{
		bool result = false;
		nErrNumber = 0;
		//pszPluginKey = pInit->pRegKey;
		//ReloadConfig();
		HRESULT hrCoInitialized = CoInitialize(NULL);
		bCoInitialized = SUCCEEDED(hrCoInitialized);
		wchar_t FullPath[MAX_PATH*2+15]; FullPath[0] = 0;
		//if (ghModule)
		//{
		//	PVDSettings::FindFile(L"GdiPlus.dll", FullPath, sizeofarray(FullPath));
		//	hGDIPlus = LoadLibraryW(FullPath);
		//}
		//if (!hGDIPlus)
		hGDIPlus = LoadLibraryW(L"GdiPlus.dll");

		if (!hGDIPlus)
		{
			nErrNumber = PGE_DLL_NOT_FOUND;
		}
		else
		{
			DllGetFunction(hGDIPlus, GdiplusStartup);
			DllGetFunction(hGDIPlus, GdiplusShutdown);
			DllGetFunction(hGDIPlus, GdipCreateBitmapFromFile);
			DllGetFunction(hGDIPlus, GdipGetImageThumbnail);
			//DllGetFunction(hGDIPlus, GdipCreateBitmapFromFileICM);
			//DllGetFunction(hGDIPlus, GdipCreateBitmapFromStream);
			//DllGetFunction(hGDIPlus, GdipCreateBitmapFromStreamICM);
			DllGetFunction(hGDIPlus, GdipGetImageWidth);
			DllGetFunction(hGDIPlus, GdipGetImageHeight);
			DllGetFunction(hGDIPlus, GdipGetImagePixelFormat);
			//DllGetFunction(hGDIPlus, GdipBitmapLockBits);
			//DllGetFunction(hGDIPlus, GdipBitmapUnlockBits);
			DllGetFunction(hGDIPlus, GdipDisposeImage);
			DllGetFunction(hGDIPlus, GdipImageGetFrameCount);
			DllGetFunction(hGDIPlus, GdipImageSelectActiveFrame);
			DllGetFunction(hGDIPlus, GdipGetPropertyItemSize);
			DllGetFunction(hGDIPlus, GdipGetPropertyItem);
			DllGetFunction(hGDIPlus, GdipImageRotateFlip);
			DllGetFunction(hGDIPlus, GdipGetImageRawFormat);
			//DllGetFunction(hGDIPlus, GdipGetImageFlags);
			//DllGetFunction(hGDIPlus, GdipGetImagePalette);
			//DllGetFunction(hGDIPlus, GdipGetImagePaletteSize);
			DllGetFunction(hGDIPlus, GdipCreateFromHDC);
			DllGetFunction(hGDIPlus, GdipDeleteGraphics);
			DllGetFunction(hGDIPlus, GdipDrawImageRectRectI);
			//DllGetFunction(hGDIPlus, GdipCreateBitmapFromScan0);
			//DllGetFunction(hGDIPlus, GdipFillRectangleI);
			//DllGetFunction(hGDIPlus, GdipCreateSolidFill);
			//DllGetFunction(hGDIPlus, GdipDeleteBrush);
			//DllGetFunction(hGDIPlus, GdipCloneBitmapAreaI);
			//DllGetFunction(hGDIPlus, GdipSetImagePalette);

			if (GdiplusStartup && GdiplusShutdown && GdipCreateBitmapFromFile && GdipGetImageThumbnail
			        && GdipGetImageWidth && GdipGetImageHeight && GdipGetImagePixelFormat && GdipGetImageRawFormat
			        //&& GdipBitmapLockBits && GdipBitmapUnlockBits
			        && GdipDisposeImage && GdipImageGetFrameCount && GdipImageSelectActiveFrame
			        && GdipGetPropertyItemSize && GdipGetPropertyItem && GdipImageRotateFlip
			        //&& GdipGetImagePalette && GdipGetImagePaletteSize && GdipCloneBitmapAreaI && GdipGetImageFlags
			        && GdipCreateFromHDC && GdipDeleteGraphics && GdipDrawImageRectRectI
			        //&& GdipCreateBitmapFromScan0 && GdipFillRectangleI && GdipCreateSolidFill && GdipDeleteBrush
			        //&& GdipSetImagePalette
			  )
			{
				Gdiplus::GdiplusStartupInput gdiplusStartupInput;
				Gdiplus::Status lRc = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
				result = (lRc == Gdiplus::Ok);

				if (!result)
				{
					nLastError = GetLastError();
					GdiplusShutdown(gdiplusToken); bTokenInitialized = false;
					nErrNumber = PGE_ERROR_BASE + (DWORD)lRc;
				}
				else
				{
					bTokenInitialized = true;
				}
			}
			else
			{
				nErrNumber = PGE_FUNCTION_NOT_FOUND;
			}

			if (!result)
				FreeLibrary(hGDIPlus);
		}

		if (result)
		{
			pInit->pContext = this;
			pInit->nModuleID = MODULE_GDIP;
		}

		return result;
	};
DWORD WINAPI CMYK_ThreadProc(void*)
{
	OutputDebugString(L"\n*** Loading CMYK.png...");
	ULONG_PTR gdiplusToken = 0; bool bTokenInitialized = false;
	BOOL bCoInitialized = FALSE;
	wchar_t* pszFileName = NULL; //ConcatPath(g_SelfPath, L"CMYK.png");
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::Status lRc;
	Gdiplus::GpBitmap *img = NULL;
	UINT lWidth = 0, lHeight = 0, pf = 0, nBPP = 0;
	Gdiplus::BitmapData bmd; bool bBitsLocked = false;
	Gdiplus::GpRect rect(0, 0, 256, 256);

	typedef Gdiplus::Status (WINAPI *GdiplusStartup_t)(OUT ULONG_PTR *token, const Gdiplus::GdiplusStartupInput *input, OUT Gdiplus::GdiplusStartupOutput *output);
	typedef VOID (WINAPI *GdiplusShutdown_t)(ULONG_PTR token);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipCreateBitmapFromFile_t)(GDIPCONST WCHAR* filename, Gdiplus::GpBitmap **bitmap);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipGetImageWidth_t)(Gdiplus::GpImage *image, UINT *width);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipGetImageHeight_t)(Gdiplus::GpImage *image, UINT *height);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipGetImagePixelFormat_t)(Gdiplus::GpImage *image, Gdiplus::PixelFormat *format);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipBitmapLockBits_t)(Gdiplus::GpBitmap* bitmap, GDIPCONST Gdiplus::GpRect* rect, UINT flags, Gdiplus::PixelFormat format, Gdiplus::BitmapData* lockedBitmapData);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipBitmapUnlockBits_t)(Gdiplus::GpBitmap* bitmap, Gdiplus::BitmapData* lockedBitmapData);
	typedef Gdiplus::GpStatus (WINGDIPAPI *GdipDisposeImage_t)(Gdiplus::GpImage *image);

	#define DllGetFunction(hModule, FunctionName) FunctionName = (FunctionName##_t)GetProcAddress(hModule, #FunctionName)
	
	GdiplusStartup_t GdiplusStartup;
	GdiplusShutdown_t GdiplusShutdown;
	GdipCreateBitmapFromFile_t GdipCreateBitmapFromFile;
	GdipGetImageWidth_t GdipGetImageWidth;
	GdipGetImageHeight_t GdipGetImageHeight;
	GdipGetImagePixelFormat_t GdipGetImagePixelFormat;
	GdipBitmapLockBits_t GdipBitmapLockBits;
	GdipBitmapUnlockBits_t GdipBitmapUnlockBits;
	GdipDisposeImage_t GdipDisposeImage;


	//gs_CMYK_ErrorInfo[0] = 0;
	//g_Plugin.nCMYK_ErrorNumber = g_Plugin.nCMYK_LastError = 0;

	HRESULT hr = CoInitialize(NULL);
	if (!(bCoInitialized = SUCCEEDED(hr))) {
		//wsprintf(gs_CMYK_ErrorInfo, L"CoInitialize failed. Code=0x%08X", (DWORD)hr);
		g_Plugin.nCMYK_ErrorNumber = MICMYKCoInitializeFailed;
		g_Plugin.nCMYK_LastError = (DWORD)hr;
		goto wrap;
	}

	g_Plugin.hGDIPlus = LoadLibraryW(L"GdiPlus.dll");
	if (!g_Plugin.hGDIPlus) {
		//dwLastError = GetLastError();
		//wsprintf(gs_CMYK_ErrorInfo, L"LoadLibrary(GdiPlus.dll) failed. Code=0x%08X", (DWORD)hr);
		g_Plugin.nCMYK_ErrorNumber = MICMYKLoadLibraryFailed;
		g_Plugin.nCMYK_LastError = GetLastError();
		goto wrap;
	}

	DllGetFunction(g_Plugin.hGDIPlus, GdiplusStartup);
	DllGetFunction(g_Plugin.hGDIPlus, GdiplusShutdown);
	DllGetFunction(g_Plugin.hGDIPlus, GdipCreateBitmapFromFile);
	DllGetFunction(g_Plugin.hGDIPlus, GdipGetImageWidth);
	DllGetFunction(g_Plugin.hGDIPlus, GdipGetImageHeight);
	DllGetFunction(g_Plugin.hGDIPlus, GdipGetImagePixelFormat);
	DllGetFunction(g_Plugin.hGDIPlus, GdipBitmapLockBits);
	DllGetFunction(g_Plugin.hGDIPlus, GdipBitmapUnlockBits);
	DllGetFunction(g_Plugin.hGDIPlus, GdipDisposeImage);

	if (!GdiplusStartup || !GdiplusShutdown || !GdipCreateBitmapFromFile || !GdipGetImageWidth || !GdipGetImageHeight 
		|| !GdipGetImagePixelFormat || !GdipBitmapLockBits || !GdipBitmapUnlockBits || !GdipDisposeImage)
	{
		//lstrcpy(gs_CMYK_ErrorInfo, L"One of GdiPlus flat api functions not found!");
		g_Plugin.nCMYK_ErrorNumber = MICMYKBadGdiFlat;
		goto wrap;
	}

	bTokenInitialized = Gdiplus::Ok == (lRc = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL));
	if (!bTokenInitialized) {
		//wsprintf(gs_CMYK_ErrorInfo, L"GdiplusStartup failed. Code=%i", (DWORD)lRc);
		g_Plugin.nCMYK_ErrorNumber = MICMYKGdipStartupFailed;
		g_Plugin.nCMYK_LastError = (DWORD)lRc;
		goto wrap;
	}

	pszFileName = ConcatPath(g_SelfPath, L"CMYK.png");

	if (Gdiplus::Ok != (lRc = GdipCreateBitmapFromFile(pszFileName, &img))) {
		//wsprintf(gs_CMYK_ErrorInfo, L"GdipCreateBitmapFromFile(CMYK.png) failed. Code=%i", (DWORD)lRc);
		g_Plugin.nCMYK_ErrorNumber = MICMYKCreateBitmapFailed;
		g_Plugin.nCMYK_LastError = (DWORD)lRc;
		goto wrap;
	}

	lRc = GdipGetImageWidth(img, &lWidth);
	lRc = GdipGetImageHeight(img, &lHeight);
	lRc = GdipGetImagePixelFormat(img, (Gdiplus::PixelFormat*)&pf);
	nBPP = pf >> 8 & 0xFF;

	if (lWidth != (16*16) || lHeight != (16*16)) {
		g_Plugin.nCMYK_ErrorNumber = MICMYKpaletteInvalidSize;
		goto wrap;
	}
	if (nBPP != 24 && nBPP != 32) {
		g_Plugin.nCMYK_ErrorNumber = MICMYKpaletteInvalidBPP;
		goto wrap;
	}

	rect.Width = lWidth; rect.Height = lHeight;

	if (Gdiplus::Ok != (lRc = GdipBitmapLockBits(img, &rect, Gdiplus::ImageLockModeRead, PixelFormat32bppRGB, &bmd))) {
		g_Plugin.nCMYK_ErrorNumber = MICMYKpaletteInvalidBPP;
		goto wrap;
	}
	bBitsLocked = true;



	g_Plugin.nCMYKparts = 17; // пока фиксировано
	g_Plugin.nCMYKsize = lWidth * lHeight;
	g_Plugin.pCMYKpalette = (DWORD*)calloc(g_Plugin.nCMYKsize,4);

	if (!g_Plugin.pCMYKpalette) {
		g_Plugin.nCMYK_ErrorNumber = MIMemoryAllocationFailed;
		goto wrap;

	} else {

		BYTE* pDst = (BYTE*)g_Plugin.pCMYKpalette;
		BYTE* pSrc = (BYTE*)bmd.Scan0;
		uint lAbsSrcPitch = 0;
		int lDstPitch = lWidth * 4;

		if (bmd.Stride < 0)
		{
			pDst += (int)(lHeight - 1) * lDstPitch;
			lAbsSrcPitch = -bmd.Stride;
			lDstPitch = -lDstPitch;
		} else {
			lAbsSrcPitch = bmd.Stride;
		}

		BltHelper::Blit32_BGRA(pDst, pSrc, 0, lWidth, lHeight, lAbsSrcPitch, lDstPitch, 0, 0, 0, 0);

		OutputDebugString(L"Succeeded.\n");
	}

	// OK

wrap:
	if (bBitsLocked) {
		GdipBitmapUnlockBits(img, &bmd); bBitsLocked = false;
	}
	if (img) {
		GdipDisposeImage(img); img = NULL;
	}
	if (pszFileName) {
		free(pszFileName); pszFileName = NULL;
	}
	if (bTokenInitialized) {
		GdiplusShutdown(gdiplusToken); bTokenInitialized = false;
	}
	//if (hGDIPlus) {
	//	FreeLibrary(hGDIPlus);
	//	hGDIPlus = NULL;
	//}
	//if (bCoInitialized)
	//	CoUninitialize();

	return 0;
}