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.

1069 lines
30 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: srcblt4.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt to a 4 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. /*******************Public*Routine*****************\
  15. * vSrcCopyS1D4
  16. *
  17. * There are three main loops in this function.
  18. *
  19. * The first loop deals with the full bytes part of
  20. * the Dst while fetching/shifting the matching 8 bits
  21. * from the Src.
  22. *
  23. * The second loop deals with the starting pixels
  24. * We use a dword mask here.
  25. *
  26. * The third loop deals with the Ending pixels
  27. * We use a dword mask here.
  28. *
  29. * We use a 4 entry dword table to expand the
  30. * Src bits. We walk thru Src one byte at a time
  31. * and expand the byte to 1 dword
  32. *
  33. * History:
  34. * 17-Oct-1994 -by- Lingyun Wang [lingyunw]
  35. * Wrote it.
  36. *
  37. \**************************************************/
  38. VOID vSrcCopyS1D4(PBLTINFO psb)
  39. {
  40. BYTE jSrc; // holds a source byte
  41. BYTE jDst; // holds a dest byte
  42. INT iSrc; // bit position in the first Src byte
  43. INT iDst; // bit position in the first 8 Dst nibbles
  44. PBYTE pjDst; // pointer to the Src bytes
  45. PBYTE pjSrc; // pointer to the Dst bytes
  46. LONG xSrcEnd = psb->xSrcEnd;
  47. LONG cy; // number of rows
  48. LONG cx; // number of pixels
  49. BYTE jAlignL; // alignment bits to the left
  50. BYTE jAlignR; // alignment bits to the right
  51. LONG cFullBytes; //number of full 8 bytes dealed with
  52. BOOL bNextByte;
  53. LONG xDstEnd;
  54. LONG lDeltaDst;
  55. LONG lDeltaSrc;
  56. BYTE jB = (BYTE) (psb->pxlo->pulXlate[0]);
  57. BYTE jF = (BYTE) (psb->pxlo->pulXlate[1]);
  58. BYTE ajExpTable[4];
  59. INT count;
  60. INT i;
  61. BYTE ajSrc[4];
  62. static ULONG aulStartMask[8] = {0XFFFFFFFF, 0XFFFFFF0F, 0XFFFFFF00,
  63. 0XFFFF0F00, 0XFFFF0000, 0XFF0F0000,
  64. 0XFF000000, 0X0F000000};
  65. static ULONG aulEndMask[8] = {0X00000000, 0X000000F0, 0X000000FF,
  66. 0X0000F0FF, 0X0000FFFF, 0X00F0FFFF,
  67. 0X00FFFFFF, 0XF0FFFFFF};
  68. ULONG ulMask;
  69. BOOL bNextSrc=TRUE;
  70. // We assume we are doing left to right top to bottom blting
  71. ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D4 - direction not left to right");
  72. ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D4 - direction not up to down");
  73. ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
  74. //DbgPrint ("vsrccopys1d4\n");
  75. // Build table
  76. ajExpTable[0] = jB | (jB << 4); // 0 0
  77. ajExpTable[1] = jF | (jB << 4); // 0 1
  78. ajExpTable[2] = jB | (jF << 4); // 1 0
  79. ajExpTable[3] = jF | (jF << 4); //1 1
  80. //Get Src and Dst start positions
  81. iSrc = psb->xSrcStart & 0x0007;
  82. iDst = psb->xDstStart & 0x0007;
  83. // Checking alignment
  84. // If Src starting point is ahead of Dst
  85. if (iSrc < iDst)
  86. jAlignL = 8 - (iDst - iSrc);
  87. else
  88. // If Dst starting point is ahead of Src
  89. jAlignL = iSrc - iDst;
  90. jAlignR = 8 - jAlignL;
  91. cx=psb->cx;
  92. xDstEnd = psb->xDstStart + cx;
  93. lDeltaDst = psb->lDeltaDst;
  94. lDeltaSrc = psb->lDeltaSrc;
  95. // check if there is a next 8 nibbles
  96. bNextByte = !((xDstEnd>>3) ==
  97. (psb->xDstStart>>3));
  98. if (bNextByte)
  99. {
  100. long iStrideSrc;
  101. long iStrideDst;
  102. PBYTE pjSrcEnd; //pointer to the Last full Src byte
  103. // Get first Dst full 8 nibbles (1 dword expanding from
  104. // 1 Src byte)
  105. pjDst = psb->pjDst + (((psb->xDstStart+7)&~0x07)>>1);
  106. // Get the Src byte that matches the first Dst
  107. // full 8 nibbles
  108. pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
  109. //Get the number of full bytes
  110. cFullBytes = (xDstEnd>>3)-((psb->xDstStart+7)>>3);
  111. //the increment to the full byte on the next scan line
  112. iStrideDst = lDeltaDst - cFullBytes*4;
  113. iStrideSrc = lDeltaSrc - cFullBytes;
  114. // deal with our special case
  115. cy = psb->cy;
  116. if (!jAlignL)
  117. {
  118. while (cy--)
  119. {
  120. pjSrcEnd = pjSrc+cFullBytes;
  121. while (pjSrc != pjSrcEnd)
  122. {
  123. jSrc = *pjSrc++;
  124. *pjDst = ajExpTable[(jSrc&0xC0)>>6];
  125. *(pjDst+1) = ajExpTable[(jSrc&0x30)>>4];
  126. *(pjDst+2) = ajExpTable[(jSrc&0x0C)>>2];
  127. *(pjDst+3) = ajExpTable[jSrc&0x03];
  128. pjDst +=4;
  129. }
  130. pjDst += iStrideDst;
  131. pjSrc += iStrideSrc;
  132. }
  133. } //end of if (!jAlignL)
  134. else // if not aligned
  135. {
  136. BYTE jRem; //remainder
  137. while (cy--)
  138. {
  139. jRem = *pjSrc << jAlignL;
  140. pjSrcEnd = pjSrc+cFullBytes;
  141. while (pjSrc != pjSrcEnd)
  142. {
  143. jSrc = ((*(++pjSrc))>>jAlignR) | jRem;
  144. *pjDst = ajExpTable[(jSrc&0xC0)>>6];
  145. *(pjDst+1) = ajExpTable[(jSrc&0x30)>>4];
  146. *(pjDst+2) = ajExpTable[(jSrc&0x0C)>>2];
  147. *(pjDst+3) = ajExpTable[jSrc&0x03];
  148. pjDst +=4;
  149. //next remainder
  150. jRem = *pjSrc << jAlignL;
  151. }
  152. pjDst += iStrideDst;
  153. pjSrc += iStrideSrc;
  154. }
  155. } //else
  156. } //if
  157. // End of our dealing with the full bytes
  158. //Deal with the starting pixels
  159. if (iDst | !bNextByte)
  160. {
  161. //build our masks
  162. ulMask = aulStartMask[iDst];
  163. // if there are only one partial left byte,
  164. // the mask is special
  165. // for example, when we have 00111000 for
  166. // Dst
  167. if (!bNextByte)
  168. {
  169. ulMask &= aulEndMask[xDstEnd&0x0007];
  170. }
  171. bNextSrc = ((iSrc+cx)>8);
  172. pjDst = psb->pjDst + ((psb->xDstStart&~0x07)>>1);
  173. pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
  174. cy = psb->cy;
  175. if (iSrc >= iDst)
  176. {
  177. if (bNextSrc)
  178. {
  179. while (cy--)
  180. {
  181. jSrc = *pjSrc << jAlignL;
  182. jSrc |= *(pjSrc+1) >> jAlignR;
  183. ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6];
  184. ajSrc[1] = ajExpTable[(jSrc&0x30)>>4];
  185. ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2];
  186. ajSrc[3] = ajExpTable[jSrc&0x03];
  187. *(PULONG) ajSrc &= ulMask;
  188. *(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
  189. pjDst += lDeltaDst;
  190. pjSrc += lDeltaSrc;
  191. }
  192. }
  193. else
  194. {
  195. while (cy--)
  196. {
  197. jSrc = *pjSrc << jAlignL;
  198. ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6];
  199. ajSrc[1] = ajExpTable[(jSrc&0x30)>>4];
  200. ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2];
  201. ajSrc[3] = ajExpTable[jSrc&0x03];
  202. *(PULONG) ajSrc &= ulMask;
  203. *(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
  204. pjDst += lDeltaDst;
  205. pjSrc += lDeltaSrc;
  206. }
  207. }
  208. }
  209. else //if (iSrc < iDst)
  210. {
  211. while (cy--)
  212. {
  213. jSrc = *pjSrc >> jAlignR;
  214. ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6];
  215. ajSrc[1] = ajExpTable[(jSrc&0x30)>>4];
  216. ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2];
  217. ajSrc[3] = ajExpTable[jSrc&0x03];
  218. *(PULONG) ajSrc &= ulMask;
  219. *(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
  220. pjDst += lDeltaDst;
  221. pjSrc += lDeltaSrc;
  222. }
  223. }
  224. }
  225. // Dealing with Ending pixels
  226. if ((xDstEnd & 0x0007)
  227. && bNextByte)
  228. {
  229. ulMask = aulEndMask[xDstEnd & 0x0007];
  230. pjDst = psb->pjDst + ((xDstEnd&~0x07)>>1);
  231. pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
  232. iSrc = (xSrcEnd-1) & 0x0007;
  233. iDst = (xDstEnd-1) & 0x0007;
  234. cy = psb->cy;
  235. if (iSrc >= iDst)
  236. {
  237. while (cy--)
  238. {
  239. jSrc = *pjSrc << jAlignL;
  240. ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6];
  241. ajSrc[1] = ajExpTable[(jSrc&0x30)>>4];
  242. ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2];
  243. ajSrc[3] = ajExpTable[jSrc&0x03];
  244. *(PULONG) ajSrc &= ulMask;
  245. *(PULONG) pjDst = (*(PULONG) pjDst & ~ulMask) | *(PULONG) ajSrc;
  246. pjDst += lDeltaDst;
  247. pjSrc += lDeltaSrc;
  248. }
  249. }
  250. else //if (iSrc < iDst)
  251. {
  252. while (cy--)
  253. {
  254. jSrc = *(pjSrc-1) << jAlignL;
  255. jSrc |= *pjSrc >> jAlignR;
  256. ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6];
  257. ajSrc[1] = ajExpTable[(jSrc&0x30)>>4];
  258. ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2];
  259. ajSrc[3] = ajExpTable[jSrc&0x03];
  260. *(PULONG) ajSrc &= ulMask;
  261. *(PULONG) pjDst = (*(PULONG) pjDst & ~ulMask) | *(PULONG) ajSrc;
  262. pjDst += lDeltaDst;
  263. pjSrc += lDeltaSrc;
  264. }
  265. }
  266. }
  267. }
  268. /******************************Public*Routine******************************\
  269. * vSrcCopyS4D4
  270. *
  271. * History:
  272. * 09-Feb-1991 -by- Patrick Haluptzok patrickh
  273. * Wrote it.
  274. \**************************************************************************/
  275. VOID vSrcCopyS4D4(PBLTINFO psb)
  276. {
  277. // We assume we are doing left to right top to bottom blting
  278. // Otherwise we would be in vSrcCopyS4D4Identity.
  279. ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D4 - direction not left to right");
  280. ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D4 - direction not up to down");
  281. BYTE jSrc;
  282. BYTE jDst;
  283. LONG iSrc;
  284. LONG iDst;
  285. PBYTE pjDst;
  286. PBYTE pjSrc;
  287. PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1);
  288. PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart >> 1);
  289. ULONG cy = psb->cy;
  290. PULONG pulXlate = psb->pxlo->pulXlate;
  291. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  292. while(1)
  293. {
  294. // Initialize all the variables
  295. pjDst = pjDstHolder;
  296. pjSrc = pjSrcHolder;
  297. iSrc = psb->xSrcStart;
  298. iDst = psb->xDstStart;
  299. {
  300. // If source and dest are not aligned we have to do
  301. // this the hard way
  302. //
  303. if ((iSrc ^ iDst) & 1)
  304. {
  305. LONG iCnt;
  306. iSrc = psb->xSrcEnd - iSrc;
  307. // if blt starts on odd nibble we need to update it
  308. //
  309. if ((iDst & 1) && iSrc)
  310. {
  311. *pjDst = (*pjDst & 0xf0) | (BYTE)pulXlate[((*pjSrc >> 4) & 0x0f)];
  312. pjDst++;
  313. iSrc--;
  314. }
  315. // loop once per output byte (2 pixels)
  316. //
  317. iCnt = iSrc >> 1;
  318. while (--iCnt >= 0)
  319. {
  320. *pjDst++ = ((BYTE)pulXlate[*pjSrc & 0x0f] << 4) |
  321. (BYTE)pulXlate[(pjSrc[1] >> 4) & 0x0f];
  322. pjSrc++;
  323. }
  324. // test if blt ends on odd nibble
  325. //
  326. if (iSrc & 1)
  327. *pjDst = (*pjDst & 0x0f) | ((BYTE)pulXlate[*pjSrc & 0x0f] << 4);
  328. }
  329. // Source and Dest are aligned
  330. //
  331. else
  332. {
  333. LONG iCnt;
  334. iSrc = psb->xSrcEnd - iSrc;
  335. // if blt starts on odd nibble we need to update it
  336. //
  337. if ((iDst & 1) && iSrc)
  338. {
  339. *pjDst = (*pjDst & 0xf0) | (BYTE)pulXlate[*pjSrc++ & 0x0f];
  340. pjDst++;
  341. iSrc--;
  342. }
  343. // loop once per output byte (2 pixels)
  344. //
  345. iCnt = iSrc >> 1;
  346. while (--iCnt >= 0)
  347. {
  348. *pjDst++ = (BYTE)pulXlate[*pjSrc & 0x0f] |
  349. ((BYTE)pulXlate[(*pjSrc & 0xf0) >> 4] << 4);
  350. pjSrc++;
  351. }
  352. // test if blt ends on odd nibble
  353. //
  354. if (iSrc & 1)
  355. *pjDst = (*pjDst & 0x0f) | ((BYTE)pulXlate[(*pjSrc >> 4) & 0x0f] << 4);
  356. }
  357. }
  358. // Check if we have anymore scanlines to do
  359. if (--cy)
  360. {
  361. pjSrcHolder += psb->lDeltaSrc;
  362. pjDstHolder += psb->lDeltaDst;
  363. }
  364. else
  365. break;
  366. }
  367. }
  368. /******************************Public*Routine******************************\
  369. * vSrcCopyS4D4Identity
  370. *
  371. * History:
  372. * 09-Feb-1991 -by- Patrick Haluptzok patrickh
  373. * Wrote it.
  374. \**************************************************************************/
  375. VOID vSrcCopyS4D4Identity(PBLTINFO psb)
  376. {
  377. BYTE jSrc;
  378. BYTE jDst;
  379. LONG iSrc;
  380. LONG iDst;
  381. PBYTE pjDst;
  382. PBYTE pjSrc;
  383. PBYTE pjDstHolder = psb->pjDst + ((psb->xDstStart) >> 1);
  384. PBYTE pjSrcHolder = psb->pjSrc + ((psb->xSrcStart) >> 1);
  385. ULONG cy = psb->cy;
  386. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  387. #if MESSAGE_BLT
  388. DbgPrint("Now entering vSrcCopyS4D4Identity\n");
  389. DbgPrint("xdir: %ld cy: %lu xSrcStart %lu xDstStart %lu xSrcEnd %lu \n",
  390. psb->xDir, cy, psb->xSrcStart, psb->xDstStart, psb->xSrcEnd);
  391. #endif
  392. if (psb->xDir > 0)
  393. {
  394. // We're going left to right.
  395. while(1)
  396. {
  397. // Initialize all the variables
  398. pjDst = pjDstHolder;
  399. pjSrc = pjSrcHolder;
  400. iSrc = psb->xSrcStart;
  401. iDst = psb->xDstStart;
  402. // If source and dest are not aligned we have to do
  403. // this the hard way
  404. //
  405. if ((iSrc ^ iDst) & 1)
  406. {
  407. LONG iCnt;
  408. iSrc = psb->xSrcEnd - iSrc;
  409. // if blt starts on odd nibble we need to update it
  410. //
  411. if ((iDst & 1) && iSrc)
  412. {
  413. *pjDst = (*pjDst & 0xf0) | ((*pjSrc >> 4) & 0x0f);
  414. pjDst++;
  415. iSrc--;
  416. }
  417. // loop once per output byte (2 pixels)
  418. //
  419. iCnt = iSrc >> 1;
  420. while (--iCnt >= 0)
  421. {
  422. BYTE jSrc = *pjSrc++ << 4;
  423. *pjDst++ = jSrc | ((*pjSrc >> 4) & 0x0f);
  424. }
  425. // test if blt ends on odd nibble
  426. //
  427. if (iSrc & 1)
  428. *pjDst = (*pjDst & 0x0f) | (*pjSrc << 4);
  429. }
  430. // Source and Dest are aligned
  431. //
  432. else
  433. {
  434. iSrc = psb->xSrcEnd - iSrc;
  435. // if blt starts on odd nibble we need to update it
  436. //
  437. if ((iDst & 1) && iSrc)
  438. {
  439. *pjDst = (*pjDst & 0xf0) | (*pjSrc++ & 0x0f);
  440. pjDst++;
  441. iSrc--;
  442. }
  443. // loop once per output byte (2 pixels)
  444. //
  445. RtlMoveMemory(pjDst,pjSrc,iSrc >> 1);
  446. // test if blt ends on odd nibble
  447. //
  448. if (iSrc & 1)
  449. {
  450. iSrc >>= 1;
  451. pjDst[iSrc] = (pjDst[iSrc] & 0x0f) | (pjSrc[iSrc] & 0xf0);
  452. }
  453. }
  454. // Check if we have anymore scanlines to do
  455. if (--cy)
  456. {
  457. pjSrcHolder += psb->lDeltaSrc;
  458. pjDstHolder += psb->lDeltaDst;
  459. }
  460. else
  461. break;
  462. }
  463. }
  464. else
  465. {
  466. // We're going right to left. It must be on the same hsurf,
  467. // therefore must be an identity translation.
  468. ASSERTGDI(psb->pxlo->bIsIdentity(), "Error: S4D4 -xDir, non-ident xlate");
  469. while(1)
  470. {
  471. // Initialize all the variables
  472. pjDst = pjDstHolder;
  473. pjSrc = pjSrcHolder;
  474. iSrc = psb->xSrcStart;
  475. iDst = psb->xDstStart;
  476. if (!(iSrc & 0x00000001))
  477. {
  478. jSrc = *pjSrc;
  479. pjSrc--;
  480. }
  481. if (iDst & 0x00000001)
  482. {
  483. jDst = 0;
  484. }
  485. else
  486. {
  487. // We're gonna need the low nibble from the first byte
  488. jDst = *pjDst;
  489. jDst = (BYTE) (jDst & 0x0F);
  490. }
  491. // Do the inner loop on a scanline
  492. while(iSrc != psb->xSrcEnd)
  493. {
  494. if (iSrc & 0x00000001)
  495. {
  496. // We need a new source byte
  497. jSrc = *pjSrc;
  498. pjSrc--;
  499. if (iDst & 0x00000001)
  500. {
  501. // jDst must be 0 right now.
  502. ASSERTGDI(jDst == (BYTE) 0, "ERROR in vSrcCopyS4D4 srcblt logic");
  503. jDst |= (BYTE) (jSrc & 0x0F);
  504. }
  505. else
  506. {
  507. jDst |= (BYTE) (((ULONG) (jSrc & 0x0F)) << 4);
  508. *pjDst = jDst;
  509. pjDst--;
  510. jDst = 0;
  511. }
  512. }
  513. else
  514. {
  515. if (iDst & 0x00000001)
  516. {
  517. // jDst must be 0 right now.
  518. ASSERTGDI(jDst == (BYTE) 0, "ERROR in vSrcCopyS4D4 srcblt logic");
  519. jDst |= (BYTE) ((jSrc & 0xF0) >> 4);
  520. }
  521. else
  522. {
  523. jDst |= (BYTE) (jSrc & 0xF0);
  524. *pjDst = jDst;
  525. pjDst--;
  526. jDst = 0;
  527. }
  528. }
  529. iSrc--;
  530. iDst--;
  531. }
  532. // Clean up after the inner loop. We are going right to left.
  533. if (!(iDst & 0x00000001))
  534. {
  535. // The last pel was the low nibble, we need to get the high
  536. // nibble out of the bitmap and write then write the byte in.
  537. *pjDst = (BYTE) (jDst | (*pjDst & 0xF0));
  538. }
  539. // Check if we have anymore scanlines to do
  540. if (--cy)
  541. {
  542. pjSrcHolder += psb->lDeltaSrc;
  543. pjDstHolder += psb->lDeltaDst;
  544. }
  545. else
  546. break;
  547. }
  548. }
  549. }
  550. /******************************Public*Routine******************************\
  551. * vSrcCopyS8D4
  552. *
  553. *
  554. * History:
  555. * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh]
  556. * optimize color translation
  557. *
  558. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  559. * Wrote it.
  560. \**************************************************************************/
  561. VOID vSrcCopyS8D4(PBLTINFO psb)
  562. {
  563. // We assume we are doing left to right top to bottom blting
  564. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D4 - direction not left to right");
  565. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D4 - direction not up to down");
  566. LONG iDst;
  567. PBYTE pjSrc;
  568. PBYTE pjDst;
  569. LONG iDstEnd = psb->xDstStart + psb->cx;
  570. PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1);
  571. PBYTE pjSrcHolder = psb->pjSrc + psb->xSrcStart;
  572. ULONG cy = psb->cy;
  573. PULONG pulXlate = psb->pxlo->pulXlate;
  574. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  575. while(1)
  576. {
  577. pjDst = pjDstHolder;
  578. pjSrc = pjSrcHolder;
  579. iDst = psb->xDstStart;
  580. if (iDst & 0x00000001)
  581. {
  582. // Do the first byte if it's misaligned.
  583. *pjDst = (BYTE) ((*pjDst) & 0xF0) | ((BYTE) pulXlate[*(pjSrc++)]);
  584. pjDst++;
  585. iDst++;
  586. }
  587. while(1)
  588. {
  589. if ((iDst + 1) < iDstEnd)
  590. {
  591. // Do a whole byte.
  592. *(pjDst++) = (BYTE) (pulXlate[*(pjSrc + 1)] |
  593. (pulXlate[*pjSrc] << 4));
  594. pjSrc += 2;
  595. iDst += 2;
  596. }
  597. else
  598. {
  599. // Check and see if we have a byte left to do.
  600. if (iDst < iDstEnd)
  601. {
  602. // This is our last byte. Save low nibble from Dst.
  603. *pjDst = (BYTE) (((*pjDst) & 0x0F) |
  604. ((BYTE) (pulXlate[*pjSrc] << 4)));
  605. }
  606. break;
  607. }
  608. }
  609. if (--cy)
  610. {
  611. pjSrcHolder += psb->lDeltaSrc;
  612. pjDstHolder += psb->lDeltaDst;
  613. }
  614. else
  615. break;
  616. }
  617. }
  618. /******************************Public*Routine******************************\
  619. * vSrcCopyS16D4
  620. *
  621. *
  622. * History:
  623. * Sun 10-Feb-1991 -by- Patrick Haluptzok [patrickh]
  624. * Wrote it.
  625. \**************************************************************************/
  626. VOID vSrcCopyS16D4(PBLTINFO psb)
  627. {
  628. // We assume we are doing left to right top to bottom blting
  629. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D4 - direction not left to right");
  630. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D4 - direction not up to down");
  631. LONG iDst;
  632. PUSHORT pusSrc;
  633. PBYTE pjDst;
  634. LONG iDstEnd = psb->xDstStart + psb->cx;
  635. PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1);
  636. PUSHORT pusSrcHolder = (PUSHORT) (psb->pjSrc + (psb->xSrcStart << 1));
  637. ULONG cy = psb->cy;
  638. XLATE *pxlo = psb->pxlo;
  639. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  640. while(1)
  641. {
  642. pjDst = pjDstHolder;
  643. pusSrc = pusSrcHolder;
  644. iDst = psb->xDstStart;
  645. if (iDst & 0x00000001)
  646. {
  647. // Do the first byte if it's misaligned.
  648. *pjDst = (BYTE) ((*pjDst) & 0xF0) | ((BYTE) pxlo->ulTranslate(*(pusSrc++)));
  649. pjDst++;
  650. iDst++;
  651. }
  652. while(1)
  653. {
  654. if ((iDst + 1) < iDstEnd)
  655. {
  656. // Do a whole byte.
  657. *(pjDst++) = (BYTE) (pxlo->ulTranslate(*(pusSrc + 1)) |
  658. (pxlo->ulTranslate(*pusSrc) << 4));
  659. pusSrc += 2;
  660. iDst += 2;
  661. }
  662. else
  663. {
  664. // Check and see if we have a byte left to do.
  665. if (iDst < iDstEnd)
  666. {
  667. // This is our last byte. Save low nibble from Dst.
  668. *pjDst = (BYTE) ((*pjDst) & 0x0F) |
  669. ((BYTE) (pxlo->ulTranslate(*pusSrc) << 4));
  670. }
  671. break;
  672. }
  673. }
  674. if (--cy)
  675. {
  676. pusSrcHolder = (PUSHORT) (((PBYTE) pusSrcHolder) + psb->lDeltaSrc);
  677. pjDstHolder += psb->lDeltaDst;
  678. }
  679. else
  680. break;
  681. }
  682. }
  683. /******************************Public*Routine******************************\
  684. * vSrcCopyS24D4
  685. *
  686. *
  687. * History:
  688. * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh]
  689. * optimize color translation
  690. *
  691. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  692. * Wrote it.
  693. \**************************************************************************/
  694. #define Translate32to4(ulPelTemp) ((ulPelLast == ulPelTemp) ? jPelLast : (jPelLast = (BYTE) pxlo->ulTranslate(ulPelLast = ulPelTemp)))
  695. VOID vSrcCopyS24D4(PBLTINFO psb)
  696. {
  697. // We assume we are doing left to right top to bottom blting
  698. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D4 - direction not left to right");
  699. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D4 - direction not up to down");
  700. LONG iDst;
  701. ULONG ulPelTemp; // variable to build src RGB's in.
  702. PBYTE pjSrc;
  703. PBYTE pjDst;
  704. LONG iDstEnd = psb->xDstStart + psb->cx;
  705. PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1);
  706. PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart * 3);
  707. ULONG cy = psb->cy;
  708. XLATE *pxlo = psb->pxlo;
  709. ULONG ulPelLast; // This is the last pel in the src.
  710. BYTE jPelLast; // This is the last pel in the dst.
  711. BYTE jDstTmp;
  712. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  713. // Initialize the cache
  714. ulPelLast = *(pjSrcHolder + 2);
  715. ulPelLast = ulPelLast << 8;
  716. ulPelLast |= (ULONG) *(pjSrcHolder + 1);
  717. ulPelLast = ulPelLast << 8;
  718. ulPelLast |= (ULONG) *pjSrcHolder;
  719. jPelLast = (BYTE) (pxlo->ulTranslate(ulPelLast));
  720. // Just do it
  721. while(1)
  722. {
  723. pjDst = pjDstHolder;
  724. pjSrc = pjSrcHolder;
  725. iDst = psb->xDstStart;
  726. if (iDst & 0x00000001)
  727. {
  728. // Do the first byte if it's misaligned.
  729. ulPelTemp = *(pjSrc + 2);
  730. ulPelTemp = ulPelTemp << 8;
  731. ulPelTemp |= (ULONG) *(pjSrc + 1);
  732. ulPelTemp = ulPelTemp << 8;
  733. ulPelTemp |= (ULONG) *pjSrc;
  734. Translate32to4(ulPelTemp);
  735. *pjDst = (BYTE) ((*pjDst) & 0xF0) | jPelLast;
  736. pjDst++;
  737. iDst++;
  738. pjSrc += 3;
  739. }
  740. while(1)
  741. {
  742. if ((iDst + 1) < iDstEnd)
  743. {
  744. // Do a whole byte.
  745. ulPelTemp = (ULONG) *(pjSrc + 2);
  746. ulPelTemp = ulPelTemp << 8;
  747. ulPelTemp |= (ULONG) *(pjSrc + 1);
  748. ulPelTemp = ulPelTemp << 8;
  749. ulPelTemp |= (ULONG) *pjSrc;
  750. jDstTmp = Translate32to4(ulPelTemp);
  751. pjSrc += 3;
  752. ulPelTemp = (ULONG) *(pjSrc + 2);
  753. ulPelTemp = ulPelTemp << 8;
  754. ulPelTemp |= (ULONG) *(pjSrc + 1);
  755. ulPelTemp = ulPelTemp << 8;
  756. ulPelTemp |= (ULONG) *pjSrc;
  757. Translate32to4(ulPelTemp);
  758. *(pjDst++) = (BYTE) (jPelLast |
  759. (jDstTmp << 4));
  760. pjSrc += 3;
  761. iDst += 2;
  762. }
  763. else
  764. {
  765. // Check and see if we have a byte left to do.
  766. if (iDst < iDstEnd)
  767. {
  768. // This is our last byte. Save low nibble from Dst.
  769. ulPelTemp = (ULONG) *(pjSrc + 2);
  770. ulPelTemp = ulPelTemp << 8;
  771. ulPelTemp |= (ULONG) *(pjSrc + 1);
  772. ulPelTemp = ulPelTemp << 8;
  773. ulPelTemp |= (ULONG) *pjSrc;
  774. Translate32to4(ulPelTemp);
  775. *pjDst = (BYTE) ((*pjDst) & 0x0F) |
  776. ((BYTE) (jPelLast << 4));
  777. }
  778. // We are done with this scan
  779. break;
  780. }
  781. }
  782. if (--cy)
  783. {
  784. pjSrcHolder += psb->lDeltaSrc;
  785. pjDstHolder += psb->lDeltaDst;
  786. }
  787. else
  788. break;
  789. }
  790. }
  791. /******************************Public*Routine******************************\
  792. * vSrcCopyS32D4
  793. *
  794. *
  795. * History:
  796. * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh]
  797. * optimize color translation
  798. *
  799. * Sun 10-Feb-1991 -by- Patrick Haluptzok [patrickh]
  800. * Wrote it.
  801. \**************************************************************************/
  802. VOID vSrcCopyS32D4(PBLTINFO psb)
  803. {
  804. // We assume we are doing left to right top to bottom blting
  805. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D4 - direction not left to right");
  806. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D4 - direction not up to down");
  807. LONG iDst;
  808. PULONG pulSrc;
  809. PBYTE pjDst;
  810. LONG iDstEnd = psb->xDstStart + psb->cx;
  811. PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1);
  812. PULONG pulSrcHolder = (PULONG) (psb->pjSrc + (psb->xSrcStart << 2));
  813. ULONG cy = psb->cy;
  814. XLATE *pxlo = psb->pxlo;
  815. ULONG ulPelTemp;
  816. ULONG ulPelLast; // This is the last pel in the src.
  817. BYTE jPelLast; // This is the last pel in the dst.
  818. BYTE jDstTmp;
  819. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  820. // Initialize the cache
  821. ulPelLast = *pulSrcHolder;
  822. jPelLast = (BYTE) (pxlo->ulTranslate(ulPelLast));
  823. // Just do it
  824. while(1)
  825. {
  826. pjDst = pjDstHolder;
  827. pulSrc = pulSrcHolder;
  828. iDst = psb->xDstStart;
  829. if (iDst & 0x00000001)
  830. {
  831. // Do the first byte if it's misaligned.
  832. ulPelTemp = *(pulSrc++);
  833. Translate32to4(ulPelTemp);
  834. *pjDst = (BYTE) ((*pjDst) & 0xF0) | jPelLast;
  835. pjDst++;
  836. iDst++;
  837. }
  838. while(1)
  839. {
  840. if ((iDst + 1) < iDstEnd)
  841. {
  842. // Do a whole byte.
  843. ulPelTemp = *(pulSrc++);
  844. jDstTmp = Translate32to4(ulPelTemp);
  845. ulPelTemp = *(pulSrc++);
  846. Translate32to4(ulPelTemp);
  847. *(pjDst++) = (BYTE) (jPelLast |
  848. (jDstTmp << 4));
  849. iDst += 2;
  850. }
  851. else
  852. {
  853. // Check and see if we have a byte left to do.
  854. if (iDst < iDstEnd)
  855. {
  856. // This is our last byte. Save low nibble from Dst.
  857. ulPelTemp = *pulSrc;
  858. Translate32to4(ulPelTemp);
  859. *pjDst = (BYTE) ((*pjDst) & 0x0F) |
  860. ((BYTE) (jPelLast << 4));
  861. }
  862. break;
  863. }
  864. }
  865. if (--cy)
  866. {
  867. pulSrcHolder = (PULONG) (((PBYTE) pulSrcHolder) + psb->lDeltaSrc);
  868. pjDstHolder += psb->lDeltaDst;
  869. }
  870. else
  871. break;
  872. }
  873. }