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.

1307 lines
36 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: srcblt24.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt to a 24 bit/pel
  5. * DIB surface.
  6. *
  7. * Created: 07-Feb-1991 19:27:49
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * Copyright (c) 1990-1999 Microsoft Corporation
  11. *
  12. \**************************************************************************/
  13. #include "precomp.hxx"
  14. // Turn off validations
  15. #if 1
  16. // On free builds, don't call any verification code:
  17. #define VERIFYS16D24(psb)
  18. #define VERIFYS32D24(psb)
  19. #else
  20. // On checked builds, verify the RGB conversions:
  21. VOID VERIFYS16D24(PBLTINFO psb)
  22. {
  23. // We assume we are doing left to right top to bottom blting
  24. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D24 - direction not left to right");
  25. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D24 - direction not up to down");
  26. // These are our holding variables
  27. ULONG ulDst;
  28. PUSHORT pusSrcTemp;
  29. PBYTE pjDstTemp;
  30. ULONG cxTemp;
  31. PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (2 * psb->xSrcStart));
  32. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  33. ULONG cx = psb->cx;
  34. ULONG cy = psb->cy;
  35. XLATE *pxlo = psb->pxlo;
  36. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  37. while(1)
  38. {
  39. pusSrcTemp = pusSrc;
  40. pjDstTemp = pjDst;
  41. cxTemp = cx;
  42. while(cxTemp--)
  43. {
  44. ulDst = pxlo->ulTranslate((ULONG) *(pusSrcTemp++));
  45. if (*(pjDstTemp++) != (BYTE) ulDst)
  46. RIP("RGB mis-match");
  47. if (*(pjDstTemp++) != (BYTE) (ulDst >> 8))
  48. RIP("RGB mis-match");
  49. if (*(pjDstTemp++) != (BYTE) (ulDst >> 16))
  50. RIP("RGB mis-match");
  51. }
  52. if (--cy)
  53. {
  54. pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
  55. pjDst += psb->lDeltaDst;
  56. }
  57. else
  58. break;
  59. }
  60. }
  61. VOID VERIFYS32D24(PBLTINFO psb)
  62. {
  63. // We assume we are doing left to right top to bottom blting
  64. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D24 - direction not left to right");
  65. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D24 - direction not up to down");
  66. // These are our holding variables
  67. ULONG ulDst;
  68. PULONG pulSrcTemp;
  69. PBYTE pjDstTemp;
  70. ULONG cxTemp;
  71. PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
  72. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  73. ULONG cx = psb->cx;
  74. ULONG cy = psb->cy;
  75. XLATE *pxlo = psb->pxlo;
  76. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  77. while(1)
  78. {
  79. pulSrcTemp = pulSrc;
  80. pjDstTemp = pjDst;
  81. cxTemp = cx;
  82. if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
  83. {
  84. while(cxTemp--)
  85. {
  86. ulDst = *(pulSrcTemp++);
  87. if (*(pjDstTemp++) != (BYTE) ulDst)
  88. RIP("RGB mis-match");
  89. if (*(pjDstTemp++) != (BYTE) (ulDst >> 8))
  90. RIP("RGB mis-match");
  91. if (*(pjDstTemp++) != (BYTE) (ulDst >> 16))
  92. RIP("RGB mis-match");
  93. }
  94. }
  95. else
  96. {
  97. while(cxTemp--)
  98. {
  99. ulDst = pxlo->ulTranslate(*(pulSrcTemp++));
  100. if (*(pjDstTemp++) != (BYTE) ulDst)
  101. RIP("RGB mis-match");
  102. if (*(pjDstTemp++) != (BYTE) (ulDst >> 8))
  103. RIP("RGB mis-match");
  104. if (*(pjDstTemp++) != (BYTE) (ulDst >> 16))
  105. RIP("RGB mis-match");
  106. }
  107. }
  108. if (--cy)
  109. {
  110. pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
  111. pjDst += psb->lDeltaDst;
  112. }
  113. else
  114. break;
  115. }
  116. }
  117. #endif
  118. /*******************Public*Routine*****************\
  119. * vSrcCopyS1D24
  120. *
  121. * There are three main loops in this function.
  122. *
  123. * The first loop deals with the full byte part mapping
  124. * the Dst while fetching/shifting the matching 8 bits
  125. * from the Src.
  126. *
  127. * The second loop deals with the left starting
  128. * pixels.
  129. *
  130. * The third loop deals with the ending pixels.
  131. *
  132. * For the full bytes, we walk thru Src one byte at a time
  133. * and expand to Dst.
  134. *
  135. * We expand the starting/ending pixels one bit
  136. * at a time.
  137. *
  138. * History:
  139. * 17-Oct-1994 -by- Lingyun Wang [lingyunw]
  140. * Wrote it.
  141. \**************************************************/
  142. VOID vSrcCopyS1D24(PBLTINFO psb)
  143. {
  144. // We assume we are doing left to right top to bottom blting
  145. ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D24 - direction not left to right");
  146. ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D24 - direction not up to down");
  147. BYTE jSrc; // holds a source byte
  148. INT iDst; // Position in the first 8 Dst units
  149. INT iSrc; // bit position in the first Src byte
  150. PBYTE pjDst;
  151. PBYTE pjSrc; // pointer to the Dst bytes
  152. LONG xSrcEnd = psb->xSrcEnd;
  153. LONG cy; // number of rows
  154. LONG cx; // number of pixels
  155. BYTE jAlignL; // alignment bits to the left
  156. BYTE jAlignR; // alignment bits to the right
  157. LONG cFullBytes; //number of full 8 bytes dealed with
  158. BOOL bNextByte;
  159. LONG xDstEnd = psb->xDstStart+psb->cx;
  160. LONG lDeltaDst;
  161. LONG lDeltaSrc;
  162. ULONG ulB = (ULONG)(psb->pxlo->pulXlate[0]);
  163. ULONG ulF = (ULONG)(psb->pxlo->pulXlate[1]);
  164. UCHAR aucTable[8];
  165. INT count;
  166. PBYTE pjTable;
  167. BOOL bNextSrc=TRUE;
  168. ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
  169. //DbgPrint ("vsrccopys1d24\n");
  170. // Generate ulTable. 2 entries.
  171. ULONG ulValB = ulB;
  172. ULONG ulValF = ulF;
  173. *(PULONG) aucTable = ulValB;
  174. *(PULONG) (aucTable+4) = ulValF;
  175. //Get Src and Dst start positions
  176. iSrc = psb->xSrcStart & 0x0007;
  177. iDst = psb->xDstStart & 0x0007;
  178. if (iSrc < iDst)
  179. jAlignL = 8 - (iDst - iSrc);
  180. // If Dst starting point is ahead of Src
  181. else
  182. jAlignL = iSrc - iDst;
  183. jAlignR = 8 - jAlignL;
  184. cx=psb->cx;
  185. lDeltaDst = psb->lDeltaDst;
  186. lDeltaSrc = psb->lDeltaSrc;
  187. // if there is a next 8 dwords
  188. bNextByte = !((xDstEnd>>3) ==
  189. (psb->xDstStart>>3));
  190. // if Src and Dst are aligned, use a separete loop
  191. // to obtain better performance;
  192. // If not, we shift the Src bytes to match with
  193. // the Dst - 1 bit expand to 3 bytes
  194. if (bNextByte)
  195. {
  196. long iStrideSrc;
  197. long iStrideDst;
  198. PBYTE pjSrcEnd;
  199. // Get first Dst full 8 dwords
  200. pjDst = psb->pjDst + 3*((psb->xDstStart+7)&~0x07);
  201. // Get the Src byte that matches the first Dst
  202. // full 8 bytes
  203. pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
  204. //Get the number of full bytes to expand
  205. cFullBytes = (xDstEnd>>3)-((psb->xDstStart+7)>>3);
  206. //the increment to the full byte on the next scan line
  207. iStrideDst = lDeltaDst - cFullBytes*8*3;
  208. iStrideSrc = lDeltaSrc - cFullBytes;
  209. // deal with our special case
  210. cy = psb->cy;
  211. if (!jAlignL)
  212. {
  213. while (cy--)
  214. {
  215. pjSrcEnd = pjSrc + cFullBytes;
  216. while (pjSrc != pjSrcEnd)
  217. {
  218. jSrc = *pjSrc++;
  219. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  220. *(pjDst + 0) = *pjTable;
  221. *(pjDst + 1) = *(pjTable+1);
  222. *(pjDst + 2) = *(pjTable+2);
  223. pjTable = aucTable + ((jSrc & 0x40) >> (6-2));
  224. *(pjDst + 3) = *pjTable;
  225. *(pjDst + 4) = *(pjTable+1);
  226. *(pjDst + 5) = *(pjTable+2);
  227. pjTable = aucTable + ((jSrc & 0x20) >> (5-2));
  228. *(pjDst + 6) = *pjTable;
  229. *(pjDst + 7) = *(pjTable+1);
  230. *(pjDst + 8) = *(pjTable+2);
  231. pjTable = aucTable + ((jSrc & 0x10) >> (4-2));
  232. *(pjDst + 9) = *pjTable;
  233. *(pjDst + 10) = *(pjTable+1);
  234. *(pjDst + 11) = *(pjTable+2);
  235. pjTable = aucTable + ((jSrc & 0x08) >> (3-2));
  236. *(pjDst + 12) = *pjTable;
  237. *(pjDst + 13) = *(pjTable+1);
  238. *(pjDst + 14) = *(pjTable+2);
  239. pjTable = aucTable + (jSrc & 0x04);
  240. *(pjDst + 15) = *pjTable;
  241. *(pjDst + 16) = *(pjTable+1);
  242. *(pjDst + 17) = *(pjTable+2);
  243. pjTable = aucTable + ((jSrc & 0x02) << 1);
  244. *(pjDst + 18) = *pjTable;
  245. *(pjDst + 19) = *(pjTable+1);
  246. *(pjDst + 20) = *(pjTable+2);
  247. pjTable = aucTable + ((jSrc & 0x01) << 2);
  248. *(pjDst + 21) = *pjTable;
  249. *(pjDst + 22) = *(pjTable+1);
  250. *(pjDst + 23) = *(pjTable+2);
  251. pjDst +=3*8;
  252. }
  253. pjDst += iStrideDst;
  254. pjSrc += iStrideSrc;
  255. }
  256. } //end of if (!jAlignL)
  257. else // if not aligned
  258. // Here comes our general case for the main full
  259. // bytes part
  260. {
  261. BYTE jRem; //remainder
  262. while (cy--)
  263. {
  264. jRem = *pjSrc << jAlignL;
  265. pjSrcEnd = pjSrc + cFullBytes;
  266. while (pjSrc != pjSrcEnd)
  267. {
  268. jSrc = ((*(++pjSrc))>>jAlignR) | jRem;
  269. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  270. *(pjDst + 0) = *pjTable;
  271. *(pjDst + 1) = *(pjTable+1);
  272. *(pjDst + 2) = *(pjTable+2);
  273. pjTable = aucTable + ((jSrc & 0x40) >> (6-2));
  274. *(pjDst + 3) = *pjTable;
  275. *(pjDst + 4) = *(pjTable+1);
  276. *(pjDst + 5) = *(pjTable+2);
  277. pjTable = aucTable + ((jSrc & 0x20) >> (5-2));
  278. *(pjDst + 6) = *pjTable;
  279. *(pjDst + 7) = *(pjTable+1);
  280. *(pjDst + 8) = *(pjTable+2);
  281. pjTable = aucTable + ((jSrc & 0x10) >> (4-2));
  282. *(pjDst + 9) = *pjTable;
  283. *(pjDst + 10) = *(pjTable+1);
  284. *(pjDst + 11) = *(pjTable+2);
  285. pjTable = aucTable + ((jSrc & 0x08) >> (3-2));
  286. *(pjDst + 12) = *pjTable;
  287. *(pjDst + 13) = *(pjTable+1);
  288. *(pjDst + 14) = *(pjTable+2);
  289. pjTable = aucTable + (jSrc & 0x04);
  290. *(pjDst + 15) = *pjTable;
  291. *(pjDst + 16) = *(pjTable+1);
  292. *(pjDst + 17) = *(pjTable+2);
  293. pjTable = aucTable + ((jSrc & 0x02) << 1);
  294. *(pjDst + 18) = *pjTable;
  295. *(pjDst + 19) = *(pjTable+1);
  296. *(pjDst + 20) = *(pjTable+2);
  297. pjTable = aucTable + ((jSrc & 0x01) << 2);
  298. *(pjDst + 21) = *pjTable;
  299. *(pjDst + 22) = *(pjTable+1);
  300. *(pjDst + 23) = *(pjTable+2);
  301. pjDst +=3*8;
  302. //next remainder
  303. jRem = *pjSrc << jAlignL;
  304. }
  305. // go to the beginging full byte of
  306. // next scan line
  307. pjDst += iStrideDst;
  308. pjSrc += iStrideSrc;
  309. }
  310. } //else
  311. } //if
  312. // End of our dealing with the full bytes
  313. // Begin dealing with the left strip of the
  314. // starting pixels
  315. if (!bNextByte)
  316. {
  317. count = cx;
  318. bNextSrc = ((iSrc+cx) > 8);
  319. }
  320. else
  321. count = 8-iDst;
  322. if (iDst | !bNextByte)
  323. {
  324. PBYTE pjDstTemp;
  325. PBYTE pjDstEnd;
  326. pjDst = psb->pjDst + 3*psb->xDstStart;
  327. pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
  328. cy = psb->cy;
  329. if (iSrc > iDst)
  330. {
  331. if (bNextSrc)
  332. {
  333. while (cy--)
  334. {
  335. jSrc = *pjSrc << jAlignL;
  336. jSrc |= *(pjSrc+1) >> jAlignR;
  337. jSrc <<= iDst;
  338. pjDstTemp = pjDst;
  339. pjDstEnd = pjDst + 3*count;
  340. while (pjDstTemp != pjDstEnd)
  341. {
  342. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  343. *(pjDstTemp + 0) = *pjTable;
  344. *(pjDstTemp + 1) = *(pjTable+1);
  345. *(pjDstTemp + 2) = *(pjTable+2);
  346. jSrc <<= 1;
  347. pjDstTemp += 3;
  348. }
  349. pjDst += lDeltaDst;
  350. pjSrc += lDeltaSrc;
  351. }
  352. }
  353. else
  354. {
  355. while (cy--)
  356. {
  357. jSrc = *pjSrc << jAlignL;
  358. jSrc <<= iDst;
  359. pjDstTemp = pjDst;
  360. pjDstEnd = pjDst + 3*count;
  361. while (pjDstTemp != pjDstEnd)
  362. {
  363. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  364. *(pjDstTemp + 0) = *pjTable;
  365. *(pjDstTemp + 1) = *(pjTable+1);
  366. *(pjDstTemp + 2) = *(pjTable+2);
  367. jSrc <<= 1;
  368. pjDstTemp += 3;
  369. }
  370. pjDst += lDeltaDst;
  371. pjSrc += lDeltaSrc;
  372. }
  373. }
  374. }
  375. else //if (iSrc <= iDst)
  376. {
  377. while (cy--)
  378. {
  379. jSrc = *pjSrc << iSrc;
  380. pjDstTemp = pjDst;
  381. pjDstEnd = pjDst + 3*count;
  382. while (pjDstTemp != pjDstEnd)
  383. {
  384. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  385. *(pjDstTemp + 0) = *pjTable;
  386. *(pjDstTemp + 1) = *(pjTable+1);
  387. *(pjDstTemp + 2) = *(pjTable+2);
  388. jSrc <<= 1;
  389. pjDstTemp += 3;
  390. }
  391. pjDst += lDeltaDst;
  392. pjSrc += lDeltaSrc;
  393. }
  394. }
  395. } //if
  396. // Begin dealing with the right edge
  397. // of partial 8 bytes
  398. // first check if there is any partial
  399. // byte left
  400. // and has next 8 bytes
  401. if ((xDstEnd & 0x0007)
  402. && bNextByte)
  403. {
  404. PBYTE pjDstTemp;
  405. PBYTE pjDstEnd;
  406. // Get the last partial bytes on the
  407. // scan line
  408. pjDst = psb->pjDst+ 3*(xDstEnd&~0x07);
  409. // Get the Src byte that matches the
  410. // right partial Dst 8 bytes
  411. pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
  412. // Get the ending position in the last
  413. // Src and Dst bytes
  414. iSrc = (psb->xSrcEnd-1) & 0x0007;
  415. iDst = (xDstEnd-1) & 0x0007;
  416. count = iDst+1;
  417. cy = psb->cy;
  418. if (iSrc >= iDst)
  419. {
  420. while (cy--)
  421. {
  422. jSrc = *pjSrc << jAlignL;
  423. pjDstTemp = pjDst;
  424. pjDstEnd = pjDst + 3*count;
  425. while (pjDstTemp != pjDstEnd)
  426. {
  427. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  428. *(pjDstTemp + 0) = *pjTable;
  429. *(pjDstTemp + 1) = *(pjTable+1);
  430. *(pjDstTemp + 2) = *(pjTable+2);
  431. jSrc <<= 1;
  432. pjDstTemp += 3;
  433. }
  434. pjDst += lDeltaDst;
  435. pjSrc += lDeltaSrc;
  436. }
  437. }
  438. else //if (iSrc < iDst)
  439. {
  440. while (cy--)
  441. {
  442. jSrc = *(pjSrc-1) << jAlignL;
  443. jSrc |= *pjSrc >> jAlignR;
  444. pjDstTemp = pjDst;
  445. pjDstEnd = pjDst + 3*count;
  446. while (pjDstTemp != pjDstEnd)
  447. {
  448. pjTable = aucTable + ((jSrc & 0x80) >> (7-2));
  449. *(pjDstTemp + 0) = *pjTable;
  450. *(pjDstTemp + 1) = *(pjTable+1);
  451. *(pjDstTemp + 2) = *(pjTable+2);
  452. jSrc <<= 1;
  453. pjDstTemp += 3;
  454. }
  455. pjDst += lDeltaDst;
  456. pjSrc += lDeltaSrc;
  457. }
  458. }
  459. } //if
  460. }
  461. /******************************Public*Routine******************************\
  462. * vSrcCopyS4D24
  463. *
  464. *
  465. * History:
  466. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  467. * Wrote it.
  468. \**************************************************************************/
  469. VOID vSrcCopyS4D24(PBLTINFO psb)
  470. {
  471. // We assume we are doing left to right top to bottom blting.
  472. // If it was on the same surface we would be doing the identity case.
  473. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D24 - direction not left to right");
  474. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D24 - direction not up to down");
  475. // These are our holding variables
  476. #if MESSAGE_BLT
  477. DbgPrint("Now entering vSrcCopyS8D24\n");
  478. #endif
  479. PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart >> 1);
  480. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  481. ULONG cx = psb->cx;
  482. ULONG cy = psb->cy;
  483. PULONG pulXlate = psb->pxlo->pulXlate;
  484. PBYTE pjDstTemp;
  485. PBYTE pjSrcTemp;
  486. ULONG cStartPixels;
  487. ULONG cMiddlePixels;
  488. ULONG cEndPixels;
  489. ULONG i,j;
  490. ULONG ul;
  491. ULONG ul0, ul1,ul2,ul3;
  492. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  493. // 'cStartPixels' is the minimum number of 3-byte pixels we'll have to
  494. // write before we have dword alignment on the destination:
  495. cStartPixels = (ULONG)((ULONG_PTR) pjDst) & 3;
  496. if (cStartPixels > cx)
  497. {
  498. cStartPixels = cx;
  499. }
  500. cx -= cStartPixels;
  501. cMiddlePixels = cx >> 2;
  502. cEndPixels = cx & 3;
  503. while(1)
  504. {
  505. // Write pixels a byte at a time until we're 'dword' aligned on
  506. // the destination:
  507. j = psb->xSrcStart;
  508. pjDstTemp = pjDst;
  509. pjSrcTemp = pjSrc;
  510. for (i = cStartPixels; i != 0; i--)
  511. {
  512. if (j & 0x00000001)
  513. {
  514. ul = pulXlate[*pjSrcTemp & 0x0F];
  515. pjSrcTemp++;
  516. }
  517. else
  518. {
  519. ul = pulXlate[(((ULONG) (*pjSrcTemp & 0xF0)) >> 4)];
  520. }
  521. *(pjDstTemp) = (BYTE) ul;
  522. *(pjDstTemp + 1) = (BYTE) (ul >> 8);
  523. *(pjDstTemp + 2) = (BYTE) (ul >> 16);
  524. j++;
  525. pjDstTemp += 3;
  526. }
  527. //
  528. // grab 4 pixles at a time
  529. //
  530. for (i = cMiddlePixels; i != 0; i--)
  531. {
  532. if (j & 0x00000001)
  533. {
  534. ul0 = pulXlate[(*pjSrcTemp & 0x0F)];
  535. pjSrcTemp++;
  536. ul1 = pulXlate[(((ULONG) (*pjSrcTemp & 0xF0)) >> 4)];
  537. ul2 = pulXlate[((ULONG) (*pjSrcTemp & 0x0F))];
  538. pjSrcTemp++;
  539. ul3 = pulXlate[((ULONG) (*pjSrcTemp & 0xF0)) >> 4];
  540. }
  541. else
  542. {
  543. ul0 = pulXlate[(((ULONG) (*pjSrcTemp & 0xF0)) >> 4)];
  544. ul1 = pulXlate[((ULONG) (*pjSrcTemp & 0x0F))];
  545. pjSrcTemp++;
  546. ul2 = pulXlate[(((ULONG) (*pjSrcTemp & 0xF0)) >> 4)];
  547. ul3 = pulXlate[((ULONG) (*pjSrcTemp & 0x0F))];
  548. pjSrcTemp++;
  549. }
  550. *((ULONG*) (pjDstTemp)) = ul0 | (ul1 << 24);
  551. *((ULONG*) (pjDstTemp + 4)) = (ul1 >> 8) | (ul2 << 16);
  552. *((ULONG*) (pjDstTemp + 8)) = (ul3 << 8) | (ul2 >> 16);
  553. j += 4;
  554. pjDstTemp += 12;
  555. }
  556. // Take care of the end alignment:
  557. for (i = cEndPixels; i != 0; i--)
  558. {
  559. if (j & 0x00000001)
  560. {
  561. ul = pulXlate[*pjSrcTemp & 0x0F];
  562. pjSrcTemp++;
  563. }
  564. else
  565. {
  566. ul = pulXlate[(((ULONG) (*pjSrcTemp & 0xF0)) >> 4)];
  567. }
  568. *(pjDstTemp) = (BYTE) ul;
  569. *(pjDstTemp + 1) = (BYTE) (ul >> 8);
  570. *(pjDstTemp + 2) = (BYTE) (ul >> 16);
  571. j++;
  572. pjDstTemp += 3;
  573. }
  574. if (--cy == 0)
  575. break;
  576. pjSrc += psb->lDeltaSrc;
  577. pjDst += psb->lDeltaDst;
  578. }
  579. }
  580. /******************************Public*Routine******************************\
  581. * vSrcCopyS8D24
  582. *
  583. *
  584. * History:
  585. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  586. * Wrote it.
  587. \**************************************************************************/
  588. VOID vSrcCopyS8D24(PBLTINFO psb)
  589. {
  590. // We assume we are doing left to right top to bottom blting.
  591. // If it was on the same surface we would be doing the identity case.
  592. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D24 - direction not left to right");
  593. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D24 - direction not up to down");
  594. // These are our holding variables
  595. #if MESSAGE_BLT
  596. DbgPrint("Now entering vSrcCopyS8D24\n");
  597. #endif
  598. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  599. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  600. ULONG cx = psb->cx;
  601. ULONG cy = psb->cy;
  602. PULONG pulXlate = psb->pxlo->pulXlate;
  603. LONG lSrcSkip = psb->lDeltaSrc - cx;
  604. LONG lDstSkip = psb->lDeltaDst - (cx * 3);
  605. ULONG cStartPixels;
  606. ULONG cMiddlePixels;
  607. ULONG cEndPixels;
  608. ULONG i;
  609. ULONG ul;
  610. ULONG ul0;
  611. ULONG ul1;
  612. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  613. // 'cStartPixels' is the minimum number of 3-byte pixels we'll have to
  614. // write before we have dword alignment on the destination:
  615. cStartPixels = (ULONG)((ULONG_PTR) pjDst) & 3;
  616. if (cStartPixels > cx)
  617. {
  618. cStartPixels = cx;
  619. }
  620. cx -= cStartPixels;
  621. cMiddlePixels = cx >> 2;
  622. cEndPixels = cx & 3;
  623. while(1)
  624. {
  625. // Write pixels a byte at a time until we're 'dword' aligned on
  626. // the destination:
  627. for (i = cStartPixels; i != 0; i--)
  628. {
  629. ul = pulXlate[*pjSrc];
  630. *(pjDst) = (BYTE) ul;
  631. *(pjDst + 1) = (BYTE) (ul >> 8);
  632. *(pjDst + 2) = (BYTE) (ul >> 16);
  633. pjSrc += 1;
  634. pjDst += 3;
  635. }
  636. // Now write pixels a dword at a time. This is almost a 4x win
  637. // over doing byte writes if we're writing to frame buffer memory
  638. // over the PCI bus on Pentium class systems, because the PCI
  639. // write throughput is so slow:
  640. for (i = cMiddlePixels; i != 0; i--)
  641. {
  642. ul0 = (pulXlate[*(pjSrc)]);
  643. ul1 = (pulXlate[*(pjSrc + 1)]);
  644. *((ULONG*) (pjDst)) = ul0 | (ul1 << 24);
  645. ul0 = (pulXlate[*(pjSrc + 2)]);
  646. *((ULONG*) (pjDst + 4)) = (ul1 >> 8) | (ul0 << 16);
  647. ul1 = (pulXlate[*(pjSrc + 3)]);
  648. *((ULONG*) (pjDst + 8)) = (ul1 << 8) | (ul0 >> 16);
  649. pjSrc += 4;
  650. pjDst += 12;
  651. }
  652. // Take care of the end alignment:
  653. for (i = cEndPixels; i != 0; i--)
  654. {
  655. ul = pulXlate[*pjSrc];
  656. *(pjDst) = (BYTE) ul;
  657. *(pjDst + 1) = (BYTE) (ul >> 8);
  658. *(pjDst + 2) = (BYTE) (ul >> 16);
  659. pjSrc += 1;
  660. pjDst += 3;
  661. }
  662. if (--cy == 0)
  663. break;
  664. pjSrc += lSrcSkip;
  665. pjDst += lDstSkip;
  666. }
  667. }
  668. /******************************Public*Routine******************************\
  669. * vSrcCopyS16D24
  670. *
  671. *
  672. * History:
  673. * 07-Feb-1991 -by- Patrick Haluptzok patrickh
  674. * Wrote it.
  675. \**************************************************************************/
  676. VOID vSrcCopyS16D24(PBLTINFO psb)
  677. {
  678. // We assume we are doing left to right top to bottom blting
  679. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D24 - direction not left to right");
  680. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D24 - direction not up to down");
  681. // These are our holding variables
  682. PBYTE pjSrc = psb->pjSrc + (2 * psb->xSrcStart);
  683. PBYTE pjDst = psb->pjDst + (3 * psb->xDstStart);
  684. ULONG cx = psb->cx;
  685. ULONG cy = psb->cy;
  686. XLATE *pxlo = psb->pxlo;
  687. LONG lSrcSkip = psb->lDeltaSrc - (cx * 2);
  688. LONG lDstSkip = psb->lDeltaDst - (cx * 3);
  689. PFN_pfnXlate pfnXlate = pxlo->pfnXlateBetweenBitfields();
  690. ULONG cStartPixels;
  691. ULONG cMiddlePixels;
  692. ULONG cEndPixels;
  693. ULONG ul;
  694. ULONG ul0;
  695. ULONG ul1;
  696. LONG i;
  697. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  698. // 'cStartPixels' is the minimum number of 3-byte pixels we'll have to
  699. // write before we have dword alignment on the destination:
  700. cStartPixels = (ULONG)((ULONG_PTR) pjDst) & 3;
  701. if (cStartPixels > cx)
  702. {
  703. cStartPixels = cx;
  704. }
  705. cx -= cStartPixels;
  706. cMiddlePixels = cx >> 2;
  707. cEndPixels = cx & 3;
  708. while (1)
  709. {
  710. for (i = cStartPixels; i != 0; i--)
  711. {
  712. ul = pfnXlate(pxlo, *((USHORT*) pjSrc));
  713. *(pjDst) = (BYTE) (ul);
  714. *(pjDst + 1) = (BYTE) (ul >> 8);
  715. *(pjDst + 2) = (BYTE) (ul >> 16);
  716. pjSrc += 2;
  717. pjDst += 3;
  718. }
  719. for (i = cMiddlePixels; i != 0; i--)
  720. {
  721. ul0 = pfnXlate(pxlo, *((USHORT*) (pjSrc)));
  722. ul1 = pfnXlate(pxlo, *((USHORT*) (pjSrc + 2)));
  723. *((ULONG*) (pjDst)) = ul0 | (ul1 << 24);
  724. ul0 = pfnXlate(pxlo, *((USHORT*) (pjSrc + 4)));
  725. *((ULONG*) (pjDst + 4)) = (ul1 >> 8) | (ul0 << 16);
  726. ul1 = pfnXlate(pxlo, *((USHORT*) (pjSrc + 6)));
  727. *((ULONG*) (pjDst + 8)) = (ul1 << 8) | (ul0 >> 16);
  728. pjSrc += 8;
  729. pjDst += 12;
  730. }
  731. for (i = cEndPixels; i != 0; i--)
  732. {
  733. ul = pfnXlate(pxlo, *((USHORT*) pjSrc));
  734. *(pjDst) = (BYTE) (ul);
  735. *(pjDst + 1) = (BYTE) (ul >> 8);
  736. *(pjDst + 2) = (BYTE) (ul >> 16);
  737. pjSrc += 2;
  738. pjDst += 3;
  739. }
  740. if (--cy == 0)
  741. break;
  742. pjSrc += lSrcSkip;
  743. pjDst += lDstSkip;
  744. }
  745. VERIFYS16D24(psb);
  746. }
  747. /******************************Public*Routine******************************\
  748. * vSrcCopyS24D24
  749. *
  750. *
  751. * History:
  752. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  753. * Wrote it.
  754. \**************************************************************************/
  755. VOID vSrcCopyS24D24(PBLTINFO psb)
  756. {
  757. // We assume we are doing left to right top to bottom blting
  758. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D24 - direction not left to right");
  759. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D24 - direction not up to down");
  760. // These are our holding variables
  761. #if MESSAGE_BLT
  762. DbgPrint("Now entering vSrcCopyS8D24\n");
  763. #endif
  764. PBYTE pjSrcTemp;
  765. PBYTE pjDstTemp;
  766. PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart * 3);
  767. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  768. ULONG cx = psb->cx;
  769. ULONG cy = psb->cy;
  770. XLATE *pxlo = psb->pxlo;
  771. ULONG cStartPixels;
  772. ULONG cMiddlePixels;
  773. ULONG cEndPixels;
  774. ULONG i,j;
  775. ULONG ul;
  776. ULONG ul0,ul1,ul2,ul3;
  777. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  778. // 'cStartPixels' is the minimum number of 3-byte pixels we'll have to
  779. // write before we have dword alignment on the destination:
  780. cStartPixels = (ULONG)((ULONG_PTR) pjDst) & 3;
  781. if (cStartPixels > cx)
  782. {
  783. cStartPixels = cx;
  784. }
  785. cx -= cStartPixels;
  786. cMiddlePixels = cx >> 2;
  787. cEndPixels = cx & 3;
  788. while(1)
  789. {
  790. // Write pixels a byte at a time until we're 'dword' aligned on
  791. // the destination:
  792. j = psb->xSrcStart;
  793. pjDstTemp = pjDst;
  794. pjSrcTemp = pjSrc;
  795. for (i = cStartPixels; i != 0; i--)
  796. {
  797. ul = (ULONG) *(pjSrcTemp + 2);
  798. ul = ul << 8;
  799. ul |= (ULONG) *(pjSrcTemp + 1);
  800. ul = ul << 8;
  801. ul |= (ULONG) *pjSrcTemp;
  802. ul = pxlo->ulTranslate(ul);
  803. *(pjDstTemp++) = (BYTE) ul;
  804. *(pjDstTemp++) = (BYTE) (ul >> 8);
  805. *(pjDstTemp++) = (BYTE) (ul >> 16);
  806. pjSrcTemp += 3;
  807. }
  808. //
  809. // grab 4 pixles at a time
  810. //
  811. for (i = cMiddlePixels; i != 0; i--)
  812. {
  813. ul0 = (ULONG) *(pjSrcTemp + 2);
  814. ul0 = ul0 << 8;
  815. ul0 |= (ULONG) *(pjSrcTemp + 1);
  816. ul0 = ul0 << 8;
  817. ul0 |= (ULONG) *pjSrcTemp;
  818. ul0 = pxlo->ulTranslate(ul0);
  819. pjSrcTemp += 3;
  820. ul1 = (ULONG) *(pjSrcTemp + 2);
  821. ul1 = ul1 << 8;
  822. ul1 |= (ULONG) *(pjSrcTemp + 1);
  823. ul1 = ul1 << 8;
  824. ul1 |= (ULONG) *pjSrcTemp;
  825. ul1 = pxlo->ulTranslate(ul1);
  826. pjSrcTemp += 3;
  827. ul2 = (ULONG) *(pjSrcTemp + 2);
  828. ul2 = ul2 << 8;
  829. ul2 |= (ULONG) *(pjSrcTemp + 1);
  830. ul2 = ul2 << 8;
  831. ul2 |= (ULONG) *pjSrcTemp;
  832. ul2 = pxlo->ulTranslate(ul2);
  833. pjSrcTemp += 3;
  834. ul3 = (ULONG) *(pjSrcTemp + 2);
  835. ul3 = ul3 << 8;
  836. ul3 |= (ULONG) *(pjSrcTemp + 1);
  837. ul3 = ul3 << 8;
  838. ul3 |= (ULONG) *pjSrcTemp;
  839. ul3 = pxlo->ulTranslate(ul3);
  840. pjSrcTemp += 3;
  841. *((ULONG*) (pjDstTemp)) = ul0 | (ul1 << 24);
  842. *((ULONG*) (pjDstTemp + 4)) = (ul1 >> 8) | (ul2 << 16);
  843. *((ULONG*) (pjDstTemp + 8)) = (ul3 << 8) | (ul2 >> 16);
  844. pjDstTemp += 12;
  845. }
  846. // Take care of the end alignment:
  847. for (i = cEndPixels; i != 0; i--)
  848. {
  849. ul = (ULONG) *(pjSrcTemp + 2);
  850. ul = ul << 8;
  851. ul |= (ULONG) *(pjSrcTemp + 1);
  852. ul = ul << 8;
  853. ul |= (ULONG) *pjSrcTemp;
  854. ul = pxlo->ulTranslate(ul);
  855. *(pjDstTemp++) = (BYTE) ul;
  856. *(pjDstTemp++) = (BYTE) (ul >> 8);
  857. *(pjDstTemp++) = (BYTE) (ul >> 16);
  858. pjSrcTemp += 3;
  859. }
  860. if (--cy == 0)
  861. break;
  862. pjSrc += psb->lDeltaSrc;
  863. pjDst += psb->lDeltaDst;
  864. }
  865. }
  866. /******************************Public*Routine******************************\
  867. * vSrcCopyS24D24Identity
  868. *
  869. * This is the special case no translate blting. All the SmDn should have
  870. * them if m==n. Identity xlates only occur amoung matching format bitmaps
  871. * and screens.
  872. *
  873. * History:
  874. * 18-Feb-1991 -by- Patrick Haluptzok patrickh
  875. * Wrote it.
  876. \**************************************************************************/
  877. VOID vSrcCopyS24D24Identity(PBLTINFO psb)
  878. {
  879. PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart * 3);
  880. PBYTE pjDst = psb->pjDst + (psb->xDstStart * 3);
  881. ULONG cx = psb->cx * 3;
  882. ULONG cy = psb->cy;
  883. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  884. #if MESSAGE_BLT
  885. DbgPrint("xdir: %ld cy: %lu xSrcStart %lu xDstStart %lu xSrcEnd %lu cx %lu\n",
  886. psb->xDir, cy, psb->xSrcStart, psb->xDstStart, psb->xSrcEnd, cx);
  887. #endif
  888. if (psb->xDir < 0)
  889. {
  890. pjSrc -= (cx - 3);
  891. pjDst -= (cx - 3);
  892. }
  893. while(1)
  894. {
  895. if(psb->fSrcAlignedRd)
  896. vSrcAlignCopyMemory(pjDst, pjSrc, cx);
  897. else
  898. RtlMoveMemory((PVOID)pjDst, (PVOID)pjSrc, cx);
  899. if (--cy)
  900. {
  901. pjSrc += psb->lDeltaSrc;
  902. pjDst += psb->lDeltaDst;
  903. }
  904. else
  905. break;
  906. }
  907. }
  908. /******************************Public*Routine******************************\
  909. * vSrcCopyS32D24
  910. *
  911. *
  912. * History:
  913. * 07-Feb-1991 -by- Patrick Haluptzok patrickh
  914. * Wrote it.
  915. \**************************************************************************/
  916. VOID vSrcCopyS32D24(PBLTINFO psb)
  917. {
  918. // We assume we are doing left to right top to bottom blting
  919. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D24 - direction not left to right");
  920. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D24 - direction not up to down");
  921. // These are our holding variables
  922. PBYTE pjSrc = psb->pjSrc + (4 * psb->xSrcStart);
  923. PBYTE pjDst = psb->pjDst + (3 * psb->xDstStart);
  924. ULONG cx = psb->cx;
  925. ULONG cy = psb->cy;
  926. XLATE *pxlo = psb->pxlo;
  927. XEPALOBJ palSrc(pxlo->ppalSrc);
  928. XEPALOBJ palDst(pxlo->ppalDst);
  929. LONG lSrcSkip = psb->lDeltaSrc - (cx * 4);
  930. LONG lDstSkip = psb->lDeltaDst - (cx * 3);
  931. PFN_pfnXlate pfnXlate;
  932. ULONG cStartPixels;
  933. ULONG cMiddlePixels;
  934. ULONG cEndPixels;
  935. ULONG ul;
  936. ULONG ul0;
  937. ULONG ul1;
  938. LONG i;
  939. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  940. if (palSrc.bIsBGR() && palDst.bIsBGR())
  941. {
  942. // 'cStartPixels' is the minimum number of 3-byte pixels we'll have to
  943. // write before we have dword alignment on the destination:
  944. cStartPixels = (ULONG)((ULONG_PTR) pjDst) & 3;
  945. if (cStartPixels > cx)
  946. {
  947. cStartPixels = cx;
  948. }
  949. cx -= cStartPixels;
  950. cMiddlePixels = cx >> 2;
  951. cEndPixels = cx & 3;
  952. while (1)
  953. {
  954. for (i = cStartPixels; i != 0; i--)
  955. {
  956. *(pjDst) = *(pjSrc);
  957. *(pjDst + 1) = *(pjSrc + 1);
  958. *(pjDst + 2) = *(pjSrc + 2);
  959. pjSrc += 4;
  960. pjDst += 3;
  961. }
  962. for (i = cMiddlePixels; i != 0; i--)
  963. {
  964. ul0 = *((ULONG *) (pjSrc));
  965. ul1 = *((ULONG *) (pjSrc + 4));
  966. *((ULONG*) (pjDst)) = (ul0 & 0xffffff) | (ul1 << 24);
  967. ul0 = *((ULONG *) (pjSrc + 8));
  968. *((ULONG*) (pjDst + 4)) = ((ul1 >> 8) & 0xffff) | (ul0 << 16);
  969. ul1 = *((ULONG *) (pjSrc + 12));
  970. *((ULONG*) (pjDst + 8)) = (ul1 << 8) | ((ul0 >> 16) & 0xff);
  971. pjSrc += 16;
  972. pjDst += 12;
  973. }
  974. for (i = cEndPixels; i != 0; i--)
  975. {
  976. *(pjDst) = *(pjSrc);
  977. *(pjDst + 1) = *(pjSrc + 1);
  978. *(pjDst + 2) = *(pjSrc + 2);
  979. pjSrc += 4;
  980. pjDst += 3;
  981. }
  982. if (--cy == 0)
  983. break;
  984. pjSrc += lSrcSkip;
  985. pjDst += lDstSkip;
  986. }
  987. VERIFYS32D24(psb);
  988. return;
  989. }
  990. pfnXlate = pxlo->pfnXlateBetweenBitfields();
  991. while (1)
  992. {
  993. i = cx;
  994. do {
  995. ul = pfnXlate(pxlo, *((ULONG*) pjSrc));
  996. *(pjDst) = (BYTE) (ul);
  997. *(pjDst + 1) = (BYTE) (ul >> 8);
  998. *(pjDst + 2) = (BYTE) (ul >> 16);
  999. pjSrc += 4;
  1000. pjDst += 3;
  1001. } while (--i != 0);
  1002. if (--cy == 0)
  1003. break;
  1004. pjSrc += lSrcSkip;
  1005. pjDst += lDstSkip;
  1006. }
  1007. VERIFYS32D24(psb);
  1008. }