ml_imageloader.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. #include "main.h"
  2. #include "./ml_imageloader.h"
  3. #include "api__gen_ml.h"
  4. #include "./ml_ipc_0313.h"
  5. #include <api/service/waServiceFactory.h>
  6. #include <api/service/svcs/svc_imgload.h>
  7. #include <api/memmgr/api_memmgr.h>
  8. #include <commctrl.h>
  9. #include <shlwapi.h>
  10. static const GUID pngGUID = { 0x5e04fb28, 0x53f5, 0x4032, { 0xbd, 0x29, 0x3, 0x2b, 0x87, 0xec, 0x37, 0x25 } };
  11. #ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
  12. #define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x000000020
  13. #endif //LOAD_LIBRARY_AS_IMAGE_RESOURCE
  14. static svc_imageLoader *wasabiPNGLoader = NULL;
  15. static api_memmgr *wasabiMemMgr = NULL;
  16. static BOOL InitializePNGService(void)
  17. {
  18. waServiceFactory *sf;
  19. if (!wasabiMemMgr)
  20. {
  21. sf = WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
  22. if (sf) wasabiMemMgr = reinterpret_cast<api_memmgr*>(sf->getInterface());
  23. }
  24. if (wasabiMemMgr && !wasabiPNGLoader)
  25. {
  26. sf = WASABI_API_SVC->service_getServiceByGuid(pngGUID);
  27. if (sf) wasabiPNGLoader = reinterpret_cast<svc_imageLoader*>(sf->getInterface());
  28. }
  29. return (wasabiMemMgr && wasabiPNGLoader);
  30. }
  31. static HBITMAP LoadImage_LoadPngData(void *pngData, UINT pngSize, BOOL fPremultiply)
  32. {
  33. INT cx, cy;
  34. HBITMAP bitmap;
  35. if (NULL == wasabiPNGLoader)
  36. {
  37. if (FALSE == InitializePNGService() ||
  38. NULL == wasabiPNGLoader)
  39. {
  40. return NULL;
  41. }
  42. }
  43. pngData = (FALSE != fPremultiply) ?
  44. wasabiPNGLoader->loadImage(pngData, pngSize, &cx, &cy) :
  45. wasabiPNGLoader->loadImageData(pngData, pngSize, &cx, &cy);
  46. if (NULL != pngData)
  47. {
  48. BITMAPINFOHEADER header;
  49. void *pixelData;
  50. ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
  51. header.biSize = sizeof(BITMAPINFOHEADER);
  52. header.biBitCount = 32;
  53. header.biPlanes = 1;
  54. header.biWidth = cx;
  55. header.biHeight = -cy;
  56. bitmap = CreateDIBSection(NULL, (LPBITMAPINFO)&header, DIB_RGB_COLORS, &pixelData, NULL, 0);
  57. if (NULL != bitmap)
  58. CopyMemory(pixelData, pngData, cx * cy * sizeof(DWORD));
  59. wasabiMemMgr->sysFree(pngData);
  60. }
  61. else
  62. bitmap = NULL;
  63. return bitmap;
  64. }
  65. static HBITMAP LoadImage_PngResource(HINSTANCE hInstance, HINSTANCE langModule,
  66. LPCWSTR pszName, LPCWSTR pszType, BOOL fPremultiply)
  67. {
  68. HRSRC res;
  69. res = (NULL != langModule) ?
  70. FindResourceW(langModule, pszName, pszType) :
  71. NULL;
  72. if (NULL == res)
  73. {
  74. res = FindResourceW(hInstance, pszName, pszType);
  75. }
  76. else
  77. {
  78. hInstance = langModule;
  79. }
  80. if (NULL == res)
  81. return NULL;
  82. HANDLE handle = LoadResource(hInstance, res);
  83. if (NULL == handle)
  84. return NULL;
  85. UINT pngSize = SizeofResource(hInstance, res);
  86. if (0 == pngSize)
  87. return NULL;
  88. void *pngData = LockResource(handle);
  89. if (NULL == pngData)
  90. return NULL;
  91. return LoadImage_LoadPngData(pngData, pngSize, fPremultiply);
  92. }
  93. static HBITMAP LoadImage_BmpResource(HINSTANCE hInstace, HINSTANCE langModule, LPCWSTR pszName, LPCWSTR pszType, BOOL fPremultiply)
  94. {
  95. UINT flags = LR_DEFAULTCOLOR | LR_CREATEDIBSECTION;
  96. if (NULL != langModule)
  97. {
  98. HBITMAP bitmap;
  99. bitmap = (HBITMAP)LoadImageW(langModule, pszName, IMAGE_BITMAP, 0, 0, flags);
  100. if (NULL != bitmap)
  101. return bitmap;
  102. }
  103. return (HBITMAP)LoadImageW(hInstace, pszName, IMAGE_BITMAP, 0, 0, flags);
  104. }
  105. static BOOL LoadImage_IsValidGuidChar(wchar_t c)
  106. {
  107. if ((c >= L'0' && c <= L'9') ||
  108. (c >= L'A' && c <= L'F') ||
  109. (c >= L'a' && c <= L'f') ||
  110. (L'-' == c))
  111. {
  112. return TRUE;
  113. }
  114. return FALSE;
  115. }
  116. static HRESULT LoadImage_CrackResProtocol(LPCWSTR pszAddress, LPCWSTR pszDefaultType, HINSTANCE *module,
  117. HINSTANCE *langModule, LPCWSTR *name, wchar_t **type)
  118. {
  119. if (NULL == module) return E_POINTER;
  120. if (NULL == pszAddress || L'\0' == *pszAddress)
  121. return E_INVALIDARG;
  122. INT cchAddress = lstrlenW(pszAddress);
  123. const WCHAR szPrefix[] = L"res://";
  124. INT cchPrefix = ARRAYSIZE(szPrefix) - 1;
  125. if (cchAddress <= cchPrefix ||
  126. CSTR_EQUAL != CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, pszAddress, cchPrefix, szPrefix, cchPrefix))
  127. {
  128. return S_FALSE;
  129. }
  130. pszAddress += cchPrefix;
  131. cchAddress -= cchPrefix;
  132. LPCWSTR resType = NULL;
  133. LPCWSTR resName = NULL;
  134. LPCWSTR p = pszAddress + cchAddress;
  135. while (p != pszAddress && L'/' != *p) p--;
  136. if (p != pszAddress && p < (pszAddress + cchAddress))
  137. {
  138. resName = p + 1;
  139. p--;
  140. }
  141. if (NULL == resName || L'\0' == *resName)
  142. return E_FAIL;
  143. WCHAR szFile[MAX_PATH + 128] = {0};
  144. if (FAILED(StringCchCopyNW(szFile, ARRAYSIZE(szFile), pszAddress, (resName - pszAddress - 1))))
  145. return E_OUTOFMEMORY;
  146. while (p != pszAddress && L'/' != *p) p--;
  147. if (p != pszAddress && p < resName)
  148. {
  149. resType = p + 1;
  150. if (L'\0' == *resType)
  151. {
  152. resType = NULL;
  153. }
  154. else
  155. {
  156. size_t pos = (resType - pszAddress);
  157. szFile[pos - 1] = L'\0';
  158. resType = &szFile[pos];
  159. }
  160. }
  161. HINSTANCE hModule = LoadLibraryExW(szFile, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  162. if (NULL == hModule && NULL != resType)
  163. {
  164. DWORD errorCode = GetLastError();
  165. if (ERROR_FILE_NOT_FOUND == errorCode)
  166. {
  167. *((LPWSTR)(resType - 1)) = L'/';
  168. resType = NULL;
  169. hModule = LoadLibraryExW(szFile, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  170. }
  171. }
  172. if (NULL == hModule)
  173. return E_FAIL;
  174. if (NULL != type)
  175. {
  176. if (NULL == resType)
  177. resType = pszDefaultType;
  178. if (FALSE == IS_INTRESOURCE(resType))
  179. {
  180. if (L'#' == *resType)
  181. {
  182. INT typeId;
  183. if (FALSE != StrToIntExW(resType + 1, STIF_DEFAULT, &typeId))
  184. resType = MAKEINTRESOURCEW(typeId);
  185. else
  186. resType = NULL;
  187. }
  188. else
  189. {
  190. int length = lstrlenW(resType);
  191. wchar_t *str = (wchar_t*)malloc((length + 1) * sizeof(wchar_t));
  192. if (NULL != str)
  193. CopyMemory(str, resType, sizeof(wchar_t) * (length + 1));
  194. resType = str;
  195. }
  196. }
  197. *type = (wchar_t*)resType;
  198. }
  199. if (NULL != langModule)
  200. {
  201. *langModule = NULL;
  202. if (NULL != WASABI_API_LNG &&
  203. FALSE == SENDWAIPC(plugin.hwndParent, IPC_GETLANGUAGEPACKINSTANCE, 1))
  204. {
  205. wchar_t buffer[64], *lang_str;
  206. GUID lang_id;
  207. if (0 != LoadStringW(hModule, LANG_DLL_GUID_STRING_ID, buffer, ARRAYSIZE(buffer)))
  208. {
  209. lang_str = buffer;
  210. while(FALSE == LoadImage_IsValidGuidChar(*lang_str))
  211. {
  212. if (L'0' == *lang_str)
  213. break;
  214. lang_str++;
  215. }
  216. int len = lstrlenW(lang_str);
  217. if (len > 0)
  218. {
  219. wchar_t *cursor = lang_str + (len - 1);
  220. while(FALSE == LoadImage_IsValidGuidChar(*cursor))
  221. {
  222. if (lang_str == cursor)
  223. break;
  224. cursor--;
  225. }
  226. *(cursor+1) = L'\0';
  227. }
  228. if (RPC_S_OK == UuidFromStringW((RPC_WSTR)lang_str, &lang_id))
  229. {
  230. *langModule = WASABI_API_LNG->FindDllHandleByGUID(lang_id);
  231. if (*langModule == hModule)
  232. *langModule = NULL;
  233. }
  234. }
  235. }
  236. }
  237. *module = hModule;
  238. if (NULL != name)
  239. *name = resName;
  240. return S_OK;
  241. }
  242. static HBITMAP
  243. LoadImage_CrackHBitmapProtocol(const wchar_t *address)
  244. {
  245. INT addressLen, prefixLen;
  246. const WCHAR prefix[] = L"hbitmap://";
  247. LONGLONG value;
  248. if (NULL == address || L'\0' == *address)
  249. return NULL;
  250. addressLen = lstrlenW(address);
  251. prefixLen = ARRAYSIZE(prefix) - 1;
  252. if (addressLen <= prefixLen ||
  253. CSTR_EQUAL != CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE,
  254. address, prefixLen, prefix, prefixLen))
  255. {
  256. return NULL;
  257. }
  258. address += prefixLen;
  259. while(L'\0' != *address && L' ' == *address)
  260. address++;
  261. if (FALSE == StrToInt64ExW(address, STIF_SUPPORT_HEX, &value))
  262. return NULL;
  263. return (HBITMAP)value;
  264. }
  265. static HBITMAP LoadImage_ResProtocol(LPCWSTR pszAddress, LPCWSTR pszDefaultType,
  266. BOOL fPremultiply, BOOL ignoreLocalized)
  267. {
  268. HRESULT hr;
  269. HINSTANCE hModule, langModule;
  270. LPCWSTR resName;
  271. wchar_t *resType;
  272. HBITMAP bitmap;
  273. BOOL loaded = FALSE;
  274. hr = LoadImage_CrackResProtocol(pszAddress, pszDefaultType, &hModule,
  275. (FALSE == ignoreLocalized) ? &langModule : NULL,
  276. &resName, &resType);
  277. if (FAILED(hr) || S_FALSE == hr)
  278. return NULL;
  279. if (FALSE != ignoreLocalized)
  280. langModule = NULL;
  281. if (NULL != resType)
  282. {
  283. if (IS_INTRESOURCE(resType))
  284. {
  285. switch((INT)(INT_PTR)resType)
  286. {
  287. case (INT)(INT_PTR)RT_BITMAP:
  288. bitmap = LoadImage_BmpResource(hModule, langModule, resName, resType, fPremultiply);
  289. loaded = TRUE;
  290. break;
  291. }
  292. }
  293. }
  294. if (FALSE == loaded)
  295. {
  296. bitmap = LoadImage_PngResource(hModule, langModule, resName, resType, fPremultiply);
  297. }
  298. if (NULL != langModule)
  299. {
  300. // do not call FreeLibrary for langModule (it was never loaded)
  301. // FreeLibrary(langModule);
  302. }
  303. FreeLibrary(hModule);
  304. if (FALSE == IS_INTRESOURCE(resType))
  305. free(resType);
  306. return bitmap;
  307. }
  308. static HBITMAP LoadImage_PngFile(LPCWSTR pszPath, BOOL fPremultiply, BOOL ignoreLocalized)
  309. {
  310. HANDLE hFile = CreateFileW(pszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  311. if (INVALID_HANDLE_VALUE == hFile)
  312. return NULL;
  313. HBITMAP bitmap = NULL;
  314. UINT pngSize = GetFileSize(hFile, NULL);
  315. if (INVALID_FILE_SIZE != pngSize)
  316. {
  317. void *pngData = malloc(pngSize);
  318. if (NULL != pngData)
  319. {
  320. DWORD readed = 0;
  321. if (0 != ReadFile(hFile, pngData, pngSize, &readed, NULL) || pngSize != readed)
  322. {
  323. bitmap = LoadImage_LoadPngData(pngData, pngSize, fPremultiply);
  324. }
  325. free(pngData);
  326. }
  327. }
  328. CloseHandle(hFile);
  329. return bitmap;
  330. }
  331. static HBITMAP LoadImage_Png(const MLIMAGESOURCE_I *pImgSource)
  332. {
  333. HBITMAP bitmap;
  334. const wchar_t *path;
  335. BOOL premultiply, ignoreLocalized;
  336. path = pImgSource->lpszName;
  337. premultiply = (0 != (ISF_PREMULTIPLY_I & pImgSource->flags));
  338. ignoreLocalized = (0 != (ISF_NOLOCALIZED_LOAD_I & pImgSource->flags));
  339. if (FALSE == IS_INTRESOURCE(path))
  340. {
  341. bitmap = LoadImage_CrackHBitmapProtocol(path);
  342. if (NULL != bitmap)
  343. {
  344. bitmap = (HBITMAP)CopyImage(bitmap,IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  345. return bitmap;
  346. }
  347. bitmap = LoadImage_ResProtocol(path, (LPCWSTR)RT_RCDATA, premultiply, ignoreLocalized);
  348. if (NULL != bitmap)
  349. return bitmap;
  350. if (0 != (ISF_LOADFROMFILE_I & pImgSource->flags))
  351. return LoadImage_PngFile(path, premultiply, ignoreLocalized);
  352. }
  353. bitmap = LoadImage_PngResource(pImgSource->hInst, NULL, path, (LPCWSTR)RT_RCDATA, premultiply);
  354. if (NULL != bitmap)
  355. return bitmap;
  356. bitmap = LoadImage_PngResource(pImgSource->hInst, NULL, path, (LPCWSTR)L"PNG", premultiply);
  357. return bitmap;
  358. }
  359. static HBITMAP LoadImage_Bmp(const MLIMAGESOURCE_I *pImgSource)
  360. {
  361. HBITMAP bitmap;
  362. const wchar_t *path;
  363. BOOL premultiply, ignoreLocalized;
  364. path = pImgSource->lpszName;
  365. premultiply = (0 != (ISF_PREMULTIPLY_I & pImgSource->flags));
  366. ignoreLocalized = (0 != (ISF_NOLOCALIZED_LOAD_I & pImgSource->flags));
  367. if (FALSE == IS_INTRESOURCE(path))
  368. {
  369. bitmap = LoadImage_CrackHBitmapProtocol(path);
  370. if (NULL != bitmap)
  371. {
  372. bitmap = (HBITMAP)CopyImage(bitmap,IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  373. return bitmap;
  374. }
  375. bitmap = LoadImage_ResProtocol(path, (LPCWSTR)RT_BITMAP, premultiply, ignoreLocalized);
  376. if (NULL != bitmap)
  377. return bitmap;
  378. }
  379. UINT flags = LR_DEFAULTCOLOR | LR_CREATEDIBSECTION;
  380. if (0 != (ISF_LOADFROMFILE_I & pImgSource->flags))
  381. flags |= LR_LOADFROMFILE;
  382. bitmap = (HBITMAP)LoadImageW(pImgSource->hInst, path, IMAGE_BITMAP, 0, 0, flags);
  383. return bitmap;
  384. }
  385. static HBITMAP LoadImage_HIMAGELIST(const MLIMAGESOURCE_I *pImgSource)
  386. {
  387. // IMAGEINFO ii;
  388. // if (!pImgSource) return NULL;
  389. // return (ImageList_GetImageInfo((HIMAGELIST)pImgSource->hInst, (INT)(INT_PTR)pImgSource->lpszName, &ii)) ? ii.hbmImage : NULL;
  390. return NULL; // not supported;
  391. }
  392. static HBITMAP DuplicateStretchedDib(HBITMAP hbmpSrc, INT xSrc, INT ySrc, INT cxSrc, INT cySrc, INT cxDst, INT cyDst, INT bppDst, INT bppSrc, BOOL fStretch)
  393. {
  394. HDC hdcSrc, hdcDst;
  395. HBITMAP hbmpDst;
  396. LPVOID dib;
  397. BITMAPINFOHEADER bi;
  398. hdcSrc = CreateCompatibleDC(0);
  399. if (!hdcSrc) return NULL;
  400. hdcDst = CreateCompatibleDC(0);
  401. if (!hdcDst) { DeleteDC(hdcSrc); return NULL; }
  402. ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
  403. bi.biSize = sizeof (BITMAPINFOHEADER);
  404. bi.biWidth = cxDst;
  405. bi.biHeight = -ABS(cyDst);
  406. bi.biPlanes = 1;
  407. bi.biBitCount = bppDst;
  408. hbmpDst = CreateDIBSection(hdcDst, (BITMAPINFO *)&bi, DIB_RGB_COLORS, &dib, NULL, NULL);
  409. if (hbmpDst)
  410. {
  411. HGDIOBJ hgdiDst = SelectObject(hdcDst, hbmpDst);
  412. HGDIOBJ hgdiSrc = SelectObject(hdcSrc, hbmpSrc);
  413. if (fStretch && (cxDst != cxSrc || cyDst != cySrc))
  414. {
  415. if (32 == bppDst || 32 == bppSrc)
  416. {
  417. BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
  418. GdiAlphaBlend(hdcDst, 0, 0, cxDst, cyDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, bf);
  419. }
  420. else
  421. {
  422. INT stretchModeOld = SetStretchBltMode(hdcDst, HALFTONE);
  423. StretchBlt(hdcDst, 0, 0, cxDst, ABS(cyDst), hdcSrc, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
  424. SetStretchBltMode(hdcDst, stretchModeOld);
  425. }
  426. }
  427. else BitBlt(hdcDst, 0, 0, cxDst, ABS(cyDst), hdcSrc, xSrc, ySrc, SRCCOPY);
  428. SelectObject(hdcSrc, hgdiSrc);
  429. SelectObject(hdcDst, hgdiDst);
  430. }
  431. DeleteDC(hdcSrc);
  432. DeleteDC(hdcDst);
  433. return hbmpDst;
  434. }
  435. HBITMAP MLImageLoaderI_LoadDib(const MLIMAGESOURCE_I *pImgSource)
  436. {
  437. HBITMAP hbmp;
  438. if (NULL == pImgSource)
  439. return NULL;
  440. switch(pImgSource->type)
  441. {
  442. case SRC_TYPE_BMP_I: hbmp = LoadImage_Bmp(pImgSource); break;
  443. case SRC_TYPE_PNG_I: hbmp = LoadImage_Png(pImgSource); break;
  444. case SRC_TYPE_HBITMAP_I: hbmp = (HBITMAP)CopyImage((HANDLE)pImgSource->lpszName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); break;
  445. case SRC_TYPE_HIMAGELIST_I: hbmp = LoadImage_HIMAGELIST(pImgSource); break;
  446. default: hbmp = NULL; break;
  447. }
  448. if (NULL != hbmp) //
  449. {
  450. // get bitmap info
  451. BITMAP bm;
  452. if (sizeof(bm) == GetObjectW(hbmp, sizeof(bm), &bm))
  453. {
  454. if (((ISF_USE_OFFSET_I & pImgSource->flags) && (pImgSource->xSrc || pImgSource->ySrc)) ||
  455. ((ISF_USE_SIZE_I & pImgSource->flags) && (pImgSource->cxSrc != bm.bmWidth || pImgSource->cySrc != bm.bmHeight)) ||
  456. ((ISF_FORCE_SIZE_I & pImgSource->flags) && (pImgSource->cxDst != bm.bmWidth || pImgSource->cyDst != bm.bmHeight)) ||
  457. ((ISF_FORCE_BPP_I & pImgSource->flags) && (pImgSource->bpp != bm.bmBitsPixel)))
  458. {
  459. HBITMAP hOldBmp;
  460. hOldBmp = hbmp;
  461. hbmp = DuplicateStretchedDib( hbmp,
  462. (ISF_USE_OFFSET_I & pImgSource->flags) ? pImgSource->xSrc : 0,
  463. (ISF_USE_OFFSET_I & pImgSource->flags) ? pImgSource->ySrc : 0,
  464. (ISF_USE_SIZE_I & pImgSource->flags) ? pImgSource->cxSrc : bm.bmWidth,
  465. (ISF_USE_SIZE_I & pImgSource->flags) ? pImgSource->cySrc : bm.bmHeight,
  466. (ISF_FORCE_SIZE_I & pImgSource->flags) ? pImgSource->cxDst: bm.bmWidth,
  467. (ISF_FORCE_SIZE_I & pImgSource->flags) ? pImgSource->cyDst: bm.bmHeight,
  468. (ISF_FORCE_BPP_I & pImgSource->flags) ? pImgSource->bpp : bm.bmBitsPixel,
  469. bm.bmBitsPixel,
  470. (ISF_SCALE_I & pImgSource->flags));
  471. DeleteObject(hOldBmp);
  472. }
  473. }
  474. else
  475. {
  476. DeleteObject(hbmp);
  477. hbmp = NULL;
  478. }
  479. }
  480. return hbmp;
  481. }
  482. BOOL MLImageLoaderI_CopyData(MLIMAGESOURCE_I *pisDst, const MLIMAGESOURCE_I *pisSrc)
  483. {
  484. if (!pisDst || !pisSrc) return FALSE;
  485. CopyMemory(pisDst, pisSrc, sizeof(MLIMAGESOURCE_I));
  486. if (SRC_TYPE_HBITMAP_I != pisSrc->type && SRC_TYPE_HIMAGELIST_I != pisSrc->type &&
  487. pisSrc->lpszName && !IS_INTRESOURCE(pisSrc->lpszName)) pisDst->lpszName = _wcsdup(pisSrc->lpszName);
  488. return TRUE;
  489. }
  490. BOOL MLImageLoaderI_FreeData(MLIMAGESOURCE_I *pis)
  491. {
  492. if (!pis) return FALSE;
  493. if (SRC_TYPE_HBITMAP_I != pis->type && SRC_TYPE_HIMAGELIST_I != pis->type &&
  494. pis->lpszName && !IS_INTRESOURCE(pis->lpszName)) free((LPWSTR)pis->lpszName);
  495. return TRUE;
  496. }
  497. BOOL MLImageLoaderI_CheckExist(const MLIMAGESOURCE_I *pis)
  498. {
  499. const wchar_t *resType;
  500. if (NULL == pis)
  501. return FALSE;
  502. switch(pis->type)
  503. {
  504. case SRC_TYPE_HBITMAP_I: return (NULL != pis->lpszName);
  505. case SRC_TYPE_HIMAGELIST_I: return FALSE;
  506. case SRC_TYPE_PNG_I: resType = (LPCWSTR)RT_RCDATA; break;
  507. case SRC_TYPE_BMP_I: resType = (LPCWSTR)RT_BITMAP; break;
  508. default: resType = NULL; break;
  509. }
  510. if (FALSE == IS_INTRESOURCE(pis->lpszName))
  511. {
  512. BOOL result;
  513. HINSTANCE module, langModule;
  514. LPCWSTR name;
  515. wchar_t *type;
  516. HRESULT hr;
  517. if (NULL != LoadImage_CrackHBitmapProtocol(pis->lpszName))
  518. return TRUE;
  519. result = FALSE;
  520. langModule = NULL;
  521. hr = LoadImage_CrackResProtocol(pis->lpszName, resType, &module,
  522. (0 == (ISF_NOLOCALIZED_LOAD_I & pis->flags)) ? &langModule : NULL,
  523. &name, &type);
  524. if (0 != (ISF_NOLOCALIZED_LOAD_I & pis->flags))
  525. langModule = NULL;
  526. if (S_OK == hr)
  527. {
  528. if (NULL != langModule)
  529. {
  530. result = (NULL != FindResourceW(langModule, name, type));
  531. // do not call FreeLibrary for langModule (it was never loaded)
  532. //FreeLibrary(langModule);
  533. }
  534. if (FALSE == result)
  535. result = (NULL != FindResourceW(module, name, type));
  536. FreeLibrary(module);
  537. if (FALSE == IS_INTRESOURCE(type))
  538. free(type);
  539. return result;
  540. }
  541. if (0 != (ISF_LOADFROMFILE_I & pis->flags))
  542. {
  543. HANDLE hFile = CreateFileW(pis->lpszName, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  544. if (INVALID_HANDLE_VALUE != hFile)
  545. {
  546. switch(pis->type)
  547. {
  548. case SRC_TYPE_PNG_I:
  549. if (NULL != wasabiPNGLoader ||
  550. InitializePNGService())
  551. {
  552. BYTE data[8] = {0}; // png signature len
  553. DWORD dataRead = 0;
  554. if(ReadFile(hFile, data, sizeof(data), &dataRead, NULL) && 0 != dataRead)
  555. result = wasabiPNGLoader->testData(data, dataRead);
  556. }
  557. break;
  558. default:
  559. result = TRUE;
  560. break;
  561. }
  562. CloseHandle(hFile);
  563. }
  564. return result;
  565. }
  566. }
  567. return (NULL != resType &&
  568. NULL != FindResourceW(pis->hInst, pis->lpszName, resType));
  569. }