graphics.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. #include "./graphics.h"
  2. #include "./shlwapi.h"
  3. BOOL Image_ColorOverEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgb)
  4. {
  5. LONG pitch;
  6. UINT a, r, g, b, ma, mr, mg, mb;
  7. INT step = (bpp>>3);
  8. LPBYTE line, cursor;
  9. pitch = bitmapCX * step;
  10. while (pitch%4) pitch++;
  11. if (step < 3)
  12. return TRUE;
  13. if (cy < 0) cy -= cy;
  14. a = (LOBYTE((rgb)>>24)); r = GetRValue(rgb); g = GetGValue(rgb); b = GetBValue(rgb);
  15. ma = 255 - a; mr = r * 255; mg = g * 255; mb = b * 255;
  16. if (0 == a)
  17. return TRUE;
  18. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  19. line = pPixels + pitch * ofs + x*step;
  20. if (0xFF == a)
  21. {
  22. for (; cy-- != 0; line += pitch)
  23. {
  24. for (x = cx, cursor = line; x-- != 0; cursor += step)
  25. {
  26. cursor[0] = (BYTE)b;
  27. cursor[1] = (BYTE)g;
  28. cursor[2] = (BYTE)r;
  29. // cursor[3] = 0xFF;
  30. }
  31. }
  32. return TRUE;
  33. }
  34. if (premult)
  35. {
  36. for (; cy-- != 0; line += pitch)
  37. {
  38. for (x = cx, cursor = line; x-- != 0; cursor += step)
  39. {
  40. UINT t = (mb + ma * cursor[0] + 127) / 255;
  41. cursor[0] = (t > 0xFF) ? 0xFF : t;
  42. t = (mg + ma * cursor[1] + 127) / 255;
  43. cursor[1] = (t > 0xFF) ? 0xFF : t;
  44. t = (mr+ ma * cursor[2] + 127) / 255;
  45. cursor[2] = (t > 0xFF) ? 0xFF : t;
  46. }
  47. }
  48. }
  49. else
  50. {
  51. WORD k = (((255 - a)*255 + 127)/255);
  52. for (; cy-- != 0; line += pitch)
  53. {
  54. for (x = cx, cursor = line; x-- != 0; cursor += step)
  55. {
  56. cursor[0] = (b*a + k*cursor[0] + 127)/255;
  57. cursor[1] = (g*a + k*cursor[1] + 127)/255;
  58. cursor[2] = (r*a + k*cursor[2] + 127)/255;
  59. // cursor[3] = (a*a + k*cursor[3] + 127)/255;
  60. }
  61. }
  62. }
  63. return TRUE;
  64. }
  65. BOOL Image_ColorizeEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgbBottom, COLORREF rgbTop)
  66. {
  67. LONG pitch;
  68. UINT rBottom, gBottom, bBottom;
  69. UINT rTop, gTop, bTop;
  70. INT step = (bpp>>3);
  71. LPBYTE startLine, line, cursor;
  72. pitch = bitmapCX * step;
  73. while (pitch%4) pitch++;
  74. if (cy < 0)
  75. cy = -cy;
  76. rBottom = GetRValue(rgbBottom);
  77. gBottom = GetGValue(rgbBottom);
  78. bBottom = GetBValue(rgbBottom);
  79. rTop = GetRValue(rgbTop);
  80. gTop = GetGValue(rgbTop);
  81. bTop = GetBValue(rgbTop);
  82. UINT a, k;
  83. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  84. startLine = pPixels + pitch * ofs + x*step;
  85. line = startLine;
  86. for (y = cy; y-- != 0; line += pitch)
  87. {
  88. for (x = cx, cursor = line; x-- != 0; cursor += step)
  89. {
  90. a = (255- cursor[2]);
  91. if (a < 0) a = 0;
  92. if (a > 254)
  93. {
  94. cursor[0] = bTop;
  95. cursor[1] = gTop;
  96. cursor[2] = rTop;
  97. }
  98. else if (a== 0)
  99. {
  100. cursor[0] = bBottom;
  101. cursor[1] = gBottom;
  102. cursor[2] = rBottom;
  103. }
  104. else
  105. {
  106. k = (((255 - a)*255 + 127)/255);
  107. cursor[0] = (bTop * a + k*bBottom + 127)/255;
  108. cursor[1] = (gTop * a + k*gBottom + 127)/255;
  109. cursor[2] = (rTop * a + k*rBottom + 127)/255;
  110. }
  111. }
  112. }
  113. if (32 == bpp && FALSE != premult)
  114. {
  115. line = startLine;
  116. for (y = cy; y-- != 0; line += pitch)
  117. {
  118. for (x = cx, cursor = line; x-- != 0; cursor += step)
  119. {
  120. a = cursor[3];
  121. k = MulDiv(cursor[0], a, 255);
  122. cursor[0] = (k < 255) ? k : 255;
  123. k = MulDiv(cursor[1], a, 255);
  124. cursor[1] = (k < 255) ? k : 255;
  125. k = MulDiv(cursor[2], a, 255);
  126. cursor[2] = (k < 255) ? k : 255;
  127. }
  128. }
  129. }
  130. return TRUE;
  131. }
  132. BOOL Image_PremultiplyEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp)
  133. {
  134. if (32 != bpp)
  135. return FALSE;
  136. LONG pitch;
  137. INT step = (bpp>>3);
  138. LPBYTE line, cursor;
  139. pitch = bitmapCX * step;
  140. while (pitch%4) pitch++;
  141. if (cy < 0)
  142. cy = -cy;
  143. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  144. line = pPixels + pitch * ofs + x*step;
  145. UINT a,k;
  146. for (; cy-- != 0; line += pitch)
  147. {
  148. for (x = cx, cursor = line; x-- != 0; cursor += step)
  149. {
  150. a = cursor[3];
  151. if (0 == a)
  152. {
  153. cursor[0] = 0;
  154. cursor[1] = 0;
  155. cursor[2] = 0;
  156. }
  157. else if (255 != a)
  158. {
  159. k = MulDiv((UINT)cursor[0], a, 255);
  160. cursor[0] = (k < 255) ? k : 255;
  161. k = MulDiv((UINT)cursor[1], a, 255);
  162. cursor[1] = (k < 255) ? k : 255;
  163. k = MulDiv((UINT)cursor[2], a, 255);
  164. cursor[2] = (k < 255) ? k : 255;
  165. }
  166. }
  167. }
  168. return TRUE;
  169. }
  170. BOOL Image_SaturateEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale)
  171. {
  172. if (32 != bpp)
  173. return FALSE;
  174. LONG pitch;
  175. INT step = (bpp>>3);
  176. LPBYTE line, cursor;
  177. pitch = bitmapCX * step;
  178. while (pitch%4) pitch++;
  179. if (FALSE == fScale)
  180. {
  181. if (n < 0) n = 0;
  182. else if (n > 1000) n = 1000;
  183. }
  184. else
  185. {
  186. if (n < -1000) n = -1000;
  187. else if (n > 1000) n = 1000;
  188. }
  189. if (cy < 0)
  190. cy = -cy;
  191. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  192. line = pPixels + pitch * ofs + x*step;
  193. COLORREF rgb;
  194. INT k;
  195. WORD h, l, s;
  196. for (; cy-- != 0; line += pitch)
  197. {
  198. for (x = cx, cursor = line; x-- != 0; cursor += step)
  199. {
  200. rgb = RGB(cursor[2], cursor[1], cursor[0]);
  201. ColorRGBToHLS(rgb, &h, &l, &s);
  202. if(FALSE == fScale)
  203. s = ((WORD)((240 * n)/1000));
  204. else
  205. {
  206. k = s;
  207. s = (WORD)(k + (k * n) /1000);
  208. }
  209. rgb = ColorHLSToRGB(h, l, s);
  210. cursor[0] = GetBValue(rgb);
  211. cursor[1] = GetGValue(rgb);
  212. cursor[2] = GetRValue(rgb);
  213. }
  214. }
  215. return TRUE;
  216. }
  217. BOOL Image_AdjustAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale)
  218. {
  219. if (32 != bpp)
  220. return FALSE;
  221. LONG pitch;
  222. INT step = (bpp>>3);
  223. LPBYTE line, cursor;
  224. pitch = bitmapCX * step;
  225. while (pitch%4) pitch++;
  226. if (FALSE == fScale)
  227. {
  228. if (n < 0) n = 0;
  229. else if (n > 1000) n = 1000;
  230. }
  231. else
  232. {
  233. if (n < -1000) n = -1000;
  234. else if (n > 1000) n = 1000;
  235. }
  236. if (cy < 0)
  237. cy = -cy;
  238. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  239. line = pPixels + pitch * ofs + x*step;
  240. INT k;
  241. for (; cy-- != 0; line += pitch)
  242. {
  243. for (x = cx, cursor = line; x-- != 0; cursor += step)
  244. {
  245. if(FALSE == fScale)
  246. cursor[3] = ((BYTE)((255 * n)/1000));
  247. else
  248. {
  249. k = cursor[3];
  250. k = k + MulDiv(k, n, 1000);
  251. if (k > 255) k = 255;
  252. cursor[3] = (BYTE)k;
  253. }
  254. }
  255. }
  256. return TRUE;
  257. }
  258. BOOL Image_AdjustSaturationAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT nSaturation, INT nAlpha)
  259. {
  260. if (32 != bpp)
  261. return FALSE;
  262. LONG pitch;
  263. INT step = (bpp>>3);
  264. LPBYTE line, cursor;
  265. pitch = bitmapCX * step;
  266. while (pitch%4) pitch++;
  267. if (nSaturation < -1000) nSaturation = -1000;
  268. else if (nSaturation > 1000) nSaturation = 1000;
  269. if (nAlpha < -1000) nAlpha = -1000;
  270. else if (nAlpha > 1000) nAlpha = 1000;
  271. if (cy < 0)
  272. cy = -cy;
  273. INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
  274. line = pPixels + pitch * ofs + x*step;
  275. INT k;
  276. COLORREF rgb;
  277. WORD h, l, s;
  278. for (; cy-- != 0; line += pitch)
  279. {
  280. for (x = cx, cursor = line; x-- != 0; cursor += step)
  281. {
  282. k = cursor[3];
  283. k = k + MulDiv(k, nAlpha, 1000);
  284. if (k > 255) k = 255;
  285. cursor[3] = (BYTE)k;
  286. rgb = RGB(cursor[2], cursor[1], cursor[0]);
  287. ColorRGBToHLS(rgb, &h, &l, &s);
  288. k = s;
  289. k = k + MulDiv(k, nSaturation, 1000);
  290. if (k > 240) k = 240;
  291. s = (WORD)k;
  292. rgb = ColorHLSToRGB(h, l, s);
  293. cursor[0] = GetBValue(rgb);
  294. cursor[1] = GetGValue(rgb);
  295. cursor[2] = GetRValue(rgb);
  296. }
  297. }
  298. return TRUE;
  299. }
  300. BOOL Image_ColorOver(HBITMAP hbmp, RECT *prcPart, BOOL premult, COLORREF rgb)
  301. {
  302. DIBSECTION dibsec;
  303. if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
  304. BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
  305. return FALSE;
  306. return Image_ColorOverEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
  307. prcPart->left, prcPart->top,
  308. prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
  309. dibsec.dsBm.bmBitsPixel, premult, rgb);
  310. }
  311. BOOL Image_Premultiply(HBITMAP hbmp, RECT *prcPart)
  312. {
  313. DIBSECTION dibsec;
  314. if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
  315. BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
  316. return FALSE;
  317. return Image_PremultiplyEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
  318. prcPart->left, prcPart->top,
  319. prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
  320. dibsec.dsBm.bmBitsPixel);
  321. }
  322. BOOL Image_Saturate(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale)
  323. {
  324. DIBSECTION dibsec;
  325. if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
  326. BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
  327. return FALSE;
  328. return Image_SaturateEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
  329. prcPart->left, prcPart->top,
  330. prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
  331. dibsec.dsBm.bmBitsPixel, n, fScale);
  332. }
  333. BOOL Image_AdjustAlpha(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale)
  334. {
  335. DIBSECTION dibsec;
  336. if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
  337. BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
  338. return FALSE;
  339. return Image_AdjustAlphaEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
  340. prcPart->left, prcPart->top,
  341. prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
  342. dibsec.dsBm.bmBitsPixel, n, fScale);
  343. }
  344. BOOL Image_AdjustSaturationAlpha(HBITMAP hbmp, RECT *prcPart, INT nSaturation, INT nAlpha)
  345. {
  346. DIBSECTION dibsec;
  347. if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
  348. BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
  349. return FALSE;
  350. return Image_AdjustSaturationAlphaEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
  351. prcPart->left, prcPart->top,
  352. prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
  353. dibsec.dsBm.bmBitsPixel, nSaturation, nAlpha);
  354. }
  355. COLORREF Color_Blend(COLORREF rgbTop, COLORREF rgbBottom, INT alpha)
  356. {
  357. if (alpha > 254) return rgbTop;
  358. if (alpha < 0) return rgbBottom;
  359. WORD k = (((255 - alpha)*255 + 127)/255);
  360. return RGB( (GetRValue(rgbTop)*alpha + k*GetRValue(rgbBottom) + 127)/255,
  361. (GetGValue(rgbTop)*alpha + k*GetGValue(rgbBottom) + 127)/255,
  362. (GetBValue(rgbTop)*alpha + k*GetBValue(rgbBottom) + 127)/255);
  363. }