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.

1063 lines
29 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: srcblt8.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt to a 8 bit/pel
  5. * DIB surface.
  6. *
  7. * Created: 07-Feb-1991 19:27:49
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * NB: The function <vSrcCopySRLE8D8()> was removed from here on 22 Jan 1992
  11. * and placed in the module <rle8blt.cxx>. - Andrew Milton (w-andym)
  12. *
  13. * Copyright (c) 1990-1999 Microsoft Corporation
  14. *
  15. \**************************************************************************/
  16. #include "precomp.hxx"
  17. /*******************Public*Routine*****************\
  18. * vSrcCopyS1D8
  19. *
  20. * There are three main loops in this function.
  21. *
  22. * The first loop deals with the full two dwords part of
  23. * the Dst while fetching/shifting the matching 8 bits
  24. * from the Src.
  25. *
  26. * The second loop deals with the left most strip
  27. * of the partial two dwords in Dst.
  28. *
  29. * The third loop deals with the right most strip
  30. * of the partial two dwords in Dst.
  31. *
  32. * We use a 16 entry dword table to expand the
  33. * Src bits. We walk thru Src one byte at a time
  34. * and expand to Dst two Dwords at a time. Dst Dword
  35. * is aligned.
  36. *
  37. * History:
  38. * 17-Oct-1994 -by- Lingyun Wang [lingyunw]
  39. * Wrote it.
  40. *
  41. \**************************************************/
  42. VOID vSrcCopyS1D8(PBLTINFO psb)
  43. {
  44. BYTE jSrc; // holds a source byte
  45. BYTE jDst; // holds a dest byte
  46. INT iSrc; // bit position in the first Src byte
  47. INT iDst; // bit position in the first 8 Dst bytes
  48. PBYTE pjDst; // pointer to the Src bytes
  49. PBYTE pjSrc; // pointer to the Dst bytes
  50. LONG xSrcEnd = psb->xSrcEnd;
  51. LONG cy; // number of rows
  52. LONG cx; // number of pixels
  53. BYTE jAlignL; // alignment bits to the left
  54. BYTE jAlignR; // alignment bits to the right
  55. LONG cFullBytes; //number of full 8 bytes dealed with
  56. BOOL bNextByte;
  57. LONG xDstEnd;
  58. LONG lDeltaDst;
  59. LONG lDeltaSrc;
  60. BYTE jB = (BYTE) (psb->pxlo->pulXlate[0]);
  61. BYTE jF = (BYTE) (psb->pxlo->pulXlate[1]);
  62. ULONG ulB = (ULONG)(psb->pxlo->pulXlate[0]);
  63. ULONG ulF = (ULONG)(psb->pxlo->pulXlate[1]);
  64. ULONG aulTable[16];
  65. UCHAR aucTable[2];
  66. INT count;
  67. INT i;
  68. BOOL bNextSrc=TRUE;
  69. // We assume we are doing left to right top to bottom blting
  70. ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D8 - direction not left to right");
  71. ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D8 - direction not up to down");
  72. ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
  73. //DbgPrint ("vsrccopys1d8\n");
  74. // Generate aucTable
  75. aucTable[0] = jB;
  76. aucTable[1] = jF;
  77. // Generate ulTable
  78. ULONG ulVal = ulB;
  79. ulVal = ulVal | (ulVal << 8);
  80. ulVal = ulVal | (ulVal << 16);
  81. aulTable[0] = ulVal; // 0 0 0 0
  82. ulVal <<= 8;
  83. ulVal |= ulF;
  84. aulTable[8] = ulVal; // 0 0 0 1
  85. ulVal <<= 8;
  86. ulVal |= ulB;
  87. aulTable[4] = ulVal; // 0 0 1 0
  88. ulVal <<= 8;
  89. ulVal |= ulF;
  90. aulTable[10] = ulVal; // 0 1 0 1
  91. ulVal <<= 8;
  92. ulVal |= ulB;
  93. aulTable[5] = ulVal; // 1 0 1 0
  94. ulVal <<= 8;
  95. ulVal |= ulB;
  96. aulTable[ 2] = ulVal; // 0 1 0 0
  97. ulVal <<= 8;
  98. ulVal |= ulF;
  99. aulTable[ 9] = ulVal; // 1 0 0 1
  100. ulVal <<= 8;
  101. ulVal |= ulF;
  102. aulTable[12] = ulVal; // 0 0 1 1
  103. ulVal <<= 8;
  104. ulVal |= ulF;
  105. aulTable[14] = ulVal; // 0 1 1 1
  106. ulVal <<= 8;
  107. ulVal |= ulF;
  108. aulTable[15] = ulVal; // 1 1 1 1
  109. ulVal <<= 8;
  110. ulVal |= ulB;
  111. aulTable[ 7] = ulVal; // 1 1 1 0
  112. ulVal <<= 8;
  113. ulVal |= ulF;
  114. aulTable[11] = ulVal; // 1 1 0 1
  115. ulVal <<= 8;
  116. ulVal |= ulF;
  117. aulTable[13] = ulVal; // 1 0 1 1
  118. ulVal <<= 8;
  119. ulVal |= ulB;
  120. aulTable[06] = ulVal; // 0 1 1 0
  121. ulVal <<= 8;
  122. ulVal |= ulB;
  123. aulTable[ 3] = ulVal; // 1 1 0 0
  124. ulVal <<= 8;
  125. ulVal |= ulB;
  126. aulTable[ 1] = ulVal; // 1 0 0 0
  127. //Get Src and Dst start positions
  128. iSrc = psb->xSrcStart & 0x0007;
  129. iDst = psb->xDstStart & 0x0007;
  130. // Checking alignment
  131. // If Src starting point is ahead of Dst
  132. if (iSrc < iDst)
  133. jAlignL = 8 - (iDst - iSrc);
  134. // If Dst starting point is ahead of Src
  135. else
  136. jAlignL = iSrc - iDst;
  137. jAlignR = 8 - jAlignL;
  138. cx=psb->cx;
  139. xDstEnd = psb->xDstStart + cx;
  140. lDeltaDst = psb->lDeltaDst;
  141. lDeltaSrc = psb->lDeltaSrc;
  142. // check if there is a next 8 bytes
  143. bNextByte = !((xDstEnd>>3) ==
  144. (psb->xDstStart>>3));
  145. // if Src and Dst are aligned, use a separete loop
  146. // to obtain better performance;
  147. // If not, we shift the Src bytes to match with
  148. // the Dst 8 bytes (2 dwords) one at a time
  149. if (bNextByte)
  150. {
  151. long iStrideSrc;
  152. long iStrideDst;
  153. PBYTE pjSrcEnd; //pointer to the Last full Src byte
  154. // Get first Dst full 8 bytes (2 dwords expanding from
  155. // 1 Src byte)
  156. pjDst = psb->pjDst + ((psb->xDstStart+7)&~0x07);
  157. // Get the Src byte that matches the first Dst
  158. // full 8 bytes
  159. pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
  160. //Get the number of full bytes
  161. cFullBytes = (xDstEnd>>3)-((psb->xDstStart+7)>>3);
  162. //the increment to the full byte on the next scan line
  163. iStrideDst = lDeltaDst - cFullBytes*8;
  164. iStrideSrc = lDeltaSrc - cFullBytes;
  165. // deal with our special case
  166. cy = psb->cy;
  167. if (!jAlignL)
  168. {
  169. while (cy--)
  170. {
  171. pjSrcEnd = pjSrc+cFullBytes;
  172. while (pjSrc != pjSrcEnd)
  173. {
  174. jSrc = *pjSrc++;
  175. *(PULONG) (pjDst + 0) = aulTable[jSrc >> 4];
  176. *(PULONG) (pjDst + 4) = aulTable[jSrc & 0X0F];
  177. pjDst +=8;
  178. }
  179. pjDst += iStrideDst;
  180. pjSrc += iStrideSrc;
  181. }
  182. } //end of if (!jAlignL)
  183. else // if not aligned
  184. {
  185. BYTE jRem; //remainder
  186. while (cy--)
  187. {
  188. jRem = *pjSrc << jAlignL;
  189. pjSrcEnd = pjSrc+cFullBytes;
  190. while (pjSrc != pjSrcEnd)
  191. {
  192. jSrc = ((*(++pjSrc))>>jAlignR) | jRem;
  193. *(PULONG) (pjDst + 0) = aulTable[jSrc >> 4];
  194. *(PULONG) (pjDst + 4) = aulTable[jSrc & 0X0F];
  195. pjDst +=8;
  196. //next remainder
  197. jRem = *pjSrc << jAlignL;
  198. }
  199. pjDst += iStrideDst;
  200. pjSrc += iStrideSrc;
  201. }
  202. } //else
  203. } //if
  204. // End of our dealing with the full bytes
  205. //Deal with the starting pixels
  206. if (!bNextByte)
  207. {
  208. count = cx;
  209. bNextSrc = ((iSrc + cx) > 8);
  210. }
  211. else
  212. count = 8-iDst;
  213. if (iDst | !bNextByte)
  214. {
  215. PBYTE pjDstTemp;
  216. PBYTE pjDstEnd;
  217. pjDst = psb->pjDst + psb->xDstStart;
  218. pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
  219. cy = psb->cy;
  220. if (iSrc > iDst)
  221. {
  222. if (bNextSrc)
  223. {
  224. while (cy--)
  225. {
  226. jSrc = *pjSrc << jAlignL;
  227. jSrc |= *(pjSrc+1) >> jAlignR;
  228. jSrc <<= iDst;
  229. pjDstTemp = pjDst;
  230. pjDstEnd = pjDst + count;
  231. while (pjDstTemp != pjDstEnd)
  232. {
  233. * (pjDstTemp++) = aucTable[(jSrc&0x80)>>7];
  234. jSrc <<= 1;
  235. }
  236. pjDst += lDeltaDst;
  237. pjSrc += lDeltaSrc;
  238. }
  239. }
  240. else // if (!bNextSrc)
  241. {
  242. while (cy--)
  243. {
  244. jSrc = *pjSrc << jAlignL;
  245. jSrc <<= iDst;
  246. pjDstTemp = pjDst;
  247. pjDstEnd = pjDst + count;
  248. while (pjDstTemp != pjDstEnd)
  249. {
  250. * (pjDstTemp++) = aucTable[(jSrc&0x80)>>7];
  251. jSrc <<= 1;
  252. }
  253. pjDst += lDeltaDst;
  254. pjSrc += lDeltaSrc;
  255. }
  256. } //else
  257. } // if
  258. else //if (iSrc <= iDst)
  259. {
  260. while (cy--)
  261. {
  262. jSrc = *pjSrc << iSrc;
  263. pjDstTemp = pjDst;
  264. pjDstEnd = pjDst + count;
  265. while (pjDstTemp != pjDstEnd)
  266. {
  267. *(pjDstTemp++) = aucTable[(jSrc&0x80)>>7];
  268. jSrc <<= 1;
  269. }
  270. pjDst += lDeltaDst;
  271. pjSrc += lDeltaSrc;
  272. }
  273. }
  274. } //if
  275. // Deal with the ending pixels
  276. if ((xDstEnd & 0x0007)
  277. && bNextByte)
  278. {
  279. PBYTE pjDstTemp;
  280. PBYTE pjDstEnd;
  281. // Get the last partial bytes on the
  282. // scan line
  283. pjDst = psb->pjDst+(xDstEnd&~0x07);
  284. // Get the Src byte that matches the
  285. // right partial Dst 8 bytes
  286. pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
  287. // Get the ending position in the last
  288. // Src and Dst bytes
  289. iSrc = (psb->xSrcEnd-1) & 0x0007;
  290. iDst = (xDstEnd-1) & 0x0007;
  291. count = iDst+1;
  292. cy = psb->cy;
  293. if (iSrc >= iDst)
  294. {
  295. while (cy--)
  296. {
  297. jSrc = *pjSrc << jAlignL;
  298. pjDstTemp = pjDst;
  299. pjDstEnd = pjDst + count;
  300. while (pjDstTemp != pjDstEnd)
  301. {
  302. * (pjDstTemp++) = aucTable[(jSrc&0x80)>>7];
  303. jSrc <<= 1;
  304. }
  305. pjDst += lDeltaDst;
  306. pjSrc += lDeltaSrc;
  307. }
  308. }
  309. else //if (iSrc < iDst)
  310. {
  311. while (cy--)
  312. {
  313. jSrc = *(pjSrc-1) << jAlignL;
  314. ASSERTGDI(pjSrc <= (psb->pjSrc+lDeltaSrc*(psb->cy-cy-1)+((psb->xSrcEnd-1)>>3)),
  315. "vSrcCopyS1D8 - pjSrc passed the last byte");
  316. jSrc |= *pjSrc >> jAlignR;
  317. pjDstTemp = pjDst;
  318. pjDstEnd = pjDst + count;
  319. while (pjDstTemp != pjDstEnd)
  320. {
  321. *(pjDstTemp++) = aucTable[(jSrc&0x80)>>7];
  322. jSrc <<= 1;
  323. }
  324. pjDst += lDeltaDst;
  325. pjSrc += lDeltaSrc;
  326. }
  327. }
  328. } //if
  329. }
  330. /******************************Public*Routine******************************\
  331. * vSrcCopyS4D8
  332. *
  333. *
  334. * History:
  335. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  336. * Wrote it.
  337. \**************************************************************************/
  338. VOID vSrcCopyS4D8(PBLTINFO psb)
  339. {
  340. // We assume we are doing left to right top to bottom blting
  341. ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D8 - direction not left to right");
  342. ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D8 - direction not up to down");
  343. BYTE jSrc;
  344. LONG i;
  345. PBYTE pjDst;
  346. PBYTE pjSrc;
  347. PBYTE pjDstHolder = psb->pjDst + psb->xDstStart;
  348. PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart >> 1);
  349. ULONG cx = psb->xSrcEnd - psb->xSrcStart;
  350. ULONG cy = psb->cy;
  351. PULONG pulTranslate = psb->pxlo->pulXlate;
  352. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  353. do {
  354. pjDst = pjDstHolder;
  355. pjSrc = pjSrcHolder;
  356. if ((psb->xSrcStart & 0x1) != 0)
  357. {
  358. jSrc = *(pjSrc++);
  359. }
  360. for (i = psb->xSrcStart; i < psb->xSrcEnd; i += 1)
  361. {
  362. if ((i & 0x1) != 0)
  363. {
  364. *(pjDst++) = (BYTE) pulTranslate[jSrc & 0x0F];
  365. }
  366. else
  367. {
  368. jSrc = *(pjSrc++);
  369. *(pjDst++) = (BYTE) pulTranslate[((ULONG) (jSrc & 0xF0)) >> 4];
  370. }
  371. }
  372. pjSrcHolder += psb->lDeltaSrc;
  373. pjDstHolder += psb->lDeltaDst;
  374. cy -= 1;
  375. } while(cy > 0);
  376. }
  377. /******************************Public*Routine******************************\
  378. * vSrcCopyS8D8
  379. *
  380. *
  381. * History:
  382. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  383. * Wrote it.
  384. \**************************************************************************/
  385. VOID vSrcCopyS8D8(PBLTINFO psb)
  386. {
  387. // We assume we are doing left to right top to bottom blting.
  388. // If it was on the same surface we would be doing the identity case.
  389. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D8 - direction not left to right");
  390. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D8 - direction not up to down");
  391. // These are our holding variables
  392. #if MESSAGE_BLT
  393. DbgPrint("Now entering vSrcCopyS8D8\n");
  394. #endif
  395. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  396. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  397. ULONG cx = psb->cx;
  398. ULONG cy = psb->cy;
  399. PULONG pulXlate = psb->pxlo->pulXlate;
  400. LONG lSrcSkip = psb->lDeltaSrc - cx;
  401. LONG lDstSkip = psb->lDeltaDst - cx;
  402. ULONG cStartPixels;
  403. ULONG cMiddlePixels;
  404. ULONG cEndPixels;
  405. ULONG i;
  406. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  407. // 'cStartPixels' is the minimum number of 1-byte pixels we'll have to
  408. // write before we have dword alignment on the destination:
  409. cStartPixels = (ULONG)((-((LONG_PTR) pjDst)) & 3);
  410. if (cStartPixels > cx)
  411. {
  412. cStartPixels = cx;
  413. }
  414. cx -= cStartPixels;
  415. cMiddlePixels = cx >> 2;
  416. cEndPixels = cx & 3;
  417. while(1)
  418. {
  419. // Write pixels a byte at a time until we're 'dword' aligned on
  420. // the destination:
  421. for (i = cStartPixels; i != 0; i--)
  422. {
  423. *pjDst++ = (BYTE) pulXlate[*pjSrc++];
  424. }
  425. // Now write pixels a dword at a time. This is almost a 4x win
  426. // over doing byte writes if we're writing to frame buffer memory
  427. // over the PCI bus on Pentium class systems, because the PCI
  428. // write throughput is so slow:
  429. for (i = cMiddlePixels; i != 0; i--)
  430. {
  431. *((ULONG*) (pjDst)) = (pulXlate[*(pjSrc)])
  432. | (pulXlate[*(pjSrc + 1)] << 8)
  433. | (pulXlate[*(pjSrc + 2)] << 16)
  434. | (pulXlate[*(pjSrc + 3)] << 24);
  435. pjDst += 4;
  436. pjSrc += 4;
  437. }
  438. // Take care of the end alignment:
  439. for (i = cEndPixels; i != 0; i--)
  440. {
  441. *pjDst++ = (BYTE) pulXlate[*pjSrc++];
  442. }
  443. if (--cy == 0)
  444. break;
  445. pjSrc += lSrcSkip;
  446. pjDst += lDstSkip;
  447. }
  448. }
  449. /******************************Public*Routine******************************\
  450. * vSrcCopyS8D8IdentityLtoR
  451. *
  452. * This is the special case no translate blting. All the SmDn should have
  453. * them if m==n. Identity xlates only occur amoung matching format bitmaps
  454. * and screens.
  455. *
  456. * History:
  457. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  458. * Wrote it.
  459. \**************************************************************************/
  460. VOID vSrcCopyS8D8IdentityLtoR(PBLTINFO psb)
  461. {
  462. #if MESSAGE_BLT
  463. DbgPrint("Now entering s8d8 identity L to R\n");
  464. #endif
  465. ASSERTGDI(psb->xDir == 1, "S8D8identLtoR has wrong value xDir");
  466. // These are our holding variables
  467. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  468. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  469. ULONG cx = psb->cx;
  470. ULONG cy = psb->cy;
  471. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  472. #if MESSAGE_BLT
  473. DbgPrint("xdir: %ld cy: %lu xSrcStart %lu xDstStart %lu xSrcEnd %lu cx %lu\n",
  474. psb->xDir, cy, psb->xSrcStart, psb->xDstStart, psb->xSrcEnd, cx);
  475. #endif
  476. do {
  477. if(psb->fSrcAlignedRd)
  478. vSrcAlignCopyMemory(pjDst,pjSrc,cx);
  479. else
  480. RtlMoveMemory((PVOID)pjDst, (PVOID)pjSrc, cx);
  481. pjSrc += psb->lDeltaSrc;
  482. pjDst += psb->lDeltaDst;
  483. cy -= 1;
  484. } while(cy > 0);
  485. }
  486. /******************************Public*Routine******************************\
  487. * vSrcCopyS8D8IdentityRtoL
  488. *
  489. * This is the special case no translate blting. All the SmDn should have
  490. * them if m==n. Identity xlates only occur amoung matching format bitmaps
  491. * and screens.
  492. *
  493. * History:
  494. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  495. * Wrote it.
  496. \**************************************************************************/
  497. VOID vSrcCopyS8D8IdentityRtoL(PBLTINFO psb)
  498. {
  499. #if MESSAGE_BLT
  500. DbgPrint("Now entering s8d8 identity R to L\n");
  501. #endif
  502. ASSERTGDI(psb->xDir == -1, "S8D8identR to L has wrong value xDir");
  503. // These are our holding variables
  504. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  505. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  506. ULONG cx = psb->cx;
  507. ULONG cy = psb->cy;
  508. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  509. #if MESSAGE_BLT
  510. DbgPrint("xdir: %ld cy: %lu xSrcStart %lu xDstStart %lu xSrcEnd %lu cx %lu\n",
  511. psb->xDir, cy, psb->xSrcStart, psb->xDstStart, psb->xSrcEnd, cx);
  512. #endif
  513. pjSrc = pjSrc - cx + 1;
  514. pjDst = pjDst - cx + 1;
  515. do {
  516. if(psb->fSrcAlignedRd)
  517. vSrcAlignCopyMemory(pjDst,pjSrc,cx);
  518. else
  519. RtlMoveMemory((PVOID)pjDst, (PVOID)pjSrc, cx);
  520. pjSrc += psb->lDeltaSrc;
  521. pjDst += psb->lDeltaDst;
  522. cy -= 1;
  523. } while(cy > 0);
  524. }
  525. /**************************************************************************\
  526. * vSrcCopyS16D8
  527. * Use translation table from 555RGB to surface palette. Not as accurare
  528. * as full nearest search but much faster.
  529. *
  530. * Arguments:
  531. *
  532. * psb - bitblt info
  533. *
  534. * Return Value:
  535. *
  536. * none
  537. *
  538. * History:
  539. *
  540. * 2/24/1997 Mark Enstrom [marke]
  541. *
  542. \**************************************************************************/
  543. VOID vSrcCopyS16D8(PBLTINFO psb)
  544. {
  545. // We assume we are doing left to right top to bottom blting
  546. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D8 - direction not left to right");
  547. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D8 - direction not up to down");
  548. // These are our holding variables
  549. ULONG cx = psb->cx;
  550. ULONG cy = psb->cy;
  551. XLATE *pxlo = psb->pxlo;
  552. PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (2 * psb->xSrcStart));
  553. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  554. PBYTE pxlate555 = NULL;
  555. PUSHORT pusSrcTemp;
  556. PBYTE pjDstTemp;
  557. ULONG cStartPixels;
  558. ULONG cMiddlePixels;
  559. ULONG cEndPixels;
  560. INT i;
  561. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  562. // 'cStartPixels' is the minimum number of 1-byte pixels we'll have to
  563. // write before we have dword alignment on the destination:
  564. cStartPixels = (ULONG)((-((LONG_PTR) pjDst)) & 3);
  565. if (cStartPixels > cx)
  566. {
  567. cStartPixels = cx;
  568. }
  569. cx -= cStartPixels;
  570. cMiddlePixels = cx >> 2;
  571. cEndPixels = cx & 3;
  572. PFN_XLATE_RGB_TO_PALETTE pfnXlate = XLATEOBJ_ulIndexToPalSurf;
  573. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  574. ASSERTGDI(((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).bValid(),"vSrcCopyS16D8: Src palette not valid\n");
  575. pxlate555 = XLATEOBJ_pGetXlate555(pxlo);
  576. if (pxlate555 != NULL)
  577. {
  578. ULONG ulPalSrcFlags = ((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).flPal();
  579. if (ulPalSrcFlags & PAL_RGB16_555)
  580. {
  581. pfnXlate = XLATEOBJ_RGB16_555ToPalSurf;
  582. }
  583. else if (ulPalSrcFlags & PAL_RGB16_565)
  584. {
  585. pfnXlate = XLATEOBJ_RGB16_565ToPalSurf;
  586. }
  587. while(1)
  588. {
  589. // Write pixels a byte at a time until we're 'dword' aligned on
  590. // the destination:
  591. pjDstTemp = pjDst;
  592. pusSrcTemp = pusSrc;
  593. for (i = cStartPixels; i != 0; i--)
  594. {
  595. *pjDstTemp++ = (*pfnXlate)(pxlo,pxlate555,*pusSrcTemp++);
  596. }
  597. // Now write pixels a dword at a time. This is almost a 4x win
  598. // over doing byte writes if we're writing to frame buffer memory
  599. // over the PCI bus on Pentium class systems, because the PCI
  600. // write throughput is so slow:
  601. for (i = cMiddlePixels; i != 0; i--)
  602. {
  603. *((ULONG*) (pjDstTemp)) = (*pfnXlate)(pxlo,pxlate555,*pusSrcTemp)
  604. | (((*pfnXlate)(pxlo,pxlate555,*(pusSrcTemp+1))) << 8)
  605. | (((*pfnXlate)(pxlo,pxlate555,*(pusSrcTemp+2)))<< 16)
  606. | (((*pfnXlate)(pxlo,pxlate555,*(pusSrcTemp+3)))<< 24);
  607. pjDstTemp += 4;
  608. pusSrcTemp += 4;
  609. }
  610. // Take care of the end alignment:
  611. for (i = cEndPixels; i != 0; i--)
  612. {
  613. *pjDstTemp++ = (*pfnXlate)(pxlo,pxlate555,*pusSrcTemp++);
  614. }
  615. if (--cy == 0)
  616. break;
  617. pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
  618. pjDst += psb->lDeltaDst;
  619. }
  620. }
  621. }
  622. /**************************************************************************\
  623. * vSrcCopyS24D8
  624. * Use translation table from 555RGB to surface palette. Not as accurare
  625. * as full nearest search but 600 times faster.
  626. *
  627. * Arguments:
  628. *
  629. * psb - bitblt info
  630. *
  631. * Return Value:
  632. *
  633. * none
  634. *
  635. * History:
  636. *
  637. * 2/24/1997 Mark Enstrom [marke]
  638. *
  639. \**************************************************************************/
  640. VOID vSrcCopyS24D8(PBLTINFO psb)
  641. {
  642. //
  643. // We assume we are doing left to right top to bottom blting
  644. //
  645. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D8 - direction not left to right");
  646. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D8 - direction not up to down");
  647. ULONG cx = psb->cx;
  648. ULONG cy = psb->cy;
  649. PBYTE pjSrc = psb->pjSrc + (3 * psb->xSrcStart);
  650. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  651. PBYTE pjDstEndY = pjDst + cy * psb->lDeltaDst;
  652. PBYTE pjDstEnd;
  653. XLATE *pxlo = psb->pxlo;
  654. PBYTE pxlate555 = NULL;
  655. PBYTE pjSrcTemp;
  656. PBYTE pjDstTemp;
  657. BYTE r, g, b;
  658. BYTE PaletteIndex1,PaletteIndex2,PaletteIndex3,PaletteIndex4;
  659. ULONG cStartPixels;
  660. ULONG cMiddlePixels;
  661. ULONG cEndPixels;
  662. INT i;
  663. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  664. ASSERTGDI(((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).bValid(),"vSrcCopyS24D8: Src palette not valid\n");
  665. // 'cStartPixels' is the minimum number of 1-byte pixels we'll have to
  666. // write before we have dword alignment on the destination:
  667. cStartPixels = (ULONG)((-((LONG_PTR) pjDst)) & 3);
  668. if (cStartPixels > cx)
  669. {
  670. cStartPixels = cx;
  671. }
  672. cx -= cStartPixels;
  673. cMiddlePixels = cx >> 2;
  674. cEndPixels = cx & 3;
  675. pxlate555 = XLATEOBJ_pGetXlate555(pxlo);
  676. if (pxlate555)
  677. {
  678. while(1)
  679. {
  680. // Write pixels a byte at a time until we're 'dword' aligned on
  681. // the destination:
  682. pjDstTemp = pjDst;
  683. pjSrcTemp = pjSrc;
  684. for (i = cStartPixels; i != 0; i--)
  685. {
  686. b = *(pjSrcTemp );
  687. g = *(pjSrcTemp+1);
  688. r = *(pjSrcTemp+2);
  689. *pjDstTemp = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  690. pjDstTemp ++;
  691. pjSrcTemp += 3;
  692. }
  693. // Now write pixels a dword at a time. This is almost a 4x win
  694. // over doing byte writes if we're writing to frame buffer memory
  695. // over the PCI bus on Pentium class systems, because the PCI
  696. // write throughput is so slow:
  697. for (i = cMiddlePixels; i != 0; i--)
  698. {
  699. b = *(pjSrcTemp );
  700. g = *(pjSrcTemp+1);
  701. r = *(pjSrcTemp+2);
  702. PaletteIndex1 = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  703. pjSrcTemp += 3;
  704. b = *(pjSrcTemp );
  705. g = *(pjSrcTemp+1);
  706. r = *(pjSrcTemp+2);
  707. PaletteIndex2 = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  708. pjSrcTemp += 3;
  709. b = *(pjSrcTemp );
  710. g = *(pjSrcTemp+1);
  711. r = *(pjSrcTemp+2);
  712. PaletteIndex3 = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  713. pjSrcTemp += 3;
  714. b = *(pjSrcTemp );
  715. g = *(pjSrcTemp+1);
  716. r = *(pjSrcTemp+2);
  717. PaletteIndex4 = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  718. pjSrcTemp += 3;
  719. *((ULONG*) (pjDstTemp)) = PaletteIndex1
  720. | (PaletteIndex2 << 8)
  721. | (PaletteIndex3 << 16)
  722. | (PaletteIndex4 << 24);
  723. pjDstTemp += 4;
  724. }
  725. // Take care of the end alignment:
  726. for (i = cEndPixels; i != 0; i--)
  727. {
  728. b = *(pjSrcTemp );
  729. g = *(pjSrcTemp+1);
  730. r = *(pjSrcTemp+2);
  731. *pjDstTemp = XLATEOBJ_RGB32ToPalSurf(pxlo,pxlate555,(b << 16) | (g << 8) | r);
  732. pjDstTemp ++;
  733. pjSrcTemp += 3;
  734. }
  735. if (--cy == 0)
  736. break;
  737. pjSrc += psb->lDeltaSrc;
  738. pjDst += psb->lDeltaDst;
  739. }
  740. }
  741. }
  742. /**************************************************************************\
  743. * vSrcCopyS32D8
  744. * Use translation table from 555RGB to surface palette. Not as accurare
  745. * as full nearest search but 600 times faster.
  746. *
  747. * Arguments:
  748. *
  749. * psb - bitblt info
  750. *
  751. * Return Value:
  752. *
  753. * none
  754. *
  755. * History:
  756. *
  757. * 2/24/1997 Mark Enstrom [marke]
  758. *
  759. \**************************************************************************/
  760. VOID vSrcCopyS32D8(PBLTINFO psb)
  761. {
  762. // We assume we are doing left to right top to bottom blting
  763. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D8 - direction not left to right");
  764. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D8 - direction not up to down");
  765. PULONG pulSrcTemp;
  766. PBYTE pjDstTemp;
  767. PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
  768. PBYTE pjDst = psb->pjDst + psb->xDstStart;
  769. ULONG cx = psb->cx;
  770. ULONG cy = psb->cy;
  771. XLATE *pxlo = psb->pxlo;
  772. PBYTE pxlate555 = NULL;
  773. ULONG cStartPixels;
  774. ULONG cMiddlePixels;
  775. ULONG cEndPixels;
  776. INT i;
  777. PFN_XLATE_RGB_TO_PALETTE pfnXlate = XLATEOBJ_ulIndexToPalSurf;
  778. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  779. //
  780. // match to the destination palette
  781. //
  782. ASSERTGDI(((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).bValid(),"vSrcCopyS32D8: Src palette not valid\n");
  783. // 'cStartPixels' is the minimum number of 1-byte pixels we'll have to
  784. // write before we have dword alignment on the destination:
  785. cStartPixels = (ULONG)((-((LONG_PTR) pjDst)) & 3);
  786. if (cStartPixels > cx)
  787. {
  788. cStartPixels = cx;
  789. }
  790. cx -= cStartPixels;
  791. cMiddlePixels = cx >> 2;
  792. cEndPixels = cx & 3;
  793. //
  794. // determine source palette type, use specialized code for RGB and BGR formats
  795. //
  796. ULONG ulPalSrcFlags = ((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).flPal();
  797. if (ulPalSrcFlags & PAL_RGB)
  798. {
  799. pfnXlate = XLATEOBJ_RGB32ToPalSurf;
  800. }
  801. else if (ulPalSrcFlags & PAL_BGR)
  802. {
  803. pfnXlate = XLATEOBJ_BGR32ToPalSurf;
  804. }
  805. //
  806. // get 555 to palete translate table
  807. //
  808. pxlate555 = XLATEOBJ_pGetXlate555(pxlo);
  809. if (pxlate555 != NULL)
  810. {
  811. //
  812. // translate bitmap
  813. //
  814. while(1)
  815. {
  816. // Write pixels a byte at a time until we're 'dword' aligned on
  817. // the destination:
  818. pjDstTemp = pjDst;
  819. pulSrcTemp = pulSrc;
  820. for (i = cStartPixels; i != 0; i--)
  821. {
  822. *pjDstTemp++ = (*pfnXlate)(pxlo,pxlate555,*pulSrcTemp++);
  823. }
  824. // Now write pixels a dword at a time. This is almost a 4x win
  825. // over doing byte writes if we're writing to frame buffer memory
  826. // over the PCI bus on Pentium class systems, because the PCI
  827. // write throughput is so slow:
  828. for (i = cMiddlePixels; i != 0; i--)
  829. {
  830. *((ULONG*) (pjDstTemp)) = (*pfnXlate)(pxlo,pxlate555,*pulSrcTemp)
  831. | (((*pfnXlate)(pxlo,pxlate555,*(pulSrcTemp+1))) << 8)
  832. | (((*pfnXlate)(pxlo,pxlate555,*(pulSrcTemp+2)))<< 16)
  833. | (((*pfnXlate)(pxlo,pxlate555,*(pulSrcTemp+3)))<< 24);
  834. pjDstTemp += 4;
  835. pulSrcTemp += 4;
  836. }
  837. // Take care of the end alignment:
  838. for (i = cEndPixels; i != 0; i--)
  839. {
  840. *pjDstTemp++ = (*pfnXlate)(pxlo,pxlate555,*pulSrcTemp++);
  841. }
  842. if (--cy == 0)
  843. break;
  844. pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
  845. pjDst += psb->lDeltaDst;
  846. }
  847. }
  848. }