1
0

setupImage.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "./setupImage.h"
  2. #include "../api__ml_online.h"
  3. #include <shlwapi.h>
  4. static BOOL SetupImage_CopyImage(HDC hdc, HBITMAP bitmapDst, INT x, INT y, INT cx, INT cy, HBITMAP bitmapSrc, INT srcX, INT srcY)
  5. {
  6. BOOL resultOk = FALSE;
  7. HDC hdcDst = CreateCompatibleDC(hdc);
  8. HDC hdcSrc = CreateCompatibleDC(hdc);
  9. if (NULL != hdcDst && NULL != hdcSrc)
  10. {
  11. HBITMAP bitmapDstOrig = (HBITMAP)SelectObject(hdcDst, bitmapDst);
  12. HBITMAP bitmapSrcOrig = (HBITMAP)SelectObject(hdcSrc, bitmapSrc);
  13. resultOk = BitBlt(hdcDst, x, y, cx, cy, hdcSrc, srcX, srcY, SRCCOPY);
  14. SelectObject(hdcDst, bitmapDstOrig);
  15. SelectObject(hdcSrc, bitmapSrcOrig);
  16. }
  17. if (NULL != hdcDst) DeleteDC(hdcDst);
  18. if (NULL != hdcSrc) DeleteDC(hdcSrc);
  19. return resultOk;
  20. }
  21. static BOOL SetupImage_ColorizeImage(BYTE *pPixels, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, LONG dstX, LONG dstY, COLORREF rgbBk, COLORREF rgbFg, BOOL removeAlpha)
  22. {
  23. LONG pitch;
  24. INT step;
  25. BYTE rFg, gFg, bFg;
  26. LPBYTE srcCursor, srcLine;
  27. LPBYTE dstLine;
  28. if (bpp < 24) return FALSE;
  29. step = (bpp>>3);
  30. pitch = cx*step;
  31. while (pitch%4) pitch++;
  32. rFg = GetRValue(rgbFg); gFg = GetGValue(rgbFg); bFg = GetBValue(rgbFg);
  33. INT bK = (bFg - GetBValue(rgbBk));
  34. INT gK = (gFg - GetGValue(rgbBk));
  35. INT rK = (rFg - GetRValue(rgbBk));
  36. srcLine = pPixels + pitch * y + x*step;
  37. dstLine = pPixels + pitch * dstY + dstX*step;
  38. if (24 == bpp)
  39. {
  40. for (; cy-- != 0; srcLine += pitch, dstLine += pitch )
  41. {
  42. LONG i;
  43. LPBYTE dstCursor;
  44. for (i = cx, srcCursor = srcLine, dstCursor = dstLine ; i-- != 0; srcCursor += 3, dstCursor +=3)
  45. {
  46. dstCursor[0] = bFg - (bK*(255 - srcCursor[0])>>8);
  47. dstCursor[1] = gFg - (gK*(255 - srcCursor[1])>>8);
  48. dstCursor[2] = rFg - (rK*(255 - srcCursor[2])>>8);
  49. }
  50. }
  51. }
  52. else
  53. {
  54. // nothing for now
  55. return FALSE;
  56. }
  57. return TRUE;
  58. }
  59. SetupImage::SetupImage(HDC hdc, HBITMAP bitmapSource, INT maxColors)
  60. : ref(1), bitmap(NULL), pixels(NULL),
  61. table(NULL), tableSize(0), tableCount(0), insertCursor(0), readCursor(0)
  62. {
  63. ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
  64. BITMAP bm;
  65. if (sizeof(BITMAP) != GetObject(bitmapSource, sizeof(BITMAP), &bm))
  66. return;
  67. if (bm.bmHeight < 0)
  68. bm.bmHeight = -bm.bmHeight;
  69. header.biSize = sizeof(BITMAPINFOHEADER);
  70. header.biCompression = BI_RGB;
  71. header.biBitCount = 24;
  72. header.biPlanes = 1;
  73. header.biWidth = bm.bmWidth;
  74. header.biHeight = -(bm.bmHeight * (maxColors + 1));
  75. bitmap = CreateDIBSection(hdc, (LPBITMAPINFO)&header, DIB_RGB_COLORS, (void**)&pixels, NULL, 0);
  76. if (NULL == bitmap)
  77. return;
  78. if (FALSE == SetupImage_CopyImage(hdc, bitmap, 0, 0, bm.bmWidth, bm.bmHeight, bitmapSource, 0, 0))
  79. {
  80. DeleteObject(bitmap);
  81. bitmap = NULL;
  82. return;
  83. }
  84. tableSize = maxColors;
  85. table = (IMAGEINDEX*)calloc(tableSize, sizeof(IMAGEINDEX));
  86. if (NULL == table)
  87. {
  88. DeleteObject(bitmap);
  89. bitmap = NULL;
  90. return;
  91. }
  92. }
  93. SetupImage::~SetupImage()
  94. {
  95. if (NULL != bitmap)
  96. {
  97. DeleteObject(bitmap);
  98. bitmap = NULL;
  99. }
  100. if (NULL != table)
  101. {
  102. free(table);
  103. table = NULL;
  104. }
  105. }
  106. SetupImage *SetupImage::CreateInstance(HDC hdc, HBITMAP bitmapSource, INT maxColors)
  107. {
  108. if (NULL == bitmapSource || maxColors < 1 || maxColors > 120)
  109. return NULL;
  110. SetupImage *instance = new SetupImage(hdc, bitmapSource, maxColors);
  111. if (NULL == instance) return NULL;
  112. if (NULL == instance->bitmap || NULL == instance->table)
  113. {
  114. instance->Release();
  115. instance = NULL;
  116. }
  117. return instance;
  118. }
  119. SetupImage *SetupImage::CreateFromPluginBitmap(HDC hdc, LPCWSTR pszModuleName, LPCWSTR resourceName, INT maxColors)
  120. {
  121. SetupImage *instance = NULL;
  122. WCHAR szPath[MAX_PATH] = {0};
  123. if (0 != GetModuleFileName(WASABI_API_ORIG_HINST, szPath, ARRAYSIZE(szPath)))
  124. {
  125. PathRemoveFileSpec(szPath);
  126. PathAppend(szPath, pszModuleName);
  127. HMODULE hModule = LoadLibraryEx(szPath, NULL, LOAD_LIBRARY_AS_DATAFILE | 0x00000020/*LOAD_LIBRARY_AS_IMAGE_RESOURCE*/);
  128. if (NULL != hModule)
  129. {
  130. HBITMAP bitmapSource = (HBITMAP)LoadImage(hModule, resourceName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
  131. if (NULL != bitmapSource)
  132. instance = CreateInstance(hdc, bitmapSource, maxColors);
  133. FreeLibrary(hModule);
  134. }
  135. }
  136. return instance;
  137. }
  138. ULONG SetupImage::AddRef()
  139. {
  140. return InterlockedIncrement((LONG*)&ref);
  141. }
  142. ULONG SetupImage::Release()
  143. {
  144. if (0 == ref)
  145. return ref;
  146. LONG r = InterlockedDecrement((LONG*)&ref);
  147. if (0 == r)
  148. delete(this);
  149. return r;
  150. }
  151. BOOL SetupImage::GetSize(SIZE *pSize)
  152. {
  153. if (NULL == pSize) return FALSE;
  154. INT cy = header.biHeight;
  155. if (cy < 0) cy = -cy;
  156. pSize->cx = header.biWidth;
  157. pSize->cy = cy / (tableSize + 1);
  158. return TRUE;
  159. }
  160. BOOL SetupImage::DrawImage(HDC hdc, INT x, INT y, INT cx, INT cy, INT srcX, INT srcY, COLORREF rgbBk, COLORREF rgbFg)
  161. {
  162. BYTE bitmapIndex = 0xFF;
  163. SIZE imageSize;
  164. if (!GetSize(&imageSize))
  165. return FALSE;
  166. for(BYTE i = readCursor; i < tableCount; i++)
  167. {
  168. if (table[i].rgbBk == rgbBk && table[i].rgbFg == rgbFg)
  169. {
  170. bitmapIndex = i;
  171. break;
  172. }
  173. }
  174. if (0xFF == bitmapIndex)
  175. {
  176. if (readCursor > tableCount)
  177. readCursor = tableCount;
  178. for(BYTE i = 0; i < readCursor; i++)
  179. {
  180. if (table[i].rgbBk == rgbBk && table[i].rgbFg == rgbFg)
  181. {
  182. bitmapIndex = i;
  183. break;
  184. }
  185. }
  186. if (0xFF == bitmapIndex)
  187. {
  188. if (tableCount < tableSize)
  189. {
  190. insertCursor = tableCount;
  191. tableCount++;
  192. }
  193. else if (++insertCursor == tableCount)
  194. insertCursor = 0;
  195. INT targetY = (insertCursor + 1) * imageSize.cy;
  196. if (!SetupImage_ColorizeImage(pixels, 0, 0, imageSize.cx, imageSize.cy,
  197. header.biBitCount, 0, targetY, rgbBk, rgbFg, TRUE))
  198. {
  199. return FALSE;
  200. }
  201. table[insertCursor].rgbBk = rgbBk;
  202. table[insertCursor].rgbFg = rgbFg;
  203. bitmapIndex = insertCursor;
  204. }
  205. }
  206. readCursor = bitmapIndex;
  207. srcY += ((bitmapIndex + 1) * imageSize.cy);
  208. INT dstY = y;
  209. INT dstCY = cy;
  210. INT imageHeight = header.biHeight;
  211. if (imageHeight < 0)
  212. {
  213. header.biHeight = -imageHeight;
  214. dstY += (cy - 1);
  215. dstCY = -cy;
  216. }
  217. BOOL resultOk = StretchDIBits(hdc, x, dstY, cx, dstCY, srcX, srcY, cx, cy,
  218. pixels, (BITMAPINFO*)&header, DIB_RGB_COLORS, SRCCOPY);
  219. if (imageHeight < 0)
  220. header.biHeight = imageHeight;
  221. return resultOk;
  222. }
  223. BOOL SetupImage::ResetCache()
  224. {
  225. if (NULL != table)
  226. ZeroMemory(&table, sizeof(IMAGEINDEX) * tableSize);
  227. tableCount = 0;
  228. insertCursor = 0;
  229. readCursor = 0;
  230. return TRUE;
  231. }