Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1185 lines
36 KiB

  1. #include "precomp.hxx"
  2. #ifdef __cplusplus
  3. extern "C" {
  4. #endif
  5. #include "dpf.h"
  6. #ifdef __cplusplus
  7. }
  8. #endif
  9. //#define BLT0808_FAST_TRANSPARENCY 1 // set to 1 if one wants a faster, less legal
  10. // transparency comparison, set to 0 for a
  11. // perfect safe but slower transparency
  12. // comparison
  13. void Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(BYTE* pSrcScanLine,
  14. int iSrcScanStride,
  15. BYTE* pDstScanLine,
  16. int iDstScanStride,
  17. int iNumDstCols,
  18. int iNumDstRows)
  19. {
  20. DWORD *pBigSrcPixel,
  21. *pBigDstPixel,
  22. *pBigEndDstPixel;
  23. BYTE *pSrcPixel,
  24. *pDstPixel,
  25. *pAlignedSrcPixel,
  26. *pAlignedDstPixel;
  27. int iNumDwordsPerLine = iNumDstCols / 4,
  28. iNumBytesLeftDst = iNumDstCols % 4,
  29. iNumUnalignedSrcBytes,
  30. iNumUnalignedDstBytes,
  31. iNumUnalignByteDiff,
  32. i,j;
  33. DWORD dwSrc1, dwSrc2;
  34. // If the total number of bytes per scan is less than 4, we are
  35. // just going to do a regular byte-wise copy, so skip all this
  36. // alignment junk.....
  37. if(!iNumDwordsPerLine){
  38. iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
  39. }
  40. else{
  41. // Find out if the src and dest pointers are dword aligned
  42. pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
  43. iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
  44. pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
  45. iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
  46. // Now decrement the number of dwords per line and the
  47. // number of bytes left over as appropriate
  48. if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
  49. iNumBytesLeftDst -= iNumUnalignedDstBytes;
  50. else{
  51. iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
  52. if(iNumBytesLeftDst != sizeof(DWORD))
  53. iNumDwordsPerLine--;
  54. }
  55. }
  56. if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
  57. // Do the fast dword copy since the alignments match
  58. for (i = 0; i < iNumDstRows; i++) {
  59. // Set up the first pointers
  60. pSrcPixel = pSrcScanLine;
  61. pDstPixel = pDstScanLine;
  62. // First we need to copy the bytes to get to an aligned dword
  63. for(j=0; j<iNumUnalignedSrcBytes; j++)
  64. *pDstPixel++ = *pSrcPixel++;
  65. // set up pointers to the first 4-pixel chunks
  66. // on src and dst scanlines, and last chunk on
  67. // dst scanline
  68. pBigSrcPixel = (DWORD*) pSrcPixel;
  69. pBigDstPixel = (DWORD*) pDstPixel;
  70. pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
  71. // copy scanline one 4-pixel chunk at a time
  72. while (pBigDstPixel != pBigEndDstPixel) {
  73. *pBigDstPixel++ = *pBigSrcPixel++;
  74. }
  75. // take care of remaining pixels on scanline
  76. if (iNumBytesLeftDst) {
  77. pSrcPixel = (BYTE*) pBigSrcPixel;
  78. pDstPixel = (BYTE*) pBigDstPixel;
  79. for(j=0; j<iNumBytesLeftDst; j++){
  80. *pDstPixel++ = *pSrcPixel++;
  81. }
  82. }
  83. // advance to next scanline
  84. pSrcScanLine += iSrcScanStride;
  85. pDstScanLine += iDstScanStride;
  86. }
  87. }
  88. else{
  89. // Find out the difference between the source and dest unalign offsets
  90. // If the unaligned dest offset is less than the unaligned src offset,
  91. // we need to decrement pSrcScanLine so that we can dword-align the first
  92. // source bytes (the extra bytes added to the beginning of the dword
  93. // will end up getting masked off anyway).
  94. if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
  95. iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
  96. else
  97. iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
  98. iNumUnalignedDstBytes);
  99. // Do the trickier copy since the alignments don't match
  100. for (i = 0; i < iNumDstRows; i++) {
  101. // Set up the first pointers
  102. pSrcPixel = pSrcScanLine;
  103. pDstPixel = pDstScanLine;
  104. // First we need to copy the bytes to get to an aligned dword
  105. for(j=0; j<iNumUnalignedDstBytes; j++)
  106. *pDstPixel++ = *pSrcPixel++;
  107. // set up Dst pointer to the first 4-pixel chunk (dword)
  108. pBigDstPixel = (DWORD *) pDstPixel;
  109. pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
  110. // Set up the temporary dword vars
  111. dwSrc1 = *pBigSrcPixel++;
  112. switch(iNumUnalignByteDiff){
  113. case 1:
  114. for(j=0; j<iNumDwordsPerLine; j++){
  115. dwSrc2 = *pBigSrcPixel++;
  116. *pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
  117. dwSrc1 = dwSrc2;
  118. }
  119. break;
  120. case 2:
  121. for(j=0; j<iNumDwordsPerLine; j++){
  122. dwSrc2 = *pBigSrcPixel++;
  123. *pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
  124. dwSrc1 = dwSrc2;
  125. }
  126. break;
  127. case 3:
  128. for(j=0; j<iNumDwordsPerLine; j++){
  129. dwSrc2 = *pBigSrcPixel++;
  130. *pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
  131. dwSrc1 = dwSrc2;
  132. }
  133. break;
  134. }
  135. // Take care of the bytes left over
  136. pDstPixel = (BYTE *)pBigDstPixel;
  137. pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
  138. // First we need to copy the bytes to get to an aligned dword
  139. for(j=0; j<iNumBytesLeftDst; j++)
  140. *pDstPixel++ = *pSrcPixel++;
  141. // advance to next scanline
  142. pSrcScanLine += iSrcScanStride;
  143. pDstScanLine += iDstScanStride;
  144. }
  145. }
  146. }
  147. void Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(BYTE* pSrcScanLine,
  148. int iSrcScanStride,
  149. int iNumSrcRows,
  150. BYTE* pDstScanLine,
  151. int iDstScanStride,
  152. int iNumDstCols,
  153. int iNumDstRows)
  154. {
  155. DWORD *pBigSrcPixel,
  156. *pBigDstPixel,
  157. *pBigEndDstPixel;
  158. BYTE *pSrcPixel,
  159. *pDstPixel,
  160. *pAlignedSrcPixel,
  161. *pAlignedDstPixel;
  162. int iNumDwordsPerLine = iNumDstCols / 4,
  163. iNumBytesLeftDst = iNumDstCols % 4,
  164. iNumUnalignedSrcBytes,
  165. iNumUnalignedDstBytes,
  166. iNumUnalignByteDiff,
  167. iVertError = 0,
  168. iVertAdvanceError,
  169. iSrcScanAdvance,
  170. i,j;
  171. DWORD dwSrc1, dwSrc2;
  172. // If the total number of bytes per scan is less than 4, we are
  173. // just going to do a regular byte-wise copy, so skip all this
  174. // alignment junk.....
  175. if(!iNumDwordsPerLine){
  176. iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
  177. }
  178. else{
  179. // Find out if the src and dest pointers are dword aligned
  180. pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
  181. iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
  182. pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
  183. iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
  184. // Now decrement the number of dwords per line and the
  185. // number of bytes left over as appropriate
  186. if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
  187. iNumBytesLeftDst -= iNumUnalignedDstBytes;
  188. else{
  189. iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
  190. if(iNumBytesLeftDst != sizeof(DWORD))
  191. iNumDwordsPerLine--;
  192. }
  193. }
  194. if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
  195. // compute advance and error terms for stepping
  196. // vertically through the src bitmap
  197. if (iNumSrcRows < iNumDstRows) {
  198. iSrcScanAdvance = 0;
  199. iVertAdvanceError = iNumSrcRows;
  200. }
  201. else{
  202. iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
  203. iVertAdvanceError = iNumSrcRows % iNumDstRows;
  204. }
  205. // Do the fast dword copy since the alignments match
  206. for (i = 0; i < iNumDstRows; i++) {
  207. // Set up the first pointers
  208. pSrcPixel = pSrcScanLine;
  209. pDstPixel = pDstScanLine;
  210. // First we need to copy the bytes to get to an aligned dword
  211. for(j=0; j<iNumUnalignedSrcBytes; j++)
  212. *pDstPixel++ = *pSrcPixel++;
  213. // set up pointers to the first 4-pixel chunks
  214. // on src and dst scanlines, and last chunk on
  215. // dst scanline
  216. pBigSrcPixel = (DWORD*) pSrcPixel;
  217. pBigDstPixel = (DWORD*) pDstPixel;
  218. pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
  219. // copy scanline one 4-pixel chunk at a time
  220. while (pBigDstPixel != pBigEndDstPixel) {
  221. *pBigDstPixel++ = *pBigSrcPixel++;
  222. }
  223. // take care of remaining pixels on scanline
  224. if (iNumBytesLeftDst) {
  225. pSrcPixel = (BYTE*) pBigSrcPixel;
  226. pDstPixel = (BYTE*) pBigDstPixel;
  227. for(j=0; j<iNumBytesLeftDst; j++){
  228. *pDstPixel++ = *pSrcPixel++;
  229. }
  230. }
  231. // advance to next scanline
  232. pSrcScanLine += iSrcScanAdvance;
  233. pDstScanLine += iDstScanStride;
  234. // update and check vertical stepping error,
  235. // adjust src scanline pointer if necessary
  236. iVertError += iVertAdvanceError;
  237. if (iVertError >= iNumDstRows) {
  238. pSrcScanLine += iSrcScanStride;
  239. iVertError -= iNumDstRows;
  240. }
  241. }
  242. }
  243. else{
  244. // Find out the difference between the source and dest unalign offsets
  245. // If the unaligned dest offset is less than the unaligned src offset,
  246. // we need to decrement pSrcScanLine so that we can dword-align the first
  247. // source bytes (the extra bytes added to the beginning of the dword
  248. // will end up getting masked off anyway).
  249. if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
  250. iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
  251. else
  252. iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
  253. iNumUnalignedDstBytes);
  254. // compute advance and error terms for stepping
  255. // vertically through the src bitmap
  256. if (iNumSrcRows < iNumDstRows) {
  257. iSrcScanAdvance = 0;
  258. iVertAdvanceError = iNumSrcRows;
  259. }
  260. else{
  261. iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
  262. iVertAdvanceError = iNumSrcRows % iNumDstRows;
  263. }
  264. // Do the trickier copy since the alignments don't match
  265. for (i = 0; i < iNumDstRows; i++) {
  266. // Set up the first pointers
  267. pSrcPixel = pSrcScanLine;
  268. pDstPixel = pDstScanLine;
  269. // First we need to copy the bytes to get to an aligned dword
  270. for(j=0; j<iNumUnalignedDstBytes; j++)
  271. *pDstPixel++ = *pSrcPixel++;
  272. // set up Dst pointer to the first 4-pixel chunk (dword)
  273. pBigDstPixel = (DWORD *) pDstPixel;
  274. pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
  275. // Set up the temporary dword vars
  276. dwSrc1 = *pBigSrcPixel++;
  277. switch(iNumUnalignByteDiff){
  278. case 1:
  279. for(j=0; j<iNumDwordsPerLine; j++){
  280. dwSrc2 = *pBigSrcPixel++;
  281. *pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
  282. dwSrc1 = dwSrc2;
  283. }
  284. break;
  285. case 2:
  286. for(j=0; j<iNumDwordsPerLine; j++){
  287. dwSrc2 = *pBigSrcPixel++;
  288. *pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
  289. dwSrc1 = dwSrc2;
  290. }
  291. break;
  292. case 3:
  293. for(j=0; j<iNumDwordsPerLine; j++){
  294. dwSrc2 = *pBigSrcPixel++;
  295. *pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
  296. dwSrc1 = dwSrc2;
  297. }
  298. break;
  299. }
  300. // Take care of the bytes left over
  301. pDstPixel = (BYTE *)pBigDstPixel;
  302. pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
  303. // First we need to copy the bytes to get to an aligned dword
  304. for(j=0; j<iNumBytesLeftDst; j++)
  305. *pDstPixel++ = *pSrcPixel++;
  306. // advance to next scanline
  307. pSrcScanLine += iSrcScanAdvance;
  308. pDstScanLine += iDstScanStride;
  309. // update and check vertical stepping error,
  310. // adjust src scanline pointer if necessary
  311. iVertError += iVertAdvanceError;
  312. if (iVertError >= iNumDstRows) {
  313. pSrcScanLine += iSrcScanStride;
  314. iVertError -= iNumDstRows;
  315. }
  316. }
  317. }
  318. }
  319. void Blt08to08_NoTrans_NoHcopy_SRCCOPY(BYTE* pSrcScanLine,
  320. int iSrcScanStride,
  321. int iNumSrcCols,
  322. int iNumSrcRows,
  323. BYTE* pDstScanLine,
  324. int iDstScanStride,
  325. int iNumDstCols,
  326. int iNumDstRows,
  327. int iHorizMirror)
  328. {
  329. BYTE *pSrcPixel,
  330. *pDstPixel;
  331. int iVertError = 0,
  332. iVertAdvanceError,
  333. iSrcScanAdvance,
  334. iHorizError,
  335. iHorizAdvanceError,
  336. iSrcPixelAdvance;
  337. // compute advance and error terms for stepping
  338. // vertically through the src bitmap
  339. if (iNumSrcRows < iNumDstRows) {
  340. iSrcScanAdvance = 0;
  341. iVertAdvanceError = iNumSrcRows;
  342. } else {
  343. iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
  344. iVertAdvanceError = iNumSrcRows % iNumDstRows;
  345. }
  346. // compute advance and error terms for stepping
  347. // horizontally through src bitmap
  348. if (iNumSrcCols < iNumDstCols) {
  349. iSrcPixelAdvance = 0;
  350. iHorizAdvanceError = iNumSrcCols;
  351. } else {
  352. iSrcPixelAdvance = iNumSrcCols / iNumDstCols;
  353. iHorizAdvanceError = iNumSrcCols % iNumDstCols;
  354. }
  355. for (int i = 0; i < iNumDstRows; i++) {
  356. // set pointers to the beginning of src and dst scanlines,
  357. // clear horizontal stepping error accumulator
  358. pSrcPixel = pSrcScanLine;
  359. pDstPixel = pDstScanLine;
  360. iHorizError = 0;
  361. for (int j = 0; j < iNumDstCols; j++) {
  362. // copy a pixel
  363. *pDstPixel = *pSrcPixel;
  364. // advance to next pixel
  365. pSrcPixel += iSrcPixelAdvance;
  366. pDstPixel += iHorizMirror;
  367. // update and check horizontal stepping error,
  368. // adjust src pixel pointer if necessary
  369. iHorizError += iHorizAdvanceError;
  370. if (iHorizError >= iNumDstCols) {
  371. pSrcPixel++;
  372. iHorizError -= iNumDstCols;
  373. }
  374. }
  375. // advance to next scanline
  376. pSrcScanLine += iSrcScanAdvance;
  377. pDstScanLine += iDstScanStride;
  378. // update and check vertical stepping error,
  379. // adjust src scanline pointer if necessary
  380. iVertError += iVertAdvanceError;
  381. if (iVertError >= iNumDstRows) {
  382. pSrcScanLine += iSrcScanStride;
  383. iVertError -= iNumDstRows;
  384. }
  385. }
  386. }
  387. void Blt08to08_Trans_Hcopy_SRCCOPY(BYTE* pSrcScanLine,
  388. int iSrcScanStride,
  389. int iNumSrcRows,
  390. BYTE* pDstScanLine,
  391. int iDstScanStride,
  392. int iNumDstCols,
  393. int iNumDstRows,
  394. BYTE bTransparentIndex)
  395. {
  396. BYTE *pSrcPixel,
  397. *pDstPixel;
  398. int iVertError = 0,
  399. iVertAdvanceError,
  400. iSrcScanAdvance;
  401. // compute advance and error terms for stepping
  402. // vertically through the src bitmap
  403. if (iNumSrcRows < iNumDstRows) {
  404. iSrcScanAdvance = 0;
  405. iVertAdvanceError = iNumSrcRows;
  406. } else {
  407. iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
  408. iVertAdvanceError = iNumSrcRows % iNumDstRows;
  409. }
  410. for (int i = 0; i < iNumDstRows; i++) {
  411. // set pointers to beginning of src and dest scanlines
  412. pSrcPixel = pSrcScanLine;
  413. pDstPixel = pDstScanLine;
  414. for (int j = 0; j < iNumDstCols; j++) {
  415. // only copy pixel if it's not transparent
  416. #if BLT0808_FAST_TRANSPARENCY
  417. *pDstPixel ^= (*pDstPixel ^ *pSrcPixel) *
  418. (BYTE) !(*pSrcPixel == bTransparentIndex);
  419. #else
  420. if (*pSrcPixel != bTransparentIndex)
  421. {
  422. *pDstPixel = *pSrcPixel;
  423. }
  424. #endif
  425. pSrcPixel++;
  426. pDstPixel++;
  427. }
  428. // advance to next scanline
  429. pSrcScanLine += iSrcScanAdvance;
  430. pDstScanLine += iDstScanStride;
  431. // update and check vertical stepping error,
  432. // adjust src scanline pointer if necessary
  433. iVertError += iVertAdvanceError;
  434. if (iVertError >= iNumDstRows) {
  435. pSrcScanLine += iSrcScanStride;
  436. iVertError -= iNumDstRows;
  437. }
  438. }
  439. }
  440. void Blt08to08_Trans_NoHcopy_SRCCOPY(BYTE* pSrcScanLine,
  441. int iSrcScanStride,
  442. int iNumSrcCols,
  443. int iNumSrcRows,
  444. BYTE* pDstScanLine,
  445. int iDstScanStride,
  446. int iNumDstCols,
  447. int iNumDstRows,
  448. int iHorizMirror,
  449. BYTE bTransparentIndex)
  450. {
  451. BYTE *pSrcPixel,
  452. *pDstPixel;
  453. int iVertError = 0,
  454. iVertAdvanceError,
  455. iSrcScanAdvance,
  456. iHorizError,
  457. iHorizAdvanceError,
  458. iSrcPixelAdvance;
  459. // compute advance and error terms for stepping
  460. // vertically through the src bitmap
  461. if (iNumSrcRows < iNumDstRows) {
  462. iSrcScanAdvance = 0;
  463. iVertAdvanceError = iNumSrcRows;
  464. } else {
  465. iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
  466. iVertAdvanceError = iNumSrcRows % iNumDstRows;
  467. }
  468. // compute advance and error terms for stepping
  469. // horizontally through src bitmap
  470. if (iNumSrcCols < iNumDstCols) {
  471. iSrcPixelAdvance = 0;
  472. iHorizAdvanceError = iNumSrcCols;
  473. } else {
  474. iSrcPixelAdvance = iNumSrcCols / iNumDstCols;
  475. iHorizAdvanceError = iNumSrcCols % iNumDstCols;
  476. }
  477. for (int i = 0; i < iNumDstRows; i++) {
  478. // set pointers to the beginning of src and dst scanlines,
  479. // clear horizontal stepping error accumulator
  480. pSrcPixel = pSrcScanLine;
  481. pDstPixel = pDstScanLine;
  482. iHorizError = 0;
  483. for (int j = 0; j < iNumDstCols; j++) {
  484. // only copy pixel if it's not transparent
  485. #if BLT0808_FAST_TRANSPARENCY
  486. *pDstPixel ^= (*pDstPixel ^ *pSrcPixel) *
  487. (BYTE) !(*pSrcPixel == bTransparentIndex);
  488. #else
  489. if (*pSrcPixel != bTransparentIndex) {
  490. *pDstPixel = *pSrcPixel;
  491. }
  492. #endif
  493. // advance to next pixel
  494. pSrcPixel += iSrcPixelAdvance;
  495. pDstPixel += iHorizMirror;
  496. // update and check horizontal stepping error,
  497. // adjust src pixel pointer if necessary
  498. iHorizError += iHorizAdvanceError;
  499. if (iHorizError >= iNumDstCols) {
  500. pSrcPixel++;
  501. iHorizError -= iNumDstCols;
  502. }
  503. }
  504. // advance to next scanline
  505. pSrcScanLine += iSrcScanAdvance;
  506. pDstScanLine += iDstScanStride;
  507. // update and check vertical stepping error,
  508. // adjust src scanline pointer if necessary
  509. iVertError += iVertAdvanceError;
  510. if (iVertError >= iNumDstRows) {
  511. pSrcScanLine += iSrcScanStride;
  512. iVertError -= iNumDstRows;
  513. }
  514. }
  515. }
  516. #ifndef DDRAW
  517. ///////////////////////////////////////////////////////////////////////
  518. //
  519. // Private BlitLib_Chunk32_BitBlt08to08 -
  520. // BitBlit from source bitmap to destination bitmap in 32 x 32
  521. // bit chunks
  522. //
  523. // Parameters:
  524. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  525. // pDibBitsDst Pointer to the bits for the Destination DIB
  526. // prcDst Pointer to the Destination rectangle
  527. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  528. // pDibBitsSrc Pointer to the bits for the Source DIB
  529. //
  530. // Return Value:
  531. // NO_ERROR or E_* value as specified in the .H file.
  532. //
  533. // Status: Incomplete
  534. //
  535. ///////////////////////////////////////////////////////////////////////
  536. #ifdef __cplusplus
  537. extern "C" {
  538. #endif
  539. SCODE BlitLib_Chunk32_BitBlt08to08(PDIBINFO pDibInfoDst,
  540. PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc,
  541. PDIBBITS pDibBitsSrc)
  542. {
  543. DWORD *pbDst,*pbSrc,*pend;
  544. int j;
  545. int iDstStride=DibWidthBytes(pDibInfoDst);
  546. // calc pbsrc and pbdst
  547. pbDst = (DWORD *) ((BYTE *) pDibBitsDst + (prcDst->top) * (iDstStride)
  548. + prcDst->left);
  549. pbSrc=(DWORD *)pDibBitsSrc;
  550. iDstStride-=32;
  551. // convert stride to dwords
  552. iDstStride/=4;
  553. // copy a scanline
  554. // counting down to 0 faster
  555. for (j=32;j>0 ;j-- )
  556. {
  557. pend=(DWORD *)pbSrc+8;
  558. for (; pbSrc < pend; pbSrc++ )
  559. {
  560. *pbDst++=*pbSrc;
  561. }
  562. pbDst+=iDstStride;
  563. }
  564. return(S_OK);
  565. }
  566. ///////////////////////////////////////////////////////////////////////
  567. //
  568. // Private BlitLib_Chunk32_BitBlt08to08_Trans -
  569. // BitBlit from source bitmap to destination bitmap in 32 x 32
  570. // bit chunks with optional transparency
  571. //
  572. // Parameters:
  573. // pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
  574. // pDibBitsDst Pointer to the bits for the Destination DIB
  575. // prcDst Pointer to the Destination rectangle
  576. // pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
  577. // pDibBitsSrc Pointer to the bits for the Source DIB
  578. // crTransparent Tranparent color value
  579. //
  580. // Return Value:
  581. // NO_ERROR or E_* value as specified in the .H file.
  582. //
  583. // Status: Incomplete
  584. //
  585. ///////////////////////////////////////////////////////////////////////
  586. SCODE BlitLib_Chunk32_BitBlt08to08_Trans(PDIBINFO pDibInfoDst,
  587. PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc,
  588. PDIBBITS pDibBitsSrc, COLORREF crTransparent)
  589. {
  590. BYTE * pbDst,*pend;
  591. int j;
  592. int iDstStride=DibWidthBytes(pDibInfoDst);
  593. // calc pbsrc and pbdst
  594. pbDst = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstStride)
  595. + prcDst->left;
  596. iDstStride-=32;
  597. // copy a scanline
  598. // counting down to 0 faster
  599. for (j=32;j>0 ;j-- )
  600. {
  601. pend=pDibBitsSrc+32;
  602. for (;pDibBitsSrc<pend;pDibBitsSrc++ )
  603. {
  604. if (*pDibBitsSrc != (BYTE)crTransparent)
  605. *pbDst=*pDibBitsSrc;
  606. pbDst++;
  607. }
  608. pbDst+=iDstStride;
  609. }
  610. return(S_OK);
  611. }
  612. #ifdef __cplusplus
  613. }
  614. #endif
  615. #endif
  616. ///////////////////////////////////////////////////////////////////////
  617. //
  618. // Private Blt08to08_LeftToRight_BottomToTop_SRCOPY -
  619. // BitBlit from source bitmap to destination bitmap (where these
  620. // bitmaps overlap) by walking both the source and destination
  621. // from left to right and bottom to top
  622. //
  623. // Parameters:
  624. // pSrcScanLine Pointer to the first Source scan line
  625. // iSrcScanStride The Source scan stride
  626. // pDstScanLine Pointer to the first Destination scan line
  627. // iDstScanStride The Destination scan stride
  628. // iNumDstCols Number of destination columns
  629. // iNumDstRows Number of destination rows
  630. //
  631. // Return Value:
  632. // NO_ERROR or E_* value as specified in the .H file.
  633. //
  634. ///////////////////////////////////////////////////////////////////////
  635. void Blt08to08_LeftToRight_BottomToTop_SRCCOPY(BYTE* pSrcScanLine,
  636. int iSrcScanStride,
  637. BYTE* pDstScanLine,
  638. int iDstScanStride,
  639. int iNumDstCols,
  640. int iNumDstRows)
  641. {
  642. DWORD *pBigSrcPixel,
  643. *pBigDstPixel,
  644. *pBigEndDstPixel;
  645. BYTE *pSrcPixel,
  646. *pDstPixel,
  647. *pAlignedSrcPixel,
  648. *pAlignedDstPixel;
  649. int iNumDwordsPerLine = iNumDstCols / 4,
  650. iNumBytesLeftDst = iNumDstCols % 4,
  651. iNumUnalignedSrcBytes,
  652. iNumUnalignedDstBytes,
  653. iNumUnalignByteDiff,
  654. i,j;
  655. DWORD dwSrc1, dwSrc2;
  656. // If the total number of bytes per scan is less than 4, we are
  657. // just going to do a regular byte-wise copy, so skip all this
  658. // alignment junk.....
  659. if(!iNumDwordsPerLine){
  660. iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
  661. }
  662. else{
  663. // Find out if the source and dest pointers are dword aligned
  664. pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
  665. iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
  666. pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
  667. iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
  668. // Now decrement the number of dwords per line and the
  669. // number of bytes left over as appropriate
  670. if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
  671. iNumBytesLeftDst -= iNumUnalignedDstBytes;
  672. else{
  673. iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
  674. if(iNumBytesLeftDst != sizeof(DWORD))
  675. iNumDwordsPerLine--;
  676. }
  677. }
  678. if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
  679. // Do the fast dword copy since the alignments match
  680. for (i = 0; i < iNumDstRows; i++) {
  681. // Set up the first pointers
  682. pSrcPixel = pSrcScanLine;
  683. pDstPixel = pDstScanLine;
  684. // First we need to copy the bytes to get to an aligned dword
  685. for(j=0; j<iNumUnalignedSrcBytes; j++)
  686. *pDstPixel++ = *pSrcPixel++;
  687. // set up pointers to the first 4-pixel chunks
  688. // on src and dst scanlines, and last chunk on
  689. // dst scanline
  690. pBigSrcPixel = (DWORD*) pSrcPixel;
  691. pBigDstPixel = (DWORD*) pDstPixel;
  692. pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
  693. // copy scanline one 4-pixel chunk at a time
  694. while (pBigDstPixel != pBigEndDstPixel) {
  695. *pBigDstPixel++ = *pBigSrcPixel++;
  696. }
  697. // take care of remaining pixels on scanline
  698. if (iNumBytesLeftDst) {
  699. pSrcPixel = (BYTE*) pBigSrcPixel;
  700. pDstPixel = (BYTE*) pBigDstPixel;
  701. for(j=0; j<iNumBytesLeftDst; j++){
  702. *pDstPixel++ = *pSrcPixel++;
  703. }
  704. }
  705. // advance to next scanline
  706. pSrcScanLine -= iSrcScanStride;
  707. pDstScanLine -= iDstScanStride;
  708. }
  709. }
  710. else{
  711. // Find out the difference between the source and dest unalign offsets
  712. // If the unaligned dest offset is less than the unaligned src offset,
  713. // we need to decrement pSrcScanLine so that we can dword-align the first
  714. // source bytes (the extra bytes added to the beginning of the dword
  715. // will end up getting masked off anyway).
  716. if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
  717. iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
  718. else
  719. iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
  720. iNumUnalignedDstBytes);
  721. // Do the trickier copy since the alignments don't match
  722. for (i = 0; i < iNumDstRows; i++) {
  723. // Set up the first pointers
  724. pSrcPixel = pSrcScanLine;
  725. pDstPixel = pDstScanLine;
  726. // First we need to copy the bytes to get to an aligned dword
  727. for(j=0; j<iNumUnalignedDstBytes; j++)
  728. *pDstPixel++ = *pSrcPixel++;
  729. // set up Dst pointer to the first 4-pixel chunk (dword)
  730. pBigDstPixel = (DWORD *) pDstPixel;
  731. pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
  732. // Set up the temporary dword vars
  733. dwSrc1 = *pBigSrcPixel++;
  734. switch(iNumUnalignByteDiff){
  735. case 1:
  736. for(j=0; j<iNumDwordsPerLine; j++){
  737. dwSrc2 = *pBigSrcPixel++;
  738. *pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
  739. dwSrc1 = dwSrc2;
  740. }
  741. break;
  742. case 2:
  743. for(j=0; j<iNumDwordsPerLine; j++){
  744. dwSrc2 = *pBigSrcPixel++;
  745. *pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
  746. dwSrc1 = dwSrc2;
  747. }
  748. break;
  749. case 3:
  750. for(j=0; j<iNumDwordsPerLine; j++){
  751. dwSrc2 = *pBigSrcPixel++;
  752. *pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
  753. dwSrc1 = dwSrc2;
  754. }
  755. break;
  756. }
  757. // Take care of the bytes left over
  758. pDstPixel = (BYTE *)pBigDstPixel;
  759. pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
  760. // First we need to copy the bytes to get to an aligned dword
  761. for(j=0; j<iNumBytesLeftDst; j++)
  762. *pDstPixel++ = *pSrcPixel++;
  763. // advance to next scanline
  764. pSrcScanLine -= iSrcScanStride;
  765. pDstScanLine -= iDstScanStride;
  766. }
  767. }
  768. }
  769. ///////////////////////////////////////////////////////////////////////
  770. //
  771. // Private Blt08to08_RightToLeft_TopToBottom_SRCOPY -
  772. // BitBlit from source bitmap to destination bitmap (where these
  773. // bitmaps overlap) by walking both the source and destination
  774. // from right to left and top to bottom
  775. //
  776. // Parameters:
  777. // pSrcScanLine Pointer to the first Source scan line
  778. // iSrcScanStride The Source scan stride
  779. // pDstScanLine Pointer to the first Destination scan line
  780. // iDstScanStride The Destination scan stride
  781. // iNumDstCols Number of destination columns
  782. // iNumDstRows Number of destination rows
  783. //
  784. // Return Value:
  785. // NO_ERROR or E_* value as specified in the .H file.
  786. //
  787. ///////////////////////////////////////////////////////////////////////
  788. void Blt08to08_RightToLeft_TopToBottom_SRCCOPY(BYTE* pSrcScanLine,
  789. int iSrcScanStride,
  790. BYTE* pDstScanLine,
  791. int iDstScanStride,
  792. int iNumDstCols,
  793. int iNumDstRows)
  794. {
  795. DWORD *pBigSrcPixel,
  796. *pBigDstPixel,
  797. *pBigEndDstPixel;
  798. BYTE *pSrcPixel,
  799. *pDstPixel,
  800. *pAlignedSrcPixel,
  801. *pAlignedDstPixel;
  802. int iNumDwordsPerLine = iNumDstCols / 4,
  803. iNumBytesLeftDst = iNumDstCols % 4,
  804. iNumUnalignedSrcBytes,
  805. iNumUnalignedDstBytes,
  806. iNumUnalignByteDiff,
  807. i,j;
  808. DWORD dwSrc1, dwSrc2;
  809. // If the total number of bytes per scan is less than 4, we are
  810. // just going to do a regular byte-wise copy, so skip all this
  811. // alignment junk.....
  812. if(!iNumDwordsPerLine){
  813. iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
  814. }
  815. else{
  816. // Find out if the source and dest pointers are dword aligned
  817. pAlignedSrcPixel = (BYTE *)(((ULONG_PTR)pSrcScanLine) & (~3));
  818. iNumUnalignedSrcBytes = (int)(pSrcScanLine - pAlignedSrcPixel) + 1;
  819. pAlignedDstPixel = (BYTE *)(((ULONG_PTR)pDstScanLine) & (~3));
  820. iNumUnalignedDstBytes = (int)(pDstScanLine - pAlignedDstPixel) + 1;
  821. // Now decrement the number of dwords per line and the
  822. // number of bytes left over as appropriate
  823. if(iNumUnalignedDstBytes == sizeof(DWORD))
  824. iNumUnalignedDstBytes = 0;
  825. if(iNumUnalignedSrcBytes == sizeof(DWORD))
  826. iNumUnalignedSrcBytes = 0;
  827. else if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
  828. iNumBytesLeftDst -= iNumUnalignedDstBytes;
  829. else{
  830. iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
  831. iNumDwordsPerLine--;
  832. }
  833. }
  834. if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
  835. // Do the fast dword copy since the alignments match
  836. for (int i = 0; i < iNumDstRows; i++) {
  837. // First set up the pointer to take care of unaligned DWORD bytes
  838. pSrcPixel = pSrcScanLine;
  839. pDstPixel = pDstScanLine;
  840. // First we need to copy the bytes to get to an aligned dword
  841. for(j=0; j<iNumUnalignedSrcBytes; j++)
  842. *pDstPixel-- = *pSrcPixel--;
  843. // set up pointers to the first 4-pixel chunks
  844. // on src and dst scanlines, and last chunk on
  845. // dst scanline
  846. pBigSrcPixel = (DWORD*) (pSrcPixel - 3);
  847. pBigDstPixel = (DWORD*) (pDstPixel - 3);
  848. pBigEndDstPixel = pBigDstPixel - iNumDwordsPerLine;
  849. // copy scanline one 4-pixel chunk at a time
  850. while (pBigDstPixel != pBigEndDstPixel) {
  851. *pBigDstPixel-- = *pBigSrcPixel--;
  852. }
  853. if(iNumBytesLeftDst)
  854. pSrcPixel = ((BYTE *)pBigSrcPixel) + 3;
  855. pDstPixel = ((BYTE *)pBigDstPixel) + 3;
  856. for (j = 0; j < iNumBytesLeftDst; j++)
  857. *pDstPixel-- = *pSrcPixel--;
  858. // advance to next scanline
  859. pSrcScanLine += iSrcScanStride;
  860. pDstScanLine += iDstScanStride;
  861. }
  862. }
  863. else{
  864. // Find out the difference between the source and dest unalign offsets
  865. // If the unaligned dest offset is less than the unaligned src offset,
  866. // we need to decrement pSrcScanLine so that we can dword-align the first
  867. // source bytes (the extra bytes added to the beginning of the dword
  868. // will end up getting masked off anyway).
  869. if(iNumUnalignedDstBytes < iNumUnalignedSrcBytes)
  870. iNumUnalignByteDiff = iNumUnalignedSrcBytes - iNumUnalignedDstBytes;
  871. else
  872. iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedDstBytes -
  873. iNumUnalignedSrcBytes);
  874. // Do the trickier copy since the alignments don't match
  875. for (i = 0; i < iNumDstRows; i++) {
  876. // Set up the first pointers
  877. pSrcPixel = pSrcScanLine;
  878. pDstPixel = pDstScanLine;
  879. // First we need to copy the bytes to get to an aligned dword
  880. for(j=0; j<iNumUnalignedDstBytes; j++)
  881. *pDstPixel-- = *pSrcPixel--;
  882. // set up Dst pointer to the first 4-pixel chunk (dword)
  883. pBigDstPixel = (DWORD *) (pDstPixel - 3);
  884. pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
  885. // Set up the temporary dword vars
  886. dwSrc2 = *pBigSrcPixel--;
  887. switch(iNumUnalignByteDiff){
  888. case 1:
  889. for(j=0; j<iNumDwordsPerLine; j++){
  890. dwSrc1 = *pBigSrcPixel--;
  891. *pBigDstPixel-- = (dwSrc1 >> 8) | (dwSrc2 << 24);
  892. dwSrc2 = dwSrc1;
  893. }
  894. break;
  895. case 2:
  896. for(j=0; j<iNumDwordsPerLine; j++){
  897. dwSrc1 = *pBigSrcPixel--;
  898. *pBigDstPixel-- = (dwSrc1 >> 16) | (dwSrc2 << 16);
  899. dwSrc2 = dwSrc1;
  900. }
  901. break;
  902. case 3:
  903. for(j=0; j<iNumDwordsPerLine; j++){
  904. dwSrc1 = *pBigSrcPixel--;
  905. *pBigDstPixel-- = (dwSrc1 >> 24) | (dwSrc2 << 8);
  906. dwSrc2 = dwSrc1;
  907. }
  908. break;
  909. }
  910. // Take care of the bytes left over
  911. pDstPixel = ((BYTE *)pBigDstPixel + 3);
  912. pSrcPixel = (((BYTE *)(pBigSrcPixel)) + 4 +
  913. (iNumUnalignByteDiff - 1));
  914. // First we need to copy the bytes to get to an aligned dword
  915. for(j=0; j<iNumBytesLeftDst; j++)
  916. *pDstPixel-- = *pSrcPixel--;
  917. // advance to next scanline
  918. pSrcScanLine += iSrcScanStride;
  919. pDstScanLine += iDstScanStride;
  920. }
  921. }
  922. }
  923. ///////////////////////////////////////////////////////////////////////
  924. //
  925. // Private Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY -
  926. // BitBlit using a transparent color index from source bitmap to
  927. // destination bitmap (where these bitmaps overlap) by walking
  928. // both the source and destination from left to right and bottom
  929. // to top
  930. //
  931. // Parameters:
  932. // pSrcScanLine Pointer to the first Source scan line
  933. // iSrcScanStride The Source scan stride
  934. // pDstScanLine Pointer to the first Destination scan line
  935. // iDstScanStride The Destination scan stride
  936. // iNumDstCols Number of destination columns
  937. // iNumDstRows Number of destination rows
  938. // bTransparentIndex Palette Index of the transparent color
  939. //
  940. // Return Value:
  941. // NO_ERROR or E_* value as specified in the .H file.
  942. //
  943. ///////////////////////////////////////////////////////////////////////
  944. void Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY(BYTE* pSrcScanLine,
  945. int iSrcScanStride,
  946. BYTE* pDstScanLine,
  947. int iDstScanStride,
  948. int iNumDstCols,
  949. int iNumDstRows,
  950. BYTE bTransparentIndex)
  951. {
  952. BYTE *pSrcPixel,
  953. *pDstPixel;
  954. for (int i = 0; i < iNumDstRows; i++) {
  955. // set pointers to beginning of src and dest scanlines
  956. pSrcPixel = pSrcScanLine;
  957. pDstPixel = pDstScanLine;
  958. for (int j = 0; j < iNumDstCols; j++) {
  959. // only copy pixel if it's not transparent
  960. if (*pSrcPixel != bTransparentIndex) {
  961. *pDstPixel = *pSrcPixel;
  962. }
  963. pSrcPixel++;
  964. pDstPixel++;
  965. }
  966. // advance to next scanline
  967. pSrcScanLine -= iSrcScanStride;
  968. pDstScanLine -= iDstScanStride;
  969. }
  970. }
  971. ///////////////////////////////////////////////////////////////////////
  972. //
  973. // Private Blt08to08_RightToLeft_TopToBottom_Trans_SRCOPY -
  974. // BitBlit using a transparent color index from source bitmap to
  975. // destination bitmap (where these bitmaps overlap) by walking
  976. // both the source and destination from right to left and top
  977. // to bottom
  978. //
  979. // Parameters:
  980. // pSrcScanLine Pointer to the first Source scan line
  981. // iSrcScanStride The Source scan stride
  982. // pDstScanLine Pointer to the first Destination scan line
  983. // iDstScanStride The Destination scan stride
  984. // iNumDstCols Number of destination columns
  985. // iNumDstRows Number of destination rows
  986. // bTransparentIndex Palette Index of the transparent color
  987. //
  988. // Return Value:
  989. // NO_ERROR or E_* value as specified in the .H file.
  990. //
  991. ///////////////////////////////////////////////////////////////////////
  992. void Blt08to08_RightToLeft_TopToBottom_Trans_SRCCOPY(BYTE* pSrcScanLine,
  993. int iSrcScanStride,
  994. BYTE* pDstScanLine,
  995. int iDstScanStride,
  996. int iNumDstCols,
  997. int iNumDstRows,
  998. BYTE bTransparentIndex)
  999. {
  1000. BYTE *pSrcPixel,
  1001. *pDstPixel;
  1002. for (int i = 0; i < iNumDstRows; i++) {
  1003. // set pointers to beginning of src and dest scanlines
  1004. pSrcPixel = pSrcScanLine;
  1005. pDstPixel = pDstScanLine;
  1006. for (int j = 0; j < iNumDstCols; j++) {
  1007. // only copy pixel if it's not transparent
  1008. if (*pSrcPixel != bTransparentIndex) {
  1009. *pDstPixel = *pSrcPixel;
  1010. }
  1011. pSrcPixel--;
  1012. pDstPixel--;
  1013. }
  1014. // advance to next scanline
  1015. pSrcScanLine += iSrcScanStride;
  1016. pDstScanLine += iDstScanStride;
  1017. }
  1018. }