alphablit.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. #include "GREEN/BLiT/BLIT.H"
  19. #include "ORANGE/color/colormatch.h"
  20. #include "GREEN/BLiT/alphablit.h" // do NOT yet put in with blit.h (until done)
  21. //////////////////////////////////////////////////////////////////////
  22. //
  23. // ALPHABLIT.CPP
  24. //
  25. // Created in 1996 JRD
  26. // Implemented throughout 1996 and 1997 - JRD
  27. //
  28. // 07/10/97 JRD Finally added history section.
  29. //
  30. //////////////////////////////////////////////////////////////////////
  31. //***********************************************************************************
  32. // Here are some easy utilities that are useful in dealing with alpha masks:
  33. //***********************************************************************************
  34. /////////////////////////////////////////////////////////////////////////////////////
  35. // Allows "Ad Hoc" alpha adjustment with accumulative error.
  36. // (CAUTION, not reversable, UNLESS a DIFFERENT destination
  37. // mask is used from the source. Will saturate at 255.
  38. /////////////////////////////////////////////////////////////////////////////////////
  39. // UINPUT: 1.0 = no change in alpha effect, pimDst may equal pimMask
  40. /////////////////////////////////////////////////////////////////////////////////////
  41. //
  42. void rspScaleAlphaMask(RImage* pimSrc, double dScale, RImage* pimDst)
  43. {
  44. short i,j;
  45. long lSrcP = pimSrc->m_lPitch;
  46. long lDstP = pimDst->m_lPitch;
  47. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData;
  48. UCHAR* pDst,*pDstLine = pimDst->m_pData;
  49. for (j=0;j<pimSrc->m_sHeight;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  50. {
  51. pSrc = pSrcLine;
  52. pDst = pDstLine;
  53. for (i=0;i<pimSrc->m_sWidth;i++,pSrc++,pDst++)
  54. {
  55. double dVal = double(*pSrc);
  56. dVal *= dScale;
  57. if (dVal < 256.0)
  58. *pDst = UCHAR(dVal);
  59. else
  60. *pDst = UCHAR(255);
  61. }
  62. }
  63. }
  64. // The mask must be as big as the source
  65. // Should work on both main types.
  66. //
  67. void rspGeneralAlphaBlit(RMultiAlpha* pX,RImage* pimMask,
  68. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  69. RRect &rDstClip)
  70. {
  71. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  72. // right here adjust things if you need to clip to other thatn the full dst im
  73. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  74. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  75. short i,j;
  76. long lSrcP = pimSrc->m_lPitch;
  77. long lDstP = pimDst->m_lPitch;
  78. long lMaskP = pimMask->m_lPitch;
  79. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  80. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  81. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  82. UCHAR*** pppucAlphaList = pX->m_pGeneralAlpha;
  83. UCHAR ucTransparent = *(pX->m_pLevelOpacity);
  84. // set clip off at half lowest level value!
  85. // MUST ROUND UP!
  86. ucTransparent = (ucTransparent+1) >> 1;
  87. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  88. {
  89. pSrc = pSrcLine;
  90. pDst = pDstLine;
  91. pMask = pMaskLine;
  92. UCHAR ucMask;
  93. UCHAR** pucTable;
  94. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  95. {
  96. ucMask = *pMask;
  97. if (ucMask >= ucTransparent)
  98. {
  99. pucTable = pppucAlphaList[ucMask];
  100. if (pucTable) // There is an alpha channel
  101. {
  102. *pDst = pucTable[*pSrc][*pDst];
  103. }
  104. else // it is opaque
  105. {
  106. *pDst = *pSrc;
  107. }
  108. }
  109. }
  110. }
  111. }
  112. // The mask must be as big as the source
  113. // Should work on both main types.
  114. // This does a pre-dimming of the mask based on sLevel -> 255 = as is!
  115. //
  116. void rspGeneralAlphaBlit(short sLevel,RMultiAlpha* pX,RImage* pimMask,
  117. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  118. RRect &rDstClip)
  119. {
  120. ASSERT( (sLevel >= 0 ) && (sLevel < 256) );
  121. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  122. // right here adjust things if you need to clip to other thatn the full dst im
  123. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  124. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  125. short i,j;
  126. long lSrcP = pimSrc->m_lPitch;
  127. long lDstP = pimDst->m_lPitch;
  128. long lMaskP = pimMask->m_lPitch;
  129. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  130. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  131. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  132. UCHAR*** pppucAlphaList = pX->m_pGeneralAlpha;
  133. UCHAR ucTransparent = *(pX->m_pLevelOpacity);
  134. // set clip off at half lowest level value!
  135. // MUST ROUND UP!
  136. ucTransparent = (ucTransparent+1) >> 1;
  137. // Set up the dimming parameter
  138. UCHAR* pucDim = &RMultiAlpha::ms_aucLiveDimming[sLevel*256];
  139. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  140. {
  141. pSrc = pSrcLine;
  142. pDst = pDstLine;
  143. pMask = pMaskLine;
  144. UCHAR ucMask;
  145. UCHAR** pucTable;
  146. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  147. {
  148. ucMask = pucDim[*pMask]; // do the dynamic dimming!
  149. if (ucMask >= ucTransparent)
  150. {
  151. pucTable = pppucAlphaList[ucMask];
  152. if (pucTable) // There is an alpha channel
  153. {
  154. *pDst = pucTable[*pSrc][*pDst];
  155. }
  156. else // it is opaque
  157. {
  158. *pDst = *pSrc;
  159. }
  160. }
  161. }
  162. }
  163. }
  164. // The mask must be as big as the source
  165. // Should work on both main types.
  166. // This does a pre-dimming of the mask based on sLevel -> 255 = as is!
  167. //
  168. extern void rspGeneralAlphaBlitT(short sLevel,RMultiAlpha* pX,RImage* pimMask,
  169. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  170. RRect &rDstClip)
  171. {
  172. ASSERT( (sLevel >= 0 ) && (sLevel < 256) );
  173. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  174. // right here adjust things if you need to clip to other thatn the full dst im
  175. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  176. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  177. short i,j;
  178. long lSrcP = pimSrc->m_lPitch;
  179. long lDstP = pimDst->m_lPitch;
  180. long lMaskP = pimMask->m_lPitch;
  181. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  182. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  183. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  184. UCHAR*** pppucAlphaList = pX->m_pGeneralAlpha;
  185. UCHAR ucTransparent = *(pX->m_pLevelOpacity);
  186. // set clip off at half lowest level value!
  187. // MUST ROUND UP!
  188. ucTransparent = (ucTransparent+1) >> 1;
  189. // Set up the dimming parameter
  190. UCHAR* pucDim = &RMultiAlpha::ms_aucLiveDimming[sLevel*256];
  191. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  192. {
  193. pSrc = pSrcLine;
  194. pDst = pDstLine;
  195. pMask = pMaskLine;
  196. UCHAR ucMask;
  197. UCHAR** pucTable;
  198. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  199. {
  200. UCHAR ucSrc = *pSrc;
  201. if (ucSrc)
  202. {
  203. ucMask = pucDim[*pMask]; // do the dynamic dimming!
  204. if (ucMask >= ucTransparent)
  205. {
  206. pucTable = pppucAlphaList[ucMask];
  207. if (pucTable) // There is an alpha channel
  208. {
  209. *pDst = pucTable[*pSrc][*pDst];
  210. }
  211. else // it is opaque
  212. {
  213. *pDst = *pSrc;
  214. }
  215. }
  216. }
  217. }
  218. }
  219. }
  220. // The mask must be as big as the source
  221. // This Uses a Fast Multi Alpha, which leave NO ROOM for the SLIGHTEST error!
  222. // In release mode, this will likely crash if a blit occurs which
  223. // leaves the range of source or destination colors.
  224. //
  225. void rspFastMaskAlphaBlit(UCHAR*** pfaX,RImage* pimMask,
  226. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  227. RRect &rDstClip)
  228. {
  229. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  230. // right here adjust things if you need to clip to other thatn the full dst im
  231. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  232. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  233. short i,j;
  234. long lSrcP = pimSrc->m_lPitch;
  235. long lDstP = pimDst->m_lPitch;
  236. long lMaskP = pimMask->m_lPitch;
  237. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  238. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  239. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  240. UCHAR ucTransparent = *( (UCHAR*)pfaX ); // secret code!
  241. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  242. {
  243. pSrc = pSrcLine;
  244. pDst = pDstLine;
  245. pMask = pMaskLine;
  246. UCHAR ucMask;
  247. UCHAR** pucTable;
  248. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  249. {
  250. ucMask = *pMask;
  251. if (ucMask >= ucTransparent)
  252. {
  253. pucTable = pfaX[ucMask];
  254. if (pucTable) // There is an alpha channel
  255. {
  256. ASSERT(pucTable[*pSrc]); // catch source errors
  257. *pDst = *(pucTable[*pSrc] + *pDst);
  258. }
  259. else // it is opaque
  260. {
  261. *pDst = *pSrc;
  262. }
  263. }
  264. }
  265. }
  266. }
  267. // The mask must be as big as the source
  268. // This Uses a Fast Multi Alpha, which leave NO ROOM for the SLIGHTEST error!
  269. // In release mode, this will likely crash if a blit occurs which
  270. // leaves the range of source or destination colors.
  271. //
  272. // One exception here is that
  273. //
  274. void rspFastMaskAlphaBlitT(UCHAR*** pfaX,RImage* pimMask,
  275. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  276. RRect &rDstClip)
  277. {
  278. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  279. // right here adjust things if you need to clip to other thatn the full dst im
  280. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  281. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  282. short i,j;
  283. long lSrcP = pimSrc->m_lPitch;
  284. long lDstP = pimDst->m_lPitch;
  285. long lMaskP = pimMask->m_lPitch;
  286. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  287. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  288. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  289. UCHAR ucTransparent = *( (UCHAR*)pfaX ); // secret code!
  290. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  291. {
  292. pSrc = pSrcLine;
  293. pDst = pDstLine;
  294. pMask = pMaskLine;
  295. UCHAR ucMask;
  296. UCHAR** pucTable;
  297. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  298. {
  299. UCHAR ucPix = *pSrc;
  300. if (ucPix)
  301. {
  302. ucMask = *pMask;
  303. if (ucMask >= ucTransparent)
  304. {
  305. pucTable = pfaX[ucMask];
  306. if (pucTable) // There is an alpha channel
  307. {
  308. ASSERT(pucTable[ucPix]); // catch source errors
  309. *pDst = *(pucTable[ucPix] + *pDst);
  310. }
  311. else // it is opaque
  312. {
  313. *pDst = ucPix;
  314. }
  315. }
  316. }
  317. }
  318. }
  319. }
  320. // The mask must be as big as the source
  321. // ARCHAIC - this was back when instead of a mask specifying 0-255, it specified
  322. // the layer number
  323. //
  324. /*
  325. extern void rspAlphaMaskBlit(RMultiAlpha* pX,RImage* pimMask,
  326. RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  327. RRect &rDstClip)
  328. {
  329. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  330. // right here adjust things if you need to clip to other thatn the full dst im
  331. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,
  332. rDstClip.sX,rDstClip.sY,rDstClip.sW,rDstClip.sH) == -1) return ; // clipped out
  333. short i,j;
  334. long lSrcP = pimSrc->m_lPitch;
  335. long lDstP = pimDst->m_lPitch;
  336. long lMaskP = pimMask->m_lPitch;
  337. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  338. UCHAR* pMask,*pMaskLine = pimMask->m_pData + sSrcX + sSrcY * lSrcP;
  339. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  340. UCHAR ucOpaque = (UCHAR) pX->m_sNumLevels;
  341. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP,pMaskLine += lMaskP)
  342. {
  343. pSrc = pSrcLine;
  344. pDst = pDstLine;
  345. pMask = pMaskLine;
  346. UCHAR ucMask;
  347. for (i=0;i<sDstW;i++,pSrc++,pDst++,pMask++)
  348. {
  349. ucMask = *pMask;
  350. if (ucMask)
  351. {
  352. if (ucMask == ucOpaque) // optimized for mostly opqaue mask:
  353. {
  354. *pDst = *pSrc;
  355. }
  356. else
  357. {
  358. *pDst = pX->m_pAlphaList[ucMask]->m_pAlphas[*pSrc][*pDst];
  359. }
  360. }
  361. }
  362. }
  363. }
  364. */
  365. // Here is a wrapper so that the homogenous alpha blit can use a multialpha:
  366. // sAlphaLevel goes from 0 (you see background) to 255 (you see the sprite)
  367. // As the name implies, this does not consider source colors of index zero.
  368. //
  369. void rspAlphaBlitT(short sAlphaLevel,RMultiAlpha* pMultiX,RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  370. RRect* prDst)
  371. {
  372. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  373. // right here adjust things if you need to clip to other thatn the full dst im
  374. if (prDst == NULL)
  375. {
  376. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,0,0,
  377. pimDst->m_sWidth,pimDst->m_sHeight) == -1) return ; // clipped out
  378. }
  379. else
  380. {
  381. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,prDst->sX,prDst->sY,
  382. prDst->sW,prDst->sH) == -1) return ; // clipped out
  383. }
  384. short i,j;
  385. long lSrcP = pimSrc->m_lPitch;
  386. long lDstP = pimDst->m_lPitch;
  387. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  388. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  389. UCHAR ucTransparent = *(pMultiX->m_pLevelOpacity);
  390. // Test out trivial conditions:
  391. // Check on 1/2 the lowest vales as a cross over point!
  392. // Must round up!
  393. if (sAlphaLevel <= short((ucTransparent+1)>>1)) return;
  394. UCHAR** ppucAlpha = pMultiX->m_pGeneralAlpha[sAlphaLevel];
  395. if (!ppucAlpha) // it is opaque!
  396. {
  397. rspBlitT(0,pimSrc,pimDst,sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,NULL,NULL);
  398. return;
  399. }
  400. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  401. {
  402. pSrc = pSrcLine;
  403. pDst = pDstLine;
  404. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  405. {
  406. UCHAR ucPix = *pSrc;
  407. if (ucPix) *pDst = ppucAlpha[ucPix][*pDst];
  408. }
  409. }
  410. }
  411. // Here is a wrapper so that the homogenous alpha blit can use a multialpha:
  412. // sAlphaLevel goes from 0 (you see background) to 255 (you see the sprite)
  413. // As the name implies, this does not consider source colors of index zero.
  414. //
  415. void rspFastAlphaBlitT(short sAlphaLevel,UCHAR*** pMultiX,RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY,
  416. RRect* prDst)
  417. {
  418. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  419. // right here adjust things if you need to clip to other thatn the full dst im
  420. if (prDst == NULL)
  421. {
  422. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,0,0,
  423. pimDst->m_sWidth,pimDst->m_sHeight) == -1) return ; // clipped out
  424. }
  425. else
  426. {
  427. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,prDst->sX,prDst->sY,
  428. prDst->sW,prDst->sH) == -1) return ; // clipped out
  429. }
  430. short i,j;
  431. long lSrcP = pimSrc->m_lPitch;
  432. long lDstP = pimDst->m_lPitch;
  433. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  434. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  435. UCHAR ucTransparent = *((UCHAR*)pMultiX); // Secret Code
  436. // Test out trivial conditions:
  437. if (sAlphaLevel <= short(ucTransparent)) return;
  438. UCHAR** ppucAlpha = pMultiX[sAlphaLevel];
  439. if (!ppucAlpha) // it is opaque!
  440. {
  441. rspBlitT(0,pimSrc,pimDst,sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,NULL,NULL);
  442. return;
  443. }
  444. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  445. {
  446. pSrc = pSrcLine;
  447. pDst = pDstLine;
  448. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  449. {
  450. UCHAR ucPix = *pSrc;
  451. if (ucPix) *pDst = ppucAlpha[ucPix][*pDst];
  452. }
  453. }
  454. }
  455. void rspAlphaBlit(RAlpha* pX,RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY)
  456. {
  457. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  458. // right here adjust things if you need to clip to other thatn the full dst im
  459. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,0,0,
  460. pimDst->m_sWidth,pimDst->m_sHeight) == -1) return ; // clipped out
  461. short i,j;
  462. long lSrcP = pimSrc->m_lPitch;
  463. long lDstP = pimDst->m_lPitch;
  464. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  465. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  466. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  467. {
  468. pSrc = pSrcLine;
  469. pDst = pDstLine;
  470. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  471. {
  472. *pDst = pX->m_pAlphas[*pSrc][*pDst];
  473. }
  474. }
  475. }
  476. void rspAlphaBlitT(RAlpha* pX,RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY)
  477. {
  478. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  479. // right here adjust things if you need to clip to other thatn the full dst im
  480. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,0,0,
  481. pimDst->m_sWidth,pimDst->m_sHeight) == -1) return ; // clipped out
  482. short i,j;
  483. long lSrcP = pimSrc->m_lPitch;
  484. long lDstP = pimDst->m_lPitch;
  485. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  486. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  487. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  488. {
  489. pSrc = pSrcLine;
  490. pDst = pDstLine;
  491. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  492. {
  493. UCHAR ucSrc = *pSrc;
  494. if (ucSrc)
  495. *pDst = pX->m_pAlphas[ucSrc][*pDst];
  496. }
  497. }
  498. }
  499. // This draws source to destination with clipping only if destination is not zero!
  500. // NOTE that this technique is only valid for adding to fully opaque masks.
  501. // For more deluxe compound masking, you need to only change if source < dest!
  502. //
  503. void rspMaskBlit(RImage* pimSrc,RImage* pimDst,short sDstX,short sDstY)
  504. {
  505. short sSrcX = 0,sSrcY = 0,sDstW = pimSrc->m_sWidth,sDstH = pimSrc->m_sHeight;
  506. // right here adjust things if you need to clip to other thatn the full dst im
  507. if (rspSimpleClip(sSrcX,sSrcY,sDstX,sDstY,sDstW,sDstH,0,0,
  508. pimDst->m_sWidth,pimDst->m_sHeight) == -1) return ; // clipped out
  509. short i,j;
  510. long lSrcP = pimSrc->m_lPitch;
  511. long lDstP = pimDst->m_lPitch;
  512. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData + sSrcX + sSrcY * lSrcP;
  513. UCHAR* pDst,*pDstLine = pimDst->m_pData + sDstX + lDstP * sDstY;
  514. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  515. {
  516. pSrc = pSrcLine;
  517. pDst = pDstLine;
  518. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  519. {
  520. if (*pDst) *pDst = *pSrc;
  521. }
  522. }
  523. }
  524. // Takes a BMP8 and converts it to a mask of 0 and ucVal
  525. void rspMakeMask(RImage* pimSrc,UCHAR ucVal)
  526. {
  527. short i,j;
  528. long lSrcP = pimSrc->m_lPitch;
  529. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData;
  530. for (j=0;j<pimSrc->m_sHeight;j++,pSrcLine += lSrcP)
  531. {
  532. pSrc = pSrcLine;
  533. for (i=0;i<pimSrc->m_sWidth;i++,pSrc++)
  534. {
  535. if (*pSrc) *pSrc = ucVal; // replace all as mask
  536. }
  537. }
  538. }
  539. // Takes a BMP8 and converts it to a mask of 0 and ucVal
  540. // Currently, no clipping or positioning possible
  541. void rspCopyAsMask(RImage* pimSrc,RImage* pimDst,UCHAR ucVal)
  542. {
  543. short i,j;
  544. long lSrcP = pimSrc->m_lPitch;
  545. long lDstP = pimDst->m_lPitch;
  546. UCHAR* pSrc,*pSrcLine = pimSrc->m_pData;
  547. UCHAR* pDst,*pDstLine = pimDst->m_pData;
  548. short sDstW = pimSrc->m_sWidth;
  549. short sDstH = pimSrc->m_sHeight;
  550. for (j=0;j<sDstH;j++,pSrcLine += lSrcP,pDstLine += lDstP)
  551. {
  552. pSrc = pSrcLine;
  553. pDst = pDstLine;
  554. for (i=0;i<sDstW;i++,pSrc++,pDst++)
  555. {
  556. if (*pSrc) *pDst = ucVal; // replace all as mask
  557. else
  558. *pDst = 0;
  559. }
  560. }
  561. }