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.

5801 lines
126 KiB

  1. /*++
  2. Copyright (c) 1990-1991 Microsoft Corporation
  3. Module Name:
  4. htstret.c
  5. Abstract:
  6. This module contains stretching functions to setup the parameters for
  7. compress or expanding the bitmap.
  8. Author:
  9. 24-Jan-1991 Thu 10:08:11 created -by- Daniel Chou (danielc)
  10. [Environment:]
  11. GDI Device Driver - Halftone.
  12. [Notes:]
  13. Revision History:
  14. --*/
  15. #define DBGP_VARNAME dbgpHTStret
  16. #include "htp.h"
  17. #include "htmapclr.h"
  18. #include "htpat.h"
  19. #include "htalias.h"
  20. #include "htrender.h"
  21. #include "htgetbmp.h"
  22. #include "htsetbmp.h"
  23. #include "htstret.h"
  24. #include "limits.h"
  25. #define DBGP_PSD 0x00000001
  26. #define DBGP_EXP 0x00000002
  27. #define DBGP_AAHT_MEM 0x00000004
  28. #define DBGP_EXPAND 0x00000008
  29. #define DBGP_SRK2 0x00000010
  30. DEF_DBGPVAR(BIT_IF(DBGP_PSD, 0) |
  31. BIT_IF(DBGP_EXP, 0) |
  32. BIT_IF(DBGP_AAHT_MEM, 0) |
  33. BIT_IF(DBGP_EXPAND, 0) |
  34. BIT_IF(DBGP_SRK2, 0))
  35. CONST WORD BGR555Idx[] = {
  36. 0x0100,0x011f,0x013e,0x015d,0x017c,0x019c,0x01bb,0x01da,
  37. 0x01f9,0x0218,0x0237,0x0256,0x0275,0x0295,0x02b4,0x02d3,
  38. 0x02f2,0x0311,0x0330,0x034f,0x036e,0x038d,0x03ad,0x03cc,
  39. 0x03eb,0x040a,0x0429,0x0448,0x0467,0x0486,0x04a6,0x04c5,
  40. 0x04e4,0x0503,0x0522,0x0541,0x0560,0x057f,0x059e,0x05be,
  41. 0x05dd,0x05fc,0x061b,0x063a,0x0659,0x0678,0x0697,0x06b7,
  42. 0x06d6,0x06f5,0x0714,0x0733,0x0752,0x0771,0x0790,0x07af,
  43. 0x07cf,0x07ee,0x080d,0x082c,0x084b,0x086a,0x0889,0x08a8,
  44. 0x08c8,0x08e7,0x0906,0x0925,0x0944,0x0963,0x0982,0x09a1,
  45. 0x09c0,0x09e0,0x09ff,0x0a1e,0x0a3d,0x0a5c,0x0a7b,0x0a9a,
  46. 0x0ab9,0x0ad9,0x0af8,0x0b17,0x0b36,0x0b55,0x0b74,0x0b93,
  47. 0x0bb2,0x0bd1,0x0bf1,0x0c10,0x0c2f,0x0c4e,0x0c6d,0x0c8c,
  48. 0x0cab,0x0cca,0x0cea,0x0d09,0x0d28,0x0d47,0x0d66,0x0d85,
  49. 0x0da4,0x0dc3,0x0de2,0x0e02,0x0e21,0x0e40,0x0e5f,0x0e7e,
  50. 0x0e9d,0x0ebc,0x0edb,0x0efb,0x0f1a,0x0f39,0x0f58,0x0f77,
  51. 0x0f96,0x0fb5,0x0fd4,0x0ff3,0x1013,0x1032,0x1051,0x1070,
  52. 0x108f,0x10ae,0x10cd,0x10ec,0x110c,0x112b,0x114a,0x1169,
  53. 0x1188,0x11a7,0x11c6,0x11e5,0x1204,0x1224,0x1243,0x1262,
  54. 0x1281,0x12a0,0x12bf,0x12de,0x12fd,0x131d,0x133c,0x135b,
  55. 0x137a,0x1399,0x13b8,0x13d7,0x13f6,0x1415,0x1435,0x1454,
  56. 0x1473,0x1492,0x14b1,0x14d0,0x14ef,0x150e,0x152e,0x154d,
  57. 0x156c,0x158b,0x15aa,0x15c9,0x15e8,0x1607,0x1626,0x1646,
  58. 0x1665,0x1684,0x16a3,0x16c2,0x16e1,0x1700,0x171f,0x173f,
  59. 0x175e,0x177d,0x179c,0x17bb,0x17da,0x17f9,0x1818,0x1837,
  60. 0x1857,0x1876,0x1895,0x18b4,0x18d3,0x18f2,0x1911,0x1930,
  61. 0x1950,0x196f,0x198e,0x19ad,0x19cc,0x19eb,0x1a0a,0x1a29,
  62. 0x1a48,0x1a68,0x1a87,0x1aa6,0x1ac5,0x1ae4,0x1b03,0x1b22,
  63. 0x1b41,0x1b61,0x1b80,0x1b9f,0x1bbe,0x1bdd,0x1bfc,0x1c1b,
  64. 0x1c3a,0x1c59,0x1c79,0x1c98,0x1cb7,0x1cd6,0x1cf5,0x1d14,
  65. 0x1d33,0x1d52,0x1d72,0x1d91,0x1db0,0x1dcf,0x1dee,0x1e0d,
  66. 0x1e2c,0x1e4b,0x1e6a,0x1e8a,0x1ea9,0x1ec8,0x1ee7,0x1f06,
  67. 0x1f25,0x1f44,0x1f63,0x1f83,0x1fa2,0x1fc1,0x1fe0,0x1fff
  68. };
  69. CONST WORD GrayIdxWORD[] = {
  70. 0x0000,0x0101,0x0202,0x0303,0x0404,0x0505,0x0606,0x0707,
  71. 0x0808,0x0909,0x0a0a,0x0b0b,0x0c0c,0x0d0d,0x0e0e,0x0f0f,
  72. 0x1010,0x1111,0x1212,0x1313,0x1414,0x1515,0x1616,0x1717,
  73. 0x1818,0x1919,0x1a1a,0x1b1b,0x1c1c,0x1d1d,0x1e1e,0x1f1f,
  74. 0x2020,0x2121,0x2222,0x2323,0x2424,0x2525,0x2626,0x2727,
  75. 0x2828,0x2929,0x2a2a,0x2b2b,0x2c2c,0x2d2d,0x2e2e,0x2f2f,
  76. 0x3030,0x3131,0x3232,0x3333,0x3434,0x3535,0x3636,0x3737,
  77. 0x3838,0x3939,0x3a3a,0x3b3b,0x3c3c,0x3d3d,0x3e3e,0x3f3f,
  78. 0x4040,0x4141,0x4242,0x4343,0x4444,0x4545,0x4646,0x4747,
  79. 0x4848,0x4949,0x4a4a,0x4b4b,0x4c4c,0x4d4d,0x4e4e,0x4f4f,
  80. 0x5050,0x5151,0x5252,0x5353,0x5454,0x5555,0x5656,0x5757,
  81. 0x5858,0x5959,0x5a5a,0x5b5b,0x5c5c,0x5d5d,0x5e5e,0x5f5f,
  82. 0x6060,0x6161,0x6262,0x6363,0x6464,0x6565,0x6666,0x6767,
  83. 0x6868,0x6969,0x6a6a,0x6b6b,0x6c6c,0x6d6d,0x6e6e,0x6f6f,
  84. 0x7070,0x7171,0x7272,0x7373,0x7474,0x7575,0x7676,0x7777,
  85. 0x7878,0x7979,0x7a7a,0x7b7b,0x7c7c,0x7d7d,0x7e7e,0x7f7f,
  86. 0x8080,0x8181,0x8282,0x8383,0x8484,0x8585,0x8686,0x8787,
  87. 0x8888,0x8989,0x8a8a,0x8b8b,0x8c8c,0x8d8d,0x8e8e,0x8f8f,
  88. 0x9090,0x9191,0x9292,0x9393,0x9494,0x9595,0x9696,0x9797,
  89. 0x9898,0x9999,0x9a9a,0x9b9b,0x9c9c,0x9d9d,0x9e9e,0x9f9f,
  90. 0xa0a0,0xa1a1,0xa2a2,0xa3a3,0xa4a4,0xa5a5,0xa6a6,0xa7a7,
  91. 0xa8a8,0xa9a9,0xaaaa,0xabab,0xacac,0xadad,0xaeae,0xafaf,
  92. 0xb0b0,0xb1b1,0xb2b2,0xb3b3,0xb4b4,0xb5b5,0xb6b6,0xb7b7,
  93. 0xb8b8,0xb9b9,0xbaba,0xbbbb,0xbcbc,0xbdbd,0xbebe,0xbfbf,
  94. 0xc0c0,0xc1c1,0xc2c2,0xc3c3,0xc4c4,0xc5c5,0xc6c6,0xc7c7,
  95. 0xc8c8,0xc9c9,0xcaca,0xcbcb,0xcccc,0xcdcd,0xcece,0xcfcf,
  96. 0xd0d0,0xd1d1,0xd2d2,0xd3d3,0xd4d4,0xd5d5,0xd6d6,0xd7d7,
  97. 0xd8d8,0xd9d9,0xdada,0xdbdb,0xdcdc,0xdddd,0xdede,0xdfdf,
  98. 0xe0e0,0xe1e1,0xe2e2,0xe3e3,0xe4e4,0xe5e5,0xe6e6,0xe7e7,
  99. 0xe8e8,0xe9e9,0xeaea,0xebeb,0xecec,0xeded,0xeeee,0xefef,
  100. 0xf0f0,0xf1f1,0xf2f2,0xf3f3,0xf4f4,0xf5f5,0xf6f6,0xf7f7,
  101. 0xf8f8,0xf9f9,0xfafa,0xfbfb,0xfcfc,0xfdfd,0xfefe,0xffff
  102. };
  103. #define GET_555IDX(b,g,r,s) (((((LONG)BGR555Idx[b]-(s)) & 0x1F00) << 2) | \
  104. ((((LONG)BGR555Idx[g]-(s)) & 0x1F00) >> 3) | \
  105. ((((LONG)BGR555Idx[r]-(s)) ) >> 8))
  106. #if _MSC_FULL_VER >= 13008827 && defined(_M_IX86)
  107. #pragma warning(disable:4731) // EBP modified with inline asm
  108. #endif
  109. VOID
  110. HTENTRY
  111. MappingBGR(
  112. PBGR8 pbgr,
  113. LONG cbgr,
  114. PBGR8 pBGRMapTable,
  115. LPBYTE pbPat555
  116. )
  117. /*++
  118. Routine Description:
  119. Arguments:
  120. Return Value:
  121. Author:
  122. 17-Dec-1998 Thu 12:37:53 created -by- Daniel Chou (danielc)
  123. Revision History:
  124. --*/
  125. {
  126. #if defined(_X86_)
  127. _asm {
  128. push ebp
  129. cld
  130. mov edi, pbgr
  131. mov ecx, cbgr
  132. mov esi, pBGRMapTable
  133. mov ebx, pbPat555
  134. LoadPat555:
  135. movzx ebp, BYTE PTR [ebx]
  136. inc ebx
  137. BGRLoop:
  138. movzx eax, BYTE PTR [edi]
  139. movzx eax, WORD PTR BGR555Idx[eax * 2];
  140. sub eax, ebp
  141. shl ah, 2
  142. movzx edx, BYTE PTR [edi + 1]
  143. movzx edx, WORD PTR BGR555Idx[edx * 2];
  144. sub edx, ebp
  145. xor dl, dl
  146. shr edx, 3
  147. or dh, ah
  148. movzx eax, BYTE PTR [edi + 2]
  149. movzx eax, WORD PTR BGR555Idx[eax * 2];
  150. sub eax, ebp
  151. or dl, ah
  152. lea edx, DWORD PTR [edx * 2 + edx]
  153. mov ax, WORD PTR [esi + edx]
  154. stosw
  155. mov al, BYTE PTR [esi + edx + 2]
  156. stosb
  157. dec ecx
  158. jz Done
  159. movzx ebp, BYTE PTR [ebx]
  160. inc ebx
  161. or ebp, ebp
  162. jnz BGRLoop
  163. sub ebx, CX_SIZE_RGB555PAT
  164. jmp LoadPat555
  165. Done:
  166. pop ebp
  167. }
  168. #else
  169. PBGR8 pbgrEnd;
  170. LONG Pat555;
  171. pbgrEnd = pbgr + cbgr;
  172. Pat555 = (LONG)*pbPat555++;
  173. do {
  174. *pbgr = pBGRMapTable[GET_555IDX(pbgr->b, pbgr->g, pbgr->r, Pat555)];
  175. if (!(Pat555 = (LONG)*pbPat555++)) {
  176. Pat555 = (LONG)*(pbPat555 -= CX_SIZE_RGB555PAT);
  177. }
  178. } while (++pbgr < pbgrEnd);
  179. #endif
  180. }
  181. VOID
  182. HTENTRY
  183. MappingBGRF(
  184. PBGRF pbgrf,
  185. PBGRF pbgrfEnd,
  186. PBGR8 pBGRMapTable,
  187. LPBYTE pbPat555
  188. )
  189. /*++
  190. Routine Description:
  191. Arguments:
  192. Return Value:
  193. Author:
  194. 17-Dec-1998 Thu 12:37:53 created -by- Daniel Chou (danielc)
  195. Revision History:
  196. --*/
  197. {
  198. #if defined(_X86_)
  199. _asm {
  200. push ebp
  201. cld
  202. mov edi, pbgrf
  203. mov ecx, pbgrfEnd
  204. mov esi, pBGRMapTable
  205. mov ebx, pbPat555
  206. LoadPat555:
  207. movzx ebp, BYTE PTR [ebx]
  208. inc ebx
  209. BGRLoop:
  210. movzx eax, BYTE PTR [edi]
  211. movzx eax, WORD PTR BGR555Idx[eax * 2];
  212. sub eax, ebp
  213. shl ah, 2
  214. movzx edx, BYTE PTR [edi + 1]
  215. movzx edx, WORD PTR BGR555Idx[edx * 2];
  216. sub edx, ebp
  217. xor dl, dl
  218. shr edx, 3
  219. or dh, ah
  220. movzx eax, BYTE PTR [edi + 2]
  221. movzx eax, WORD PTR BGR555Idx[eax * 2];
  222. sub eax, ebp
  223. or dl, ah
  224. lea edx, DWORD PTR [edx * 2 + edx]
  225. mov ax, WORD PTR [esi + edx]
  226. stosw
  227. mov al, BYTE PTR [esi + edx + 2]
  228. stosb
  229. inc edi
  230. cmp edi, ecx
  231. jae Done
  232. movzx ebp, BYTE PTR [ebx]
  233. inc ebx
  234. or ebp, ebp
  235. jnz BGRLoop
  236. sub ebx, CX_SIZE_RGB555PAT
  237. jmp LoadPat555
  238. Done:
  239. pop ebp
  240. }
  241. #else
  242. LONG Pat555;
  243. Pat555 = (LONG)*pbPat555++;
  244. do {
  245. *(PBGR8)pbgrf = *(PBGR8)(pBGRMapTable + GET_555IDX(pbgrf->b,
  246. pbgrf->g,
  247. pbgrf->r,
  248. Pat555));
  249. if (!(Pat555 = (LONG)*pbPat555++)) {
  250. Pat555 = (LONG)*(pbPat555 -= CX_SIZE_RGB555PAT);
  251. }
  252. } while (++pbgrf < pbgrfEnd);
  253. #endif
  254. }
  255. VOID
  256. AlphaBlendBGRF(
  257. PAAHEADER pAAHdr
  258. )
  259. /*++
  260. Routine Description:
  261. Arguments:
  262. Return Value:
  263. Author:
  264. 19-Feb-1999 Fri 15:18:26 created -by- Daniel Chou (danielc)
  265. Revision History:
  266. 06-Sep-2000 Wed 11:13:59 updated -by- Daniel Chou (danielc)
  267. Adding the supports for pre-multiply source alpha and optimized for
  268. different alphablending cases
  269. --*/
  270. {
  271. #define pGrayF ((PGRAYF)pbgrf)
  272. #define pwBGR ((LPWORD)pbBGR)
  273. #define pbDst ((LPBYTE)pDstBGR)
  274. PBGRF pbgrf;
  275. PBGRF pbgrfEnd;
  276. LPBYTE pbBGR;
  277. PBGR8 pDstBGR;
  278. DWORD AAHFlags;
  279. DWORD r;
  280. DWORD g;
  281. DWORD b;
  282. BOOL DoGray;
  283. //
  284. // Start Alpha Blend
  285. //
  286. AAHFlags = pAAHdr->Flags;
  287. DoGray = (BOOL)(pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY);
  288. pbgrf = (PBGRF)pAAHdr->pRealOutBeg;
  289. pbgrfEnd = (PBGRF)pAAHdr->pRealOutEnd;
  290. pbBGR = pAAHdr->pAlphaBlendBGR;
  291. //
  292. // Read in the destination first
  293. //
  294. pAAHdr->DstSurfInfo.InputFunc(&(pAAHdr->DstSurfInfo),
  295. pDstBGR = pAAHdr->pInputBeg);
  296. if (AAHFlags & AAHF_CONST_ALPHA) {
  297. //
  298. // Const alpha blending case, we only need to read the destination
  299. // and blend it with compute/cached constant alpha table
  300. //
  301. if (AAHFlags & AAHF_HAS_MASK) {
  302. if (DoGray) {
  303. do {
  304. if (PBGRF_HAS_MASK(pbgrf)) {
  305. GET_CONST_ALPHA_GRAY(pbgrf, pbDst, pwBGR);
  306. }
  307. ++pbDst;
  308. } while (++pbgrf < pbgrfEnd);
  309. } else {
  310. do {
  311. if (PBGRF_HAS_MASK(pbgrf)) {
  312. GET_CONST_ALPHA_BGR(pbgrf, pDstBGR, pwBGR);
  313. }
  314. ++pDstBGR;
  315. } while (++pbgrf < pbgrfEnd);
  316. }
  317. } else {
  318. if (DoGray) {
  319. do {
  320. GET_CONST_ALPHA_GRAY(pbgrf, pbDst, pwBGR);
  321. ++pbDst;
  322. } while (++pbgrf < pbgrfEnd);
  323. } else {
  324. do {
  325. GET_CONST_ALPHA_BGR(pbgrf, pDstBGR, pwBGR);
  326. ++pDstBGR;
  327. } while (++pbgrf < pbgrfEnd);
  328. }
  329. }
  330. } else {
  331. LPBYTE pCA;
  332. LONG CA;
  333. WORD DstGray;
  334. BYTE bCA;
  335. //
  336. // This is per-pixel alpha blending, we first read the source alpha
  337. // channel information, the source may be stretched (expand, same or
  338. // shrinked)
  339. //
  340. pAAHdr->GetAVCYFunc(pAAHdr);
  341. pCA = (LPBYTE)pAAHdr->pSrcAV;
  342. if (DoGray) {
  343. //
  344. // This is gray scale destination case
  345. //
  346. if (AAHFlags & AAHF_HAS_MASK) {
  347. do {
  348. if (PBGRF_HAS_MASK(pbgrf)) {
  349. DstGray = GRAY_B2W(*pbDst);
  350. switch (*pCA) {
  351. case 0:
  352. GET_GRAY_AB_DST(pGrayF->Gray, DstGray);
  353. break;
  354. case 0xFF:
  355. GET_GRAY_AB_SRC(pGrayF->Gray, DstGray);
  356. break;
  357. default:
  358. pGrayF->Gray = GET_GRAY_ALPHA_BLEND(pGrayF->Gray,
  359. DstGray,
  360. *pCA);
  361. }
  362. }
  363. ++pCA;
  364. ++pbDst;
  365. } while (++pbgrf < pbgrfEnd);
  366. } else {
  367. do {
  368. DstGray = GRAY_B2W(*pbDst++);
  369. switch (*pCA) {
  370. case 0:
  371. GET_GRAY_AB_DST(pGrayF->Gray, DstGray);
  372. break;
  373. case 0xFF:
  374. GET_GRAY_AB_SRC(pGrayF->Gray, DstGray);
  375. break;
  376. default:
  377. pGrayF->Gray = GET_GRAY_ALPHA_BLEND(pGrayF->Gray,
  378. DstGray,
  379. *pCA);
  380. }
  381. ++pCA;
  382. } while (++pbgrf < pbgrfEnd);
  383. }
  384. } else if (AAHFlags & AAHF_AB_DEST) {
  385. PBGRF pbgrfDst;
  386. //
  387. // This is color RGB alpha blend WITH alpha channel blending.
  388. // so we already read from the destination into the BGR order in
  389. // pDstBGR, and pCA points to the alpha value in the source
  390. // pbgrf is current source stretching/aliasing result. We need to
  391. // get destination alpha channel information from pbgrfDst->f
  392. //
  393. // The source and destination both is 32bpp and we also need to
  394. // update the destination alpha value
  395. //
  396. pbgrfDst = (PBGRF)pAAHdr->DstSurfInfo.pb;
  397. if (AAHFlags & AAHF_HAS_MASK) {
  398. do {
  399. if (PBGRF_HAS_MASK(pbgrf)) {
  400. switch (bCA = *pCA) {
  401. case 0:
  402. GET_AB_BGR_DST(pbgrf, pbBGR, pDstBGR);
  403. GET_AB_DEST_CA_DST(bCA, pbgrfDst->f);
  404. break;
  405. case 0xFF:
  406. GET_AB_BGR_SRC(pbgrf, pbBGR, pDstBGR);
  407. GET_AB_DEST_CA_SRC(bCA, pbgrfDst->f);
  408. break;
  409. default:
  410. CA = GET_CA_VALUE(bCA);
  411. GET_AB_DEST_CA(bCA, pbgrfDst->f, CA);
  412. GET_ALPHA_BLEND_BGR(pbgrf, pbBGR, pDstBGR, CA);
  413. break;
  414. }
  415. }
  416. ++pCA;
  417. ++pbgrfDst;
  418. ++pDstBGR;
  419. } while (++pbgrf < pbgrfEnd);
  420. } else {
  421. do {
  422. switch (bCA = *pCA++) {
  423. case 0:
  424. GET_AB_BGR_DST(pbgrf, pbBGR, pDstBGR);
  425. GET_AB_DEST_CA_DST(bCA, pbgrfDst->f);
  426. break;
  427. case 0xFF:
  428. GET_AB_BGR_SRC(pbgrf, pbBGR, pDstBGR);
  429. GET_AB_DEST_CA_SRC(bCA, pbgrfDst->f);
  430. break;
  431. default:
  432. CA = GET_CA_VALUE(bCA);
  433. GET_AB_DEST_CA(bCA, pbgrfDst->f, CA);
  434. GET_ALPHA_BLEND_BGR(pbgrf, pbBGR, pDstBGR, CA);
  435. break;
  436. }
  437. ++pbgrfDst;
  438. ++pDstBGR;
  439. } while (++pbgrf < pbgrfEnd);
  440. }
  441. } else {
  442. //
  443. // This is color RGB alpha blend only without alpha channel blend
  444. // so we already read from the destination into the BGR order in
  445. // pDstBGR, and pCA points to the alpha value in the source
  446. // pbgrf is current source stretching/aliasing result
  447. //
  448. if (AAHFlags & AAHF_HAS_MASK) {
  449. do {
  450. if (PBGRF_HAS_MASK(pbgrf)) {
  451. switch (*pCA) {
  452. case 0:
  453. GET_AB_BGR_DST(pbgrf, pbBGR, pDstBGR);
  454. break;
  455. case 0xFF:
  456. GET_AB_BGR_SRC(pbgrf, pbBGR, pDstBGR);
  457. break;
  458. default:
  459. CA = GET_CA_VALUE(*pCA);
  460. GET_ALPHA_BLEND_BGR(pbgrf, pbBGR, pDstBGR, CA);
  461. break;
  462. }
  463. }
  464. ++pCA;
  465. ++pDstBGR;
  466. } while (++pbgrf < pbgrfEnd);
  467. } else {
  468. do {
  469. switch (*pCA) {
  470. case 0:
  471. GET_AB_BGR_DST(pbgrf, pbBGR, pDstBGR);
  472. break;
  473. case 0xFF:
  474. GET_AB_BGR_SRC(pbgrf, pbBGR, pDstBGR);
  475. break;
  476. default:
  477. CA = GET_CA_VALUE(*pCA);
  478. GET_ALPHA_BLEND_BGR(pbgrf, pbBGR, pDstBGR, CA);
  479. break;
  480. }
  481. ++pCA;
  482. ++pDstBGR;
  483. } while (++pbgrf < pbgrfEnd);
  484. }
  485. }
  486. }
  487. #undef pbDst
  488. #undef pwBGR
  489. #undef pGrayF
  490. }
  491. LONG
  492. HTENTRY
  493. TileDIB_CY(
  494. PAAHEADER pAAHdr
  495. )
  496. /*++
  497. Routine Description:
  498. Arguments:
  499. Return Value:
  500. Author:
  501. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  502. Revision History:
  503. --*/
  504. {
  505. #define pGrayF ((PGRAYF)pOut)
  506. #define pbIn ((LPBYTE)pIn)
  507. #define pwIn ((LPWORD)pInCur)
  508. AAHEADER AAHdr;
  509. LPWORD pwGray;
  510. LONG cyLoop;
  511. LONG xSrcBeg;
  512. LONG xSrcInc;
  513. LONG cxAvai;
  514. LONG cxFirst;
  515. AAHdr = *pAAHdr;
  516. pwGray = (LPWORD)AAHdr.pAAInfoCY->pbExtra;
  517. cyLoop = AAHdr.DstSurfInfo.cy;
  518. xSrcBeg = (LONG)AAHdr.pAAInfoCX->iSrcBeg;
  519. xSrcInc = xSrcBeg * ((AAHdr.SrcSurfInfo.Flags & AASIF_GRAY) ? sizeof(WORD) :
  520. sizeof(BGR8));
  521. cxFirst = AAHdr.SrcSurfInfo.cx - xSrcBeg;
  522. while (cyLoop--) {
  523. PBGR8 pIn;
  524. PBGR8 pInCur;
  525. PBGR8 pOut;
  526. LONG cInCur;
  527. LONG cOutCur;
  528. LONG cxAvai;
  529. pIn = GetFixupScan(&AAHdr, AAHdr.pInputBeg);
  530. if (AAHdr.SrcSurfInfo.Flags & AASIF_GRAY) {
  531. cxAvai = AAHdr.SrcSurfInfo.cx;
  532. pwIn = pwGray;
  533. while (cxAvai--) {
  534. *pwIn++ = GRAY_B2W(*pbIn++);
  535. }
  536. pIn = (PBGR8)pwGray;
  537. }
  538. pInCur = (PBGR8)((LPBYTE)pIn + xSrcInc);
  539. pOut = (PBGR8)AAHdr.pAABufBeg;
  540. cOutCur = AAHdr.DstSurfInfo.cx;
  541. cxAvai = cxFirst;
  542. while (cOutCur) {
  543. if ((cInCur = cxAvai) > cOutCur) {
  544. cInCur = cOutCur;
  545. }
  546. cxAvai = AAHdr.SrcSurfInfo.cx;
  547. cOutCur -= cInCur;
  548. if (AAHdr.SrcSurfInfo.Flags & AASIF_GRAY) {
  549. while (cInCur--) {
  550. pGrayF->Gray = *pwIn++;
  551. (LPBYTE)pOut += AAHdr.AABufInc;
  552. }
  553. } else {
  554. while (cInCur--) {
  555. *pOut = *pInCur++;
  556. (LPBYTE)pOut += AAHdr.AABufInc;
  557. }
  558. }
  559. pInCur = pIn;
  560. }
  561. OUTPUT_AA_CURSCAN;
  562. }
  563. return(AAHdr.DstSurfInfo.cy);
  564. #undef pGrayF
  565. #undef pbIn
  566. #undef pwIn
  567. }
  568. VOID
  569. HTENTRY
  570. GrayCopyDIB_CXGray(
  571. PAAINFO pAAInfo,
  572. LPBYTE pIn,
  573. PGRAYF pOut,
  574. LPBYTE pOutEnd,
  575. LONG OutInc
  576. )
  577. /*++
  578. Routine Description:
  579. Arguments:
  580. Return Value:
  581. Author:
  582. 14-Apr-1999 Wed 15:22:05 created -by- Daniel Chou (danielc)
  583. Revision History:
  584. --*/
  585. {
  586. do {
  587. pOut->Gray = GRAY_B2W(*pIn++);
  588. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  589. }
  590. VOID
  591. HTENTRY
  592. GrayRepDIB_CX(
  593. PAAINFO pAAInfo,
  594. LPBYTE pIn,
  595. PGRAYF pOut,
  596. LPBYTE pOutEnd,
  597. LONG OutInc
  598. )
  599. /*++
  600. Routine Description:
  601. Arguments:
  602. Return Value:
  603. Author:
  604. 09-Dec-1998 Wed 15:54:25 created -by- Daniel Chou (danielc)
  605. Revision History:
  606. --*/
  607. {
  608. PREPDATA pRep;
  609. PREPDATA pRepEnd;
  610. DWORD cRep;
  611. WORD wGray;
  612. pRep = pAAInfo->Src.pRep;
  613. pRepEnd = pAAInfo->Src.pRepEnd;
  614. cRep = 1;
  615. do {
  616. if (--cRep == 0) {
  617. cRep = (DWORD)pRep->c;
  618. wGray = GRAY_B2W(*pIn);
  619. if (pRep < pRepEnd) {
  620. ++pRep;
  621. ++pIn;
  622. }
  623. }
  624. pOut->Gray = wGray;
  625. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  626. }
  627. VOID
  628. HTENTRY
  629. RepDIB_CX(
  630. PAAINFO pAAInfo,
  631. PBGR8 pIn,
  632. PBGR8 pOut,
  633. LPBYTE pOutEnd,
  634. LONG OutInc
  635. )
  636. /*++
  637. Routine Description:
  638. Arguments:
  639. Return Value:
  640. Author:
  641. 09-Dec-1998 Wed 15:54:25 created -by- Daniel Chou (danielc)
  642. Revision History:
  643. --*/
  644. {
  645. PREPDATA pRep;
  646. PREPDATA pRepEnd;
  647. DWORD cRep;
  648. BGR8 bgr8;
  649. pRep = pAAInfo->Src.pRep;
  650. pRepEnd = pAAInfo->Src.pRepEnd;
  651. cRep = 1;
  652. do {
  653. if (--cRep == 0) {
  654. cRep = (DWORD)pRep->c;
  655. bgr8 = *pIn;
  656. if (pRep < pRepEnd) {
  657. ++pRep;
  658. ++pIn;
  659. }
  660. }
  661. *pOut = bgr8;
  662. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  663. }
  664. LONG
  665. HTENTRY
  666. RepDIB_CY(
  667. PAAHEADER pAAHdr
  668. )
  669. /*++
  670. Routine Description:
  671. Arguments:
  672. Return Value:
  673. Author:
  674. 09-Dec-1998 Wed 15:32:38 created -by- Daniel Chou (danielc)
  675. Revision History:
  676. --*/
  677. {
  678. AAHEADER AAHdr = *pAAHdr;
  679. PAAINFO pAAInfo;
  680. PREPDATA pRep;
  681. PREPDATA pRepEnd;
  682. DWORD cRep;
  683. PBGRF pAABufBeg;
  684. PBGRF pAABufEnd;
  685. LONG AABufInc;
  686. pAAInfo = AAHdr.pAAInfoCY;
  687. pRep = pAAInfo->Src.pRep;
  688. pRepEnd = pAAInfo->Src.pRepEnd;
  689. cRep = 1;
  690. if (AAHdr.Flags & AAHF_ALPHA_BLEND) {
  691. pAABufBeg = (PBGRF)pAAInfo->pbExtra;
  692. pAABufEnd = (PBGRF)((PBGR8)pAAInfo->pbExtra + AAHdr.DstSurfInfo.cx);
  693. AABufInc = sizeof(BGR8);
  694. } else {
  695. pAABufBeg = AAHdr.pAABufBeg;
  696. pAABufEnd = AAHdr.pAABufEnd;
  697. AABufInc = AAHdr.AABufInc;
  698. }
  699. while (AAHdr.DstSurfInfo.cy--) {
  700. if (--cRep == 0) {
  701. cRep = (DWORD)pRep->c;
  702. if (pRep < pRepEnd) {
  703. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  704. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  705. (PBGR8)pAABufBeg,
  706. (LPBYTE)pAABufEnd,
  707. AABufInc);
  708. ++pRep;
  709. }
  710. }
  711. if (AAHdr.Flags & AAHF_ALPHA_BLEND) {
  712. CopyDIB_CX(NULL,
  713. (PBGR8)pAABufBeg,
  714. (PBGR8)AAHdr.pAABufBeg,
  715. (LPBYTE)AAHdr.pAABufEnd,
  716. AAHdr.AABufInc);
  717. }
  718. OUTPUT_AA_CURSCAN;
  719. }
  720. return(pAAHdr->DstSurfInfo.cy);
  721. }
  722. VOID
  723. HTENTRY
  724. CopyDIB_CX(
  725. PAAINFO pAAInfo,
  726. PBGR8 pIn,
  727. PBGR8 pOut,
  728. LPBYTE pOutEnd,
  729. LONG OutInc
  730. )
  731. /*++
  732. Routine Description:
  733. Arguments:
  734. Return Value:
  735. Author:
  736. 26-Jun-1998 Fri 11:33:20 created -by- Daniel Chou (danielc)
  737. Revision History:
  738. --*/
  739. {
  740. do {
  741. *pOut = *pIn++;
  742. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  743. }
  744. LONG
  745. HTENTRY
  746. BltDIB_CY(
  747. PAAHEADER pAAHdr
  748. )
  749. /*++
  750. Routine Description:
  751. Arguments:
  752. Return Value:
  753. Author:
  754. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  755. Revision History:
  756. --*/
  757. {
  758. AAHEADER AAHdr;
  759. PBGR8 pIn;
  760. LONG cLoop;
  761. AAHdr = *pAAHdr;
  762. cLoop = AAHdr.pAAInfoCY->cOut;
  763. while (cLoop--) {
  764. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  765. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  766. (PBGR8)AAHdr.pAABufBeg,
  767. (LPBYTE)AAHdr.pAABufEnd,
  768. AAHdr.AABufInc);
  769. if (AAHdr.SrcSurfInfo.Flags & AASIF_GRAY) {
  770. PBGRF pbgrf;
  771. pbgrf = AAHdr.pRealOutBeg;
  772. do {
  773. ((PGRAYF)pbgrf)->Gray = GRAY_B2W(pbgrf->b);
  774. } while (++pbgrf < AAHdr.pRealOutEnd);
  775. }
  776. OUTPUT_AA_CURSCAN;
  777. }
  778. return(AAHdr.DstSurfInfo.cy);
  779. }
  780. VOID
  781. HTENTRY
  782. GraySkipDIB_CX(
  783. PAAINFO pAAInfo,
  784. LPBYTE pIn,
  785. PGRAYF pOut,
  786. LPBYTE pOutEnd,
  787. LONG OutInc
  788. )
  789. /*++
  790. Routine Description:
  791. Arguments:
  792. Return Value:
  793. Author:
  794. 05-Apr-1999 Mon 12:57:42 created -by- Daniel Chou (danielc)
  795. Revision History:
  796. --*/
  797. {
  798. PREPDATA pRep;
  799. PREPDATA pRepEnd;
  800. DWORD cRep;
  801. pRep = pAAInfo->Src.pRep;
  802. pRepEnd = pAAInfo->Src.pRepEnd;
  803. do {
  804. ASSERT(pRep < pRepEnd);
  805. pIn += pRep++->c;
  806. pOut->Gray = GRAY_B2W(*(pIn - 1));
  807. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  808. }
  809. VOID
  810. HTENTRY
  811. SkipDIB_CX(
  812. PAAINFO pAAInfo,
  813. PBGR8 pIn,
  814. PBGR8 pOut,
  815. LPBYTE pOutEnd,
  816. LONG OutInc
  817. )
  818. /*++
  819. Routine Description:
  820. Arguments:
  821. Return Value:
  822. Author:
  823. 05-Apr-1999 Mon 12:57:42 created -by- Daniel Chou (danielc)
  824. Revision History:
  825. --*/
  826. {
  827. PREPDATA pRep;
  828. PREPDATA pRepEnd;
  829. pRep = pAAInfo->Src.pRep;
  830. pRepEnd = pAAInfo->Src.pRepEnd;
  831. do {
  832. ASSERT(pRep < pRepEnd);
  833. pIn += pRep++->c;
  834. *pOut = *(pIn - 1);
  835. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  836. }
  837. LONG
  838. HTENTRY
  839. SkipDIB_CY(
  840. PAAHEADER pAAHdr
  841. )
  842. /*++
  843. Routine Description:
  844. Arguments:
  845. Return Value:
  846. Author:
  847. 05-Apr-1999 Mon 12:58:00 created -by- Daniel Chou (danielc)
  848. Revision History:
  849. --*/
  850. {
  851. AAHEADER AAHdr = *pAAHdr;
  852. PAAINFO pAAInfo;
  853. PREPDATA pRep;
  854. PREPDATA pRepEnd;
  855. LONG cRep;
  856. pAAInfo = AAHdr.pAAInfoCY;
  857. pRep = pAAInfo->Src.pRep;
  858. pRepEnd = pAAInfo->Src.pRepEnd;
  859. while (AAHdr.DstSurfInfo.cy--) {
  860. ASSERT(pRep < pRepEnd);
  861. //
  862. // Skip the source scan lines (cRep - 1) by calling GetFixupScan()
  863. // with a NULL buffer pointer, !!!! we must not alter the
  864. // SrcSurfInfo.pb at here
  865. //
  866. cRep = (LONG)(pRep++->c);
  867. while (--cRep > 0) {
  868. GetFixupScan(&AAHdr, NULL);
  869. }
  870. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  871. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  872. (PBGR8)AAHdr.pAABufBeg,
  873. (LPBYTE)AAHdr.pAABufEnd,
  874. AAHdr.AABufInc);
  875. OUTPUT_AA_CURSCAN;
  876. }
  877. return(pAAHdr->DstSurfInfo.cy);
  878. }
  879. VOID
  880. HTENTRY
  881. ShrinkDIB_CX(
  882. PAAINFO pAAInfo,
  883. PBGR8 pIn,
  884. PBGR8 pOut,
  885. LPBYTE pOutEnd,
  886. LONG OutInc
  887. )
  888. /*++
  889. Routine Description:
  890. Arguments:
  891. Return Value:
  892. Author:
  893. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  894. Revision History:
  895. --*/
  896. {
  897. PSHRINKDATA pSD;
  898. PLONG pMap;
  899. PLONG pMap256X;
  900. PBGR8 pInEnd;
  901. RGBL rgbOut[3];
  902. RGBL rgbT;
  903. UINT Mul;
  904. UINT cPreLoad;
  905. pInEnd = pIn + pAAInfo->cIn;
  906. if (Mul = (UINT)pAAInfo->PreMul) {
  907. rgbOut[2].r = MULRGB(pIn->r, Mul);
  908. rgbOut[2].g = MULRGB(pIn->g, Mul);
  909. rgbOut[2].b = MULRGB(pIn->b, Mul);
  910. pIn += pAAInfo->PreSrcInc;
  911. } else {
  912. ZeroMemory(&rgbOut[2], sizeof(rgbOut[2]));
  913. }
  914. pSD = (PSHRINKDATA)(pAAInfo->pAAData);
  915. pMap256X = pAAInfo->pMapMul;
  916. cPreLoad = (UINT)pAAInfo->cPreLoad;
  917. while (cPreLoad) {
  918. Mul = (UINT)((pSD++)->Mul);
  919. pMap = (PLONG)((LPBYTE)pMap256X + GET_SDF_LARGE_OFF(Mul));
  920. if (Mul & SDF_DONE) {
  921. //
  922. // Finished a pixel
  923. //
  924. Mul &= SDF_MUL_MASK;
  925. rgbOut[2].r += (rgbT.r = MULRGB(pIn->r, Mul));
  926. rgbOut[2].g += (rgbT.g = MULRGB(pIn->g, Mul));
  927. rgbOut[2].b += (rgbT.b = MULRGB(pIn->b, Mul));
  928. CopyMemory(&rgbOut[0], &rgbOut[1], sizeof(rgbOut[0]) * 2);
  929. rgbOut[2].r = pMap[(pIn )->r] - rgbT.r;
  930. rgbOut[2].g = pMap[(pIn )->g] - rgbT.g;
  931. rgbOut[2].b = pMap[(pIn++)->b] - rgbT.b;
  932. --cPreLoad;
  933. } else {
  934. rgbOut[2].r += pMap[(pIn )->r];
  935. rgbOut[2].g += pMap[(pIn )->g];
  936. rgbOut[2].b += pMap[(pIn++)->b];
  937. }
  938. }
  939. if (pAAInfo->cPreLoad == 1) {
  940. rgbOut[0] = rgbOut[1];
  941. }
  942. while (Mul = (UINT)((pSD++)->Mul)) {
  943. pMap = (PLONG)((LPBYTE)pMap256X + GET_SDF_LARGE_OFF(Mul));
  944. if (Mul & SDF_DONE) {
  945. //
  946. // Finished a pixel
  947. //
  948. Mul &= SDF_MUL_MASK;
  949. rgbOut[2].r += (rgbT.r = MULRGB(pIn->r, Mul));
  950. rgbOut[2].g += (rgbT.g = MULRGB(pIn->g, Mul));
  951. rgbOut[2].b += (rgbT.b = MULRGB(pIn->b, Mul));
  952. SHARPEN_PRGB_LR(pOut, rgbOut[0], rgbOut[1], rgbOut[2], DI_R_SHIFT);
  953. (LPBYTE)pOut += OutInc;
  954. CopyMemory(&rgbOut[0], &rgbOut[1], sizeof(rgbOut[0]) * 2);
  955. rgbOut[2].r = pMap[(pIn )->r] - rgbT.r;
  956. rgbOut[2].g = pMap[(pIn )->g] - rgbT.g;
  957. rgbOut[2].b = pMap[(pIn++)->b] - rgbT.b;
  958. } else {
  959. rgbOut[2].r += pMap[(pIn )->r];
  960. rgbOut[2].g += pMap[(pIn )->g];
  961. rgbOut[2].b += pMap[(pIn++)->b];
  962. }
  963. }
  964. ASSERT(pIn == pInEnd);
  965. if ((LPBYTE)pOut == (pOutEnd - OutInc)) {
  966. SHARPEN_PRGB_LR(pOut, rgbOut[0], rgbOut[1], rgbOut[1], DI_R_SHIFT);
  967. }
  968. }
  969. LONG
  970. HTENTRY
  971. ShrinkDIB_CY(
  972. PAAHEADER pAAHdr
  973. )
  974. /*++
  975. Routine Description:
  976. This function shrink the scanline down first in Y direction from source
  977. bitmap when it is done for group of scanlines then it call AXFunc to
  978. compose current scanline (it may be Shrink(CX) or Expand(CX)) to the
  979. final output BGR8 buffer
  980. The shrink is done by sharpen the current pixel first.
  981. Arguments:
  982. Return Value:
  983. Author:
  984. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  985. Revision History:
  986. --*/
  987. {
  988. AAHEADER AAHdr;
  989. PSHRINKDATA pSD;
  990. SHRINKDATA sd;
  991. PBGR8 pIBuf;
  992. PBGR8 pICur;
  993. PBGR8 pOCur;
  994. PRGBL prgbIn[3];
  995. PRGBL prgb0;
  996. PRGBL prgb1;
  997. PRGBL prgb2;
  998. PRGBL prgb2End;
  999. PLONG pMap;
  1000. PLONG pMapMul;
  1001. PLONG pMapMul2;
  1002. PLONG pMap256Y;
  1003. RGBL rgbT;
  1004. BGR8 rgbCur;
  1005. LONG cbrgbY;
  1006. LONG Mul;
  1007. LONG cAAData;
  1008. BOOL CopyFirst;
  1009. LONG cyOut;
  1010. INT cPreLoad;
  1011. BYTE Mask;
  1012. //
  1013. // Adding 3 to each side of pIBuf for ExpandDIB_CX
  1014. //
  1015. AAHdr = *pAAHdr;
  1016. pMap256Y = AAHdr.pAAInfoCY->pMapMul;
  1017. pMapMul = (PLONG)(AAHdr.pAAInfoCY->pbExtra);
  1018. pMapMul2 = pMapMul + 256;
  1019. cbrgbY = (LONG)(AAHdr.SrcSurfInfo.cx * sizeof(RGBL));
  1020. prgbIn[0] = (PRGBL)(pMapMul2 + 256);
  1021. prgbIn[1] = (PRGBL)((LPBYTE)prgbIn[0] + cbrgbY);
  1022. prgbIn[2] = (PRGBL)((LPBYTE)prgbIn[1] + cbrgbY);
  1023. pIBuf = (PBGR8)((LPBYTE)prgbIn[2] + cbrgbY) + 3;
  1024. ASSERT_MEM_ALIGN(prgbIn[0], sizeof(LONG));
  1025. ASSERT_MEM_ALIGN(prgbIn[1], sizeof(LONG));
  1026. ASSERT_MEM_ALIGN(prgbIn[2], sizeof(LONG));
  1027. if (Mul = AAHdr.pAAInfoCY->PreMul) {
  1028. pMap = pMapMul;
  1029. rgbT.r = -Mul;
  1030. do {
  1031. pMap[0] = (rgbT.r += Mul);
  1032. } while (++pMap < pMapMul2);
  1033. pICur = GetFixupScan(&AAHdr, AAHdr.pInputBeg);
  1034. pOCur = pIBuf;
  1035. prgb2 = prgbIn[2];
  1036. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1037. do {
  1038. prgb2->r = pMapMul[(pICur )->r];
  1039. prgb2->g = pMapMul[(pICur )->g];
  1040. prgb2->b = pMapMul[(pICur++)->b];
  1041. } while (++prgb2 < prgb2End);
  1042. //
  1043. // The AAInputFunc() will increment the pointer, so reduced it
  1044. //
  1045. if (!(AAHdr.pAAInfoCY->PreSrcInc)) {
  1046. AAHdr.Flags |= AAHF_GET_LAST_SCAN;
  1047. }
  1048. }
  1049. pSD = (PSHRINKDATA)(AAHdr.pAAInfoCY->pAAData);
  1050. cPreLoad = (INT)AAHdr.pAAInfoCY->cPreLoad;
  1051. CopyFirst = (BOOL)(cPreLoad == 1);
  1052. cAAData = AAHdr.pAAInfoCY->cAAData;
  1053. cyOut = 0;
  1054. while (cAAData--) {
  1055. pICur = GetFixupScan(&AAHdr, AAHdr.pInputBeg);
  1056. sd = *pSD++;
  1057. prgb2 = prgbIn[2];
  1058. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1059. Mask = GET_SDF_LARGE_MASK(sd.Mul);
  1060. if (sd.Mul & SDF_DONE) {
  1061. //
  1062. // Build current Mul Table
  1063. //
  1064. Mul = (LONG)(sd.Mul & SDF_MUL_MASK);
  1065. pMap = pMapMul;
  1066. rgbT.r = -Mul;
  1067. rgbT.b = (LONG)(pMap256Y[1] - Mul + (LONG)(Mask & 0x01));
  1068. rgbT.g = -rgbT.b;
  1069. do {
  1070. pMap[ 0] = (rgbT.r += Mul);
  1071. pMap[256] = (rgbT.g += rgbT.b);
  1072. } while (++pMap < pMapMul2);
  1073. //
  1074. // Finished a scanline, so to see if have prev/next to sharpen with
  1075. //
  1076. prgb0 = prgbIn[0];
  1077. prgb1 = prgbIn[1];
  1078. if (cPreLoad-- > 0) {
  1079. do {
  1080. prgb2->r += pMapMul[pICur->r];
  1081. prgb2->g += pMapMul[pICur->g];
  1082. prgb2->b += pMapMul[pICur->b];
  1083. prgb0->r = pMapMul[pICur->r + 256];
  1084. prgb0->g = pMapMul[pICur->g + 256];
  1085. prgb0->b = pMapMul[pICur->b + 256];
  1086. ++pICur;
  1087. prgb0++;
  1088. } while (++prgb2 < prgb2End);
  1089. if (CopyFirst) {
  1090. CopyMemory(prgb1, prgbIn[2], cbrgbY);
  1091. CopyFirst = FALSE;
  1092. }
  1093. } else {
  1094. pOCur = pIBuf;
  1095. do {
  1096. rgbCur = *pICur++;
  1097. prgb2->r += pMapMul[rgbCur.r];
  1098. prgb2->g += pMapMul[rgbCur.g];
  1099. prgb2->b += pMapMul[rgbCur.b];
  1100. SHARPEN_PRGB_LR(pOCur,
  1101. (*prgb0),
  1102. (*prgb1),
  1103. (*prgb2),
  1104. DI_R_SHIFT);
  1105. prgb0->r = pMapMul[rgbCur.r + 256];
  1106. prgb0->g = pMapMul[rgbCur.g + 256];
  1107. prgb0->b = pMapMul[rgbCur.b + 256];
  1108. ++pOCur;
  1109. ++prgb0;
  1110. ++prgb1;
  1111. } while (++prgb2 < prgb2End);
  1112. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  1113. pIBuf,
  1114. (PBGR8)AAHdr.pAABufBeg,
  1115. (LPBYTE)AAHdr.pAABufEnd,
  1116. AAHdr.AABufInc);
  1117. OUTPUT_AA_CURSCAN;
  1118. ++cyOut;
  1119. }
  1120. prgb2 = prgbIn[0];
  1121. prgbIn[0] = prgbIn[1];
  1122. prgbIn[1] = prgbIn[2];
  1123. prgbIn[2] = prgb2;
  1124. } else {
  1125. pMap = (PLONG)((LPBYTE)pMap256Y + GET_SDF_LARGE_OFF(sd.Mul));
  1126. do {
  1127. prgb2->r += pMap[(pICur )->r];
  1128. prgb2->g += pMap[(pICur )->g];
  1129. prgb2->b += pMap[(pICur++)->b];
  1130. } while (++prgb2 < prgb2End);
  1131. }
  1132. }
  1133. if (AAHdr.DstSurfInfo.pb != AAHdr.pOutLast) {
  1134. //
  1135. // Do the last line if exist
  1136. //
  1137. pOCur = pIBuf;
  1138. prgb0 = prgbIn[0];
  1139. prgb2 = prgbIn[1];
  1140. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1141. do {
  1142. SHARPEN_PRGB_LR(pOCur,
  1143. (*prgb0),
  1144. (*prgb2),
  1145. (*prgb2),
  1146. DI_R_SHIFT);
  1147. ++prgb0;
  1148. ++pOCur;
  1149. } while (++prgb2 < prgb2End);
  1150. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  1151. pIBuf,
  1152. (PBGR8)AAHdr.pAABufBeg,
  1153. (LPBYTE)AAHdr.pAABufEnd,
  1154. AAHdr.AABufInc);
  1155. OUTPUT_AA_CURSCAN;
  1156. ++cyOut;
  1157. }
  1158. ASSERTMSG("Shrink: cScan not equal", cyOut == AAHdr.DstSurfInfo.cy);
  1159. return(cyOut);
  1160. }
  1161. VOID
  1162. HTENTRY
  1163. SrkYDIB_SrkCX(
  1164. PAAINFO pAAInfo,
  1165. PBGR8 pIn,
  1166. PBGR8 pOut
  1167. )
  1168. /*++
  1169. Routine Description:
  1170. Arguments:
  1171. Return Value:
  1172. Author:
  1173. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1174. Revision History:
  1175. --*/
  1176. {
  1177. PSHRINKDATA pSD;
  1178. PLONG pMap;
  1179. PLONG pMap256X;
  1180. BGR8 rgbIn;
  1181. RGBL rgbOut;
  1182. RGBL rgbT;
  1183. UINT Mul;
  1184. if (Mul = (UINT)pAAInfo->PreMul) {
  1185. rgbOut.r = MULRGB(pIn->r, Mul);
  1186. rgbOut.g = MULRGB(pIn->g, Mul);
  1187. rgbOut.b = MULRGB(pIn->b, Mul);
  1188. pIn += pAAInfo->PreSrcInc;
  1189. } else {
  1190. ZeroMemory(&rgbOut, sizeof(rgbOut));
  1191. }
  1192. pSD = (PSHRINKDATA)(pAAInfo->pAAData);
  1193. pMap256X = pAAInfo->pMapMul;
  1194. while (Mul = (UINT)((pSD++)->Mul)) {
  1195. pMap = (PLONG)((LPBYTE)pMap256X + GET_SDF_LARGE_OFF(Mul));
  1196. rgbIn = *pIn++;
  1197. if (Mul & SDF_DONE) {
  1198. //
  1199. // Finished a pixel
  1200. //
  1201. Mul &= SDF_MUL_MASK;
  1202. rgbOut.r += (rgbT.r = MULRGB(rgbIn.r, Mul));
  1203. rgbOut.g += (rgbT.g = MULRGB(rgbIn.g, Mul));
  1204. rgbOut.b += (rgbT.b = MULRGB(rgbIn.b, Mul));
  1205. RGB_DIMAX_TO_BYTE(pOut, rgbOut, pOut++);
  1206. rgbOut.r = pMap[rgbIn.r] - rgbT.r;
  1207. rgbOut.g = pMap[rgbIn.g] - rgbT.g;
  1208. rgbOut.b = pMap[rgbIn.b] - rgbT.b;
  1209. } else {
  1210. rgbOut.r += pMap[rgbIn.r];
  1211. rgbOut.g += pMap[rgbIn.g];
  1212. rgbOut.b += pMap[rgbIn.b];
  1213. }
  1214. }
  1215. }
  1216. LONG
  1217. HTENTRY
  1218. ShrinkDIB_CY_SrkCX(
  1219. PAAHEADER pAAHdr
  1220. )
  1221. /*++
  1222. Routine Description:
  1223. This function shrink the scanline down first in Y direction from source
  1224. bitmap when it is done for group of scanlines then it call AXFunc to
  1225. compose current scanline (it may be Shrink(CX) or Expand(CX)) to the
  1226. final output BGR8 buffer
  1227. The shrink is done by sharpen the current pixel first.
  1228. Arguments:
  1229. Return Value:
  1230. Author:
  1231. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1232. Revision History:
  1233. --*/
  1234. {
  1235. AAHEADER AAHdr;
  1236. PSHRINKDATA pSD;
  1237. PBGR8 pICur;
  1238. PBGR8 pOCur;
  1239. PRGBL prgbIn[4];
  1240. PRGBL prgb0;
  1241. PRGBL prgb1;
  1242. PRGBL prgb2;
  1243. PRGBL prgb1End;
  1244. PRGBL prgb2End;
  1245. PLONG pMap;
  1246. PLONG pMapMul;
  1247. PLONG pMapMul2;
  1248. PLONG pMap256Y;
  1249. RGBL rgbT;
  1250. BGR8 rgbIn;
  1251. LONG cbrgbY;
  1252. LONG cyOut;
  1253. UINT cPreLoad;
  1254. UINT cPLCX;
  1255. UINT LargeInc;
  1256. UINT Mul;
  1257. AAHdr = *pAAHdr;
  1258. pMap256Y = AAHdr.pAAInfoCY->pMapMul;
  1259. pMapMul = (PLONG)(AAHdr.pAAInfoCY->pbExtra);
  1260. pMapMul2 = pMapMul + 256;
  1261. cbrgbY = (LONG)((AAHdr.pAAInfoCX->cAADone + 2) * sizeof(RGBL));
  1262. prgbIn[0] = (PRGBL)(pMapMul2 + 256);
  1263. prgbIn[1] = (PRGBL)((LPBYTE)prgbIn[0] + cbrgbY);
  1264. prgbIn[2] = (PRGBL)((LPBYTE)prgbIn[1] + cbrgbY);
  1265. ++prgbIn[0];
  1266. ++prgbIn[1];
  1267. ++prgbIn[2];
  1268. cbrgbY -= (sizeof(RGBL) * 2);
  1269. cPLCX = (UINT)(AAHdr.pAAInfoCX->cPreLoad - 1);
  1270. if (Mul = (UINT)AAHdr.pAAInfoCY->PreMul) {
  1271. SrkYDIB_SrkCX(AAHdr.pAAInfoCX,
  1272. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  1273. pICur = AAHdr.pInputBeg);
  1274. pMap = pMapMul;
  1275. rgbT.r = -(LONG)Mul;
  1276. do {
  1277. pMap[0] = (rgbT.r += Mul);
  1278. } while (++pMap < pMapMul2);
  1279. prgb2 = prgbIn[2];
  1280. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1281. do {
  1282. prgb2->r = pMapMul[(pICur )->r];
  1283. prgb2->g = pMapMul[(pICur )->g];
  1284. prgb2->b = pMapMul[(pICur++)->b];
  1285. } while (++prgb2 < prgb2End);
  1286. //
  1287. // The AAInputFunc() will increment the pointer, so reduced it
  1288. //
  1289. if (!(AAHdr.pAAInfoCY->PreSrcInc)) {
  1290. AAHdr.Flags |= AAHF_GET_LAST_SCAN;
  1291. }
  1292. }
  1293. pSD = (PSHRINKDATA)(AAHdr.pAAInfoCY->pAAData);
  1294. cPreLoad = (UINT)AAHdr.pAAInfoCY->cPreLoad;
  1295. cyOut = 0;
  1296. while (cPreLoad) {
  1297. Mul = (UINT)(pSD++)->Mul;
  1298. prgb2 = prgbIn[2];
  1299. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1300. DBGP_IF(DBGP_PSD,
  1301. DBGP("pSD[%3ld]=%4ld, Flags=0x%04lx"
  1302. ARGDW(pSD - (PSHRINKDATA)(AAHdr.pAAInfoCY->pAAData) - 1)
  1303. ARGDW(Mul & DI_NUM_MASK) ARGDW(Mul & ~DI_NUM_MASK)));
  1304. SrkYDIB_SrkCX(AAHdr.pAAInfoCX,
  1305. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  1306. pICur = AAHdr.pInputBeg);
  1307. if (Mul & SDF_DONE) {
  1308. //
  1309. // Build current Mul Table
  1310. //
  1311. LargeInc = GET_SDF_LARGE_INC(Mul);
  1312. Mul &= SDF_MUL_MASK;
  1313. pMap = pMapMul;
  1314. rgbT.r = -(LONG)Mul;
  1315. rgbT.b = (LONG)(pMap256Y[1] - Mul + LargeInc);
  1316. rgbT.g = -rgbT.b;
  1317. do {
  1318. pMap[ 0] = (rgbT.r += Mul);
  1319. pMap[256] = (rgbT.g += rgbT.b);
  1320. } while (++pMap < pMapMul2);
  1321. //
  1322. // Finished a scanline, so to see if have prev/next to sharpen with
  1323. //
  1324. prgbIn[3] =
  1325. prgb0 = prgbIn[0];
  1326. do {
  1327. (prgb2 )->r += pMapMul[(pICur )->r ];
  1328. (prgb2 )->g += pMapMul[(pICur )->g ];
  1329. (prgb2 )->b += pMapMul[(pICur )->b ];
  1330. (prgb0 )->r = pMapMul[(pICur )->r + 256];
  1331. (prgb0 )->g = pMapMul[(pICur )->g + 256];
  1332. (prgb0++)->b = pMapMul[(pICur++)->b + 256];
  1333. } while (++prgb2 < prgb2End);
  1334. prgbIn[0] = prgbIn[1];
  1335. prgbIn[1] = prgbIn[2];
  1336. prgbIn[2] = prgbIn[3];
  1337. --cPreLoad;
  1338. } else {
  1339. pMap = (PLONG)((LPBYTE)pMap256Y + GET_SDF_LARGE_OFF(Mul));
  1340. do {
  1341. prgb2->r += pMap[(pICur )->r];
  1342. prgb2->g += pMap[(pICur )->g];
  1343. prgb2->b += pMap[(pICur++)->b];
  1344. } while (++prgb2 < prgb2End);
  1345. }
  1346. }
  1347. if (AAHdr.pAAInfoCY->cPreLoad == 1) {
  1348. CopyMemory(prgbIn[0], prgbIn[1], cbrgbY);
  1349. }
  1350. while (Mul = (UINT)((pSD++)->Mul)) {
  1351. prgb2 = prgbIn[2];
  1352. prgb2End = (PRGBL)((LPBYTE)prgb2 + cbrgbY);
  1353. DBGP_IF(DBGP_PSD,
  1354. DBGP("pSD[%3ld]=%4ld, Flags=0x%04lx"
  1355. ARGDW(pSD - (PSHRINKDATA)(AAHdr.pAAInfoCY->pAAData) - 1)
  1356. ARGDW(Mul & DI_NUM_MASK) ARGDW(Mul & ~DI_NUM_MASK)));
  1357. SrkYDIB_SrkCX(AAHdr.pAAInfoCX,
  1358. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  1359. pICur = AAHdr.pInputBeg);
  1360. if (Mul & SDF_DONE) {
  1361. //
  1362. // Build current Mul Table
  1363. //
  1364. LargeInc = GET_SDF_LARGE_INC(Mul);
  1365. Mul &= SDF_MUL_MASK;
  1366. pMap = pMapMul;
  1367. rgbT.r = -(LONG)Mul;
  1368. rgbT.b = (LONG)(pMap256Y[1] - Mul + LargeInc);
  1369. rgbT.g = -rgbT.b;
  1370. do {
  1371. pMap[ 0] = (rgbT.r += Mul);
  1372. pMap[256] = (rgbT.g += rgbT.b);
  1373. } while (++pMap < pMapMul2);
  1374. //
  1375. // Finished a scanline, so to see if have prev/next to sharpen with
  1376. //
  1377. prgbIn[3] =
  1378. prgb0 = prgbIn[0];
  1379. prgb1 = prgbIn[1];
  1380. prgb1End = (PRGBL)((LPBYTE)prgb1 + cbrgbY);
  1381. *(prgb1End ) = *(prgb1End - 1);
  1382. pOCur = (PBGR8)AAHdr.pAABufBeg;
  1383. if (cPLCX) {
  1384. rgbIn = *pICur++;
  1385. (prgb2 )->r += pMapMul[rgbIn.r ];
  1386. (prgb2 )->g += pMapMul[rgbIn.g ];
  1387. (prgb2++)->b += pMapMul[rgbIn.b ];
  1388. (prgb0 )->r = pMapMul[rgbIn.r + 256];
  1389. (prgb0 )->g = pMapMul[rgbIn.g + 256];
  1390. (prgb0++)->b = pMapMul[rgbIn.b + 256];
  1391. ++prgb1;
  1392. } else {
  1393. *(prgb1 - 1) = *prgb1;
  1394. }
  1395. do {
  1396. rgbIn = *pICur++;
  1397. (prgb2 )->r += pMapMul[rgbIn.r];
  1398. (prgb2 )->g += pMapMul[rgbIn.g];
  1399. (prgb2 )->b += pMapMul[rgbIn.b];
  1400. SHARPEN_PRGB_LRTB(pOCur, prgb0, prgb1, prgb2, DI_R_SHIFT);
  1401. (prgb0 )->r = pMapMul[rgbIn.r + 256];
  1402. (prgb0 )->g = pMapMul[rgbIn.g + 256];
  1403. (prgb0++)->b = pMapMul[rgbIn.b + 256];
  1404. ++prgb1;
  1405. ++prgb2;
  1406. } while (((LPBYTE)pOCur += AAHdr.AABufInc) !=
  1407. (LPBYTE)AAHdr.pAABufEnd);
  1408. if (prgb2 < prgb2End) {
  1409. rgbIn = *pICur;
  1410. (prgb2)->r += pMapMul[rgbIn.r ];
  1411. (prgb2)->g += pMapMul[rgbIn.g ];
  1412. (prgb2)->b += pMapMul[rgbIn.b ];
  1413. (prgb0)->r = pMapMul[rgbIn.r + 256];
  1414. (prgb0)->g = pMapMul[rgbIn.g + 256];
  1415. (prgb0)->b = pMapMul[rgbIn.b + 256];
  1416. }
  1417. prgbIn[0] = prgbIn[1];
  1418. prgbIn[1] = prgbIn[2];
  1419. prgbIn[2] = prgbIn[3];
  1420. OUTPUT_AA_CURSCAN;
  1421. ++cyOut;
  1422. } else {
  1423. pMap = (PLONG)((LPBYTE)pMap256Y + GET_SDF_LARGE_OFF(Mul));
  1424. do {
  1425. prgb2->r += pMap[(pICur )->r];
  1426. prgb2->g += pMap[(pICur )->g];
  1427. prgb2->b += pMap[(pICur++)->b];
  1428. } while (++prgb2 < prgb2End);
  1429. }
  1430. }
  1431. if (AAHdr.DstSurfInfo.pb != AAHdr.pOutLast) {
  1432. //
  1433. // Do the last line if exist
  1434. //
  1435. prgb0 = prgbIn[0];
  1436. prgb1 = prgbIn[1];
  1437. prgb1End = (PRGBL)((LPBYTE)prgb1 + cbrgbY);
  1438. *(prgb1End ) = *(prgb1End - 1);
  1439. pOCur = (PBGR8)AAHdr.pAABufBeg;
  1440. *(prgb1 - 1) = *prgb1;
  1441. prgb0 += cPLCX;
  1442. prgb1 += cPLCX;
  1443. do {
  1444. SHARPEN_PRGB_LRTB(pOCur, prgb0, prgb1, prgb1, DI_R_SHIFT);
  1445. ++prgb0;
  1446. ++prgb1;
  1447. } while (((LPBYTE)pOCur += AAHdr.AABufInc) != (LPBYTE)AAHdr.pAABufEnd);
  1448. OUTPUT_AA_CURSCAN;
  1449. ++cyOut;
  1450. }
  1451. ASSERTMSG("Shrink: cScan not equal", cyOut == AAHdr.DstSurfInfo.cy);
  1452. return(cyOut);
  1453. }
  1454. PBGR8
  1455. HTENTRY
  1456. SharpenInput(
  1457. DWORD AAHFlags,
  1458. PBGR8 pbgrS,
  1459. PBGR8 pbgr0,
  1460. PBGR8 pbgr1,
  1461. PBGR8 pbgr2,
  1462. LONG cbBGRIn
  1463. )
  1464. /*++
  1465. Routine Description:
  1466. Arguments:
  1467. Return Value:
  1468. Author:
  1469. 24-Apr-1998 Fri 15:06:58 created -by- Daniel Chou (danielc)
  1470. Revision History:
  1471. --*/
  1472. {
  1473. PBGR8 pSBeg;
  1474. PBGR8 pSEnd;
  1475. PBGR8 pbgr1End;
  1476. pSBeg = pbgrS;
  1477. pSEnd = (PBGR8)((LPBYTE)pbgrS + cbBGRIn);
  1478. pbgr1End = (PBGR8)((LPBYTE)pbgr1 + cbBGRIn);
  1479. if (AAHFlags & AAHF_BBPF_AA_OFF) {
  1480. pSBeg = pbgr1;
  1481. pSEnd = pbgr1End;
  1482. } else {
  1483. *(pbgr1 - 1) = *pbgr1;
  1484. *pbgr1End = *(pbgr1End - 1);
  1485. #if defined(_X86_)
  1486. _asm {
  1487. push ebp
  1488. cld
  1489. mov edi, pbgrS
  1490. mov ebx, pbgr0
  1491. mov esi, pbgr1
  1492. mov edx, pbgr2
  1493. mov ebp, pbgr1End
  1494. jmp DoLoop
  1495. Special1:
  1496. shr eax, 24
  1497. not al
  1498. jmp StoreClr1
  1499. Special2:
  1500. shr eax, 24
  1501. not al
  1502. jmp StoreClr2
  1503. Special3:
  1504. shr eax, 24
  1505. not al
  1506. jmp StoreClr3
  1507. DoLoop:
  1508. movzx eax, BYTE PTR [esi]
  1509. lea eax, [eax * 2 + eax]
  1510. shl eax, 2
  1511. movzx ecx, BYTE PTR [esi - 3]
  1512. sub eax, ecx
  1513. movzx ecx, BYTE PTR [esi + 3]
  1514. sub eax, ecx
  1515. movzx ecx, BYTE PTR [ebx]
  1516. sub eax, ecx
  1517. movzx ecx, BYTE PTR [edx]
  1518. sub eax, ecx
  1519. sar eax, 3
  1520. or ah, ah
  1521. jnz Special1
  1522. StoreClr1:
  1523. stosb
  1524. movzx eax, BYTE PTR [esi + 1]
  1525. lea eax, [eax * 2 + eax]
  1526. shl eax, 2
  1527. movzx ecx, BYTE PTR [esi - 3 + 1]
  1528. sub eax, ecx
  1529. movzx ecx, BYTE PTR [esi + 3 + 1]
  1530. sub eax, ecx
  1531. movzx ecx, BYTE PTR [ebx + 1]
  1532. sub eax, ecx
  1533. movzx ecx, BYTE PTR [edx + 1]
  1534. sub eax, ecx
  1535. sar eax, 3
  1536. or ah, ah
  1537. jnz Special2
  1538. StoreClr2:
  1539. stosb
  1540. movzx eax, BYTE PTR [esi + 2]
  1541. lea eax, [eax * 2 + eax]
  1542. shl eax, 2
  1543. movzx ecx, BYTE PTR [esi - 3 + 2]
  1544. sub eax, ecx
  1545. movzx ecx, BYTE PTR [esi + 3 + 2]
  1546. sub eax, ecx
  1547. movzx ecx, BYTE PTR [ebx + 2]
  1548. sub eax, ecx
  1549. movzx ecx, BYTE PTR [edx + 2]
  1550. sub eax, ecx
  1551. sar eax, 3
  1552. or ah, ah
  1553. jnz Special3
  1554. StoreClr3:
  1555. stosb
  1556. add ebx, 3
  1557. add edx, 3
  1558. add esi, 3
  1559. cmp esi, ebp
  1560. jb DoLoop
  1561. pop ebp
  1562. }
  1563. #else
  1564. while (pbgr1 < pbgr1End) {
  1565. SHARPEN_PRGB_LRTB(pbgrS, pbgr0, pbgr1, pbgr2, 0);
  1566. ++pbgrS;
  1567. ++pbgr0;
  1568. ++pbgr1;
  1569. ++pbgr2;
  1570. }
  1571. #endif
  1572. }
  1573. *(pSBeg - 3) =
  1574. *(pSBeg - 2) =
  1575. *(pSBeg - 1) = *pSBeg;
  1576. *(pSEnd ) =
  1577. *(pSEnd + 1) = *(pSEnd - 1);
  1578. return(pSBeg);
  1579. }
  1580. VOID
  1581. HTENTRY
  1582. ExpandDIB_CX(
  1583. PAAINFO pAAInfo,
  1584. PBGR8 pIn,
  1585. PBGR8 pOut,
  1586. LPBYTE pOutEnd,
  1587. LONG OutInc
  1588. )
  1589. /*++
  1590. Routine Description:
  1591. Arguments:
  1592. Return Value:
  1593. Author:
  1594. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1595. Revision History:
  1596. --*/
  1597. {
  1598. AAINFO AAI = *pAAInfo;
  1599. PBGR8 pInEnd;
  1600. PEXPDATA pED;
  1601. BGR8 rgbIn[8];
  1602. RGBL rgbOut;
  1603. UINT cPreLoad;
  1604. UINT cAAData;
  1605. UINT Idx;
  1606. pInEnd = pIn + AAI.cIn + 2;
  1607. *(pInEnd - 0) =
  1608. *(pInEnd - 1) =
  1609. *(pInEnd - 2) = *(pInEnd - 3);
  1610. rgbIn[5] = *pIn;
  1611. INC_PIN_BY_1ST_LEFT(pIn, AAI.Flags);
  1612. rgbIn[6] = *pIn++;
  1613. cPreLoad = (UINT)AAI.cPreLoad;
  1614. cAAData = (UINT)(cPreLoad >> 4);
  1615. if ((!(cPreLoad &= 0x0F)) && (cAAData)) {
  1616. rgbIn[6] = rgbIn[5];
  1617. ++cPreLoad;
  1618. --cAAData;
  1619. --pIn;
  1620. }
  1621. Idx = 4 - cPreLoad;
  1622. while (cPreLoad--) {
  1623. CopyMemory(&rgbIn[0], &rgbIn[1], sizeof(rgbIn[0]) * 6);
  1624. rgbIn[6] = *pIn++;
  1625. if (AAI.Flags & AAIF_EXP_NO_SHARPEN) {
  1626. rgbIn[3] = rgbIn[5];
  1627. } else {
  1628. SHARPEN_RGB_LR(rgbIn[3], rgbIn[4], rgbIn[5], rgbIn[6], 0);
  1629. }
  1630. DBGP_IF(DBGP_EXP, DBGP("ExpDIB: PreLoad=%ld, pIn=%8lx"
  1631. ARGDW(cPreLoad) ARGPTR(pIn)));
  1632. }
  1633. rgbIn[7] = rgbIn[Idx--];
  1634. while (cAAData--) {
  1635. rgbIn[Idx--] = rgbIn[7];
  1636. }
  1637. pED = (PEXPDATA)(AAI.pAAData);
  1638. pOutEnd += OutInc;
  1639. do {
  1640. EXPDATA ed = *pED++;
  1641. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  1642. CopyMemory(&rgbIn[0], &rgbIn[1], sizeof(rgbIn[0]) * 6);
  1643. rgbIn[6] = *pIn++;
  1644. if (AAI.Flags & AAIF_EXP_NO_SHARPEN) {
  1645. rgbIn[3] = rgbIn[5];
  1646. } else {
  1647. SHARPEN_RGB_LR(rgbIn[3], rgbIn[4], rgbIn[5], rgbIn[6], 0);
  1648. }
  1649. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  1650. }
  1651. rgbOut.r = MULRGB(rgbIn[3].r, ed.Mul[3]);
  1652. rgbOut.g = MULRGB(rgbIn[3].g, ed.Mul[3]);
  1653. rgbOut.b = MULRGB(rgbIn[3].b, ed.Mul[3]);
  1654. if (ed.Mul[2]) {
  1655. rgbOut.r += MULRGB(rgbIn[2].r, ed.Mul[2]);
  1656. rgbOut.g += MULRGB(rgbIn[2].g, ed.Mul[2]);
  1657. rgbOut.b += MULRGB(rgbIn[2].b, ed.Mul[2]);
  1658. if (ed.Mul[1]) {
  1659. rgbOut.r += MULRGB(rgbIn[1].r, ed.Mul[1]);
  1660. rgbOut.g += MULRGB(rgbIn[1].g, ed.Mul[1]);
  1661. rgbOut.b += MULRGB(rgbIn[1].b, ed.Mul[1]);
  1662. if (ed.Mul[0]) {
  1663. rgbOut.r += MULRGB(rgbIn[0].r, ed.Mul[0]);
  1664. rgbOut.g += MULRGB(rgbIn[0].g, ed.Mul[0]);
  1665. rgbOut.b += MULRGB(rgbIn[0].b, ed.Mul[0]);
  1666. }
  1667. }
  1668. }
  1669. RGB_DIMAX_TO_BYTE(pOut, rgbOut, pOut);
  1670. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  1671. ASSERT(pIn <= pInEnd);
  1672. }
  1673. VOID
  1674. HTENTRY
  1675. ExpYDIB_ExpCX(
  1676. PEXPDATA pED,
  1677. PBGR8 pIn,
  1678. PBGR8 pOut,
  1679. PBGR8 pOutEnd
  1680. )
  1681. /*++
  1682. Routine Description:
  1683. Arguments:
  1684. Return Value:
  1685. Author:
  1686. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1687. Revision History:
  1688. --*/
  1689. {
  1690. RGBL rgbOut;
  1691. do {
  1692. UINT Mul;
  1693. EXPDATA ed = *pED++;
  1694. INC_PIN_BY_EDF_LOAD_PIXEL(pIn, ed.Mul[0]);
  1695. Mul = (UINT)ed.Mul[3];
  1696. rgbOut.r = MULRGB(pIn->r, Mul);
  1697. rgbOut.g = MULRGB(pIn->g, Mul);
  1698. rgbOut.b = MULRGB(pIn->b, Mul);
  1699. if (Mul = (UINT)ed.Mul[2]) {
  1700. rgbOut.r += MULRGB((pIn - 1)->r, Mul);
  1701. rgbOut.g += MULRGB((pIn - 1)->g, Mul);
  1702. rgbOut.b += MULRGB((pIn - 1)->b, Mul);
  1703. if (Mul = (UINT)ed.Mul[1]) {
  1704. rgbOut.r += MULRGB((pIn - 2)->r, Mul);
  1705. rgbOut.g += MULRGB((pIn - 2)->g, Mul);
  1706. rgbOut.b += MULRGB((pIn - 2)->b, Mul);
  1707. if (Mul = (UINT)(ed.Mul[0] & ~(EDF_LOAD_PIXEL |
  1708. EDF_NO_NEWSRC))) {
  1709. rgbOut.r += MULRGB((pIn - 3)->r, Mul);
  1710. rgbOut.g += MULRGB((pIn - 3)->g, Mul);
  1711. rgbOut.b += MULRGB((pIn - 3)->b, Mul);
  1712. }
  1713. }
  1714. }
  1715. RGB_DIMAX_TO_BYTE(pOut, rgbOut, pOut);
  1716. } while (++pOut != pOutEnd);
  1717. }
  1718. LONG
  1719. HTENTRY
  1720. ExpandDIB_CY_ExpCX(
  1721. PAAHEADER pAAHdr
  1722. )
  1723. /*++
  1724. Routine Description:
  1725. This funtion anti-alias the bitmap by query scanlines from CX direction
  1726. (may be Shrink(CX) or Expand(CX)) then compose current scanlines and output
  1727. it to real BGR8 final buffer,
  1728. The complication is need to have scanline one before current destination
  1729. scanline, this may be because the source is not available or because the
  1730. clipping is done on destination.
  1731. Since the anti-alias for expanding requred at least four surounding
  1732. scanlines to compose current scanline, it required large amount of
  1733. memory to retain the prevous result scanlines
  1734. The expanding is by sharpen the source pixel first before anti-aliasing
  1735. smooth through
  1736. prgbIn[0] - Previous un-sharpen source scan
  1737. AND Last The 4th composition sharpened scan after sharpen
  1738. prgbIn[1] - Current un-sharpen source scan
  1739. prgbIn[2] - Next un-sharpen source scan
  1740. prgbIn[3] - The 1st composition sharpened scan
  1741. prgbIn[4] - The 2nd composition sharpened scan
  1742. prgbIn[5] - The 3rd composition sharpened scan
  1743. Exp=Load Sharpen Exp
  1744. Srk=Load Srk Sharpen
  1745. Cpy=Load Cpy
  1746. Exp_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX) SharpenY ExpY
  1747. Exp_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX) SharpenY ExpY
  1748. Exp_CY:Cpy_CX Cpy_CX:(LoadX CpyX ) SharpenY ExpY
  1749. Srk_CY:Exp_CX InputCX SrkY SharpenY Exp_CX:(LoadX SharpenX ExpX)
  1750. Srk_CY:Srk_CX InputCX SrkY SharpenY Srk_CX:(LoadX SrkX SharpenX)
  1751. Srk_CY:Cpy_CX InputCX SrkY SharpenY Cpy_CX:(LoadX CpyX )
  1752. Cpy_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX)
  1753. Cpy_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX)
  1754. Cpy_CY:Cpy_CX Cpy_CX:(LoadX CpyX )
  1755. Arguments:
  1756. Return Value:
  1757. Author:
  1758. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1759. Revision History:
  1760. --*/
  1761. {
  1762. AAHEADER AAHdr = *pAAHdr;
  1763. PAAINFO pAAInfo;
  1764. PEXPDATA pED;
  1765. PEXPDATA pEDCX;
  1766. PBGR8 prgbOut[4];
  1767. PBGR8 prgbS;
  1768. PLONG pMap;
  1769. PLONG pMap0;
  1770. PLONG pMap0End;
  1771. PBGR8 prgbIn0;
  1772. PBGR8 prgbIn1;
  1773. PBGR8 prgbIn2;
  1774. PBGR8 prgb0;
  1775. PBGR8 prgb1;
  1776. PBGR8 prgb2;
  1777. PBGR8 prgb3;
  1778. PBGR8 pOCur;
  1779. EXPDATA ed;
  1780. LONG cb1stSharpen;
  1781. LONG cbrgbY;
  1782. LONG cbrgbIn;
  1783. LONG cAAData;
  1784. LONG cPreLoad;
  1785. UINT IdxOut;
  1786. //
  1787. // Figure out the horizontal scan line increment
  1788. //
  1789. pAAInfo = AAHdr.pAAInfoCX;
  1790. cPreLoad = (LONG)(pAAInfo->cPreLoad & 0x0F) - 1 +
  1791. (LONG)((pAAInfo->Flags & AAIF_EXP_HAS_1ST_LEFT) ? 1 : 0);
  1792. pEDCX = (PEXPDATA)(pAAInfo->pAAData);
  1793. pAAInfo = AAHdr.pAAInfoCY;
  1794. pMap0 = (PLONG)pAAInfo->pbExtra;
  1795. pMap0End = pMap0 + 256;
  1796. cbrgbIn = AAHdr.SrcSurfInfo.cx * sizeof(BGR8);
  1797. cbrgbY = AAHdr.DstSurfInfo.cx * sizeof(BGR8);
  1798. prgbOut[0] = (PBGR8)(pMap0 + (256 * 4));
  1799. prgbOut[1] = (PBGR8)((LPBYTE)prgbOut[0] + cbrgbY);
  1800. prgbOut[2] = (PBGR8)((LPBYTE)prgbOut[1] + cbrgbY);
  1801. prgbOut[3] = (PBGR8)((LPBYTE)prgbOut[2] + cbrgbY);
  1802. prgbIn0 = (PBGR8)((LPBYTE)prgbOut[3] + cbrgbY) + 3;
  1803. prgbIn1 = (PBGR8)((LPBYTE)prgbIn0 + cbrgbIn) + 6;
  1804. prgbIn2 = (PBGR8)((LPBYTE)prgbIn1 + cbrgbIn) + 6;
  1805. prgbS = AAHdr.pInputBeg + 3;
  1806. cb1stSharpen = (LONG)(sizeof(BGR8) * cPreLoad);
  1807. IdxOut = ~0;
  1808. DBGP_IF(DBGP_AAHT_MEM,
  1809. DBGP("prgbIn=%p:%p:%p, prgbOut=%p:%p:%p:%p, prgbS=%p, cb1stSharpen=%ld"
  1810. ARGPTR(prgbIn0) ARGPTR(prgbIn1) ARGPTR(prgbIn2)
  1811. ARGPTR(prgbOut[0]) ARGPTR(prgbOut[1]) ARGPTR(prgbOut[2])
  1812. ARGPTR(prgbOut[3]) ARGPTR(prgbS) ARGDW(cb1stSharpen)));
  1813. //
  1814. // Always read first source
  1815. //
  1816. DBGP_IF(DBGP_EXPAND, DBGP("\nExpand: PRE-LOAD FIRST SCAN"));
  1817. GetFixupScan(&AAHdr, prgbIn1);
  1818. if (pAAInfo->Flags & AAIF_EXP_HAS_1ST_LEFT) {
  1819. DBGP_IF(DBGP_EXPAND, DBGP("Expand: LOAD FIRST LEFT"));
  1820. GetFixupScan(&AAHdr, prgbIn2);
  1821. } else {
  1822. DBGP_IF(DBGP_EXPAND, DBGP("Expand: COPY FIRST LEFT"));
  1823. CopyMemory(prgbIn2, prgbIn1, cbrgbIn);
  1824. }
  1825. //
  1826. // cPreLoad: Low 4 bits means real load, high 4 bit means imaginary load
  1827. //
  1828. DBGP_IF(DBGP_EXPAND,
  1829. DBGP("cPreLoad=%02lx: AAData[0]=%6ld:%6ld:%6ld:%6ld, %hs"
  1830. ARGDW(pAAInfo->cPreLoad)
  1831. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[0] &
  1832. ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC))
  1833. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[1])
  1834. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[2])
  1835. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[3])
  1836. ARGPTR((((PEXPDATA)(pAAInfo->pAAData))->Mul[0] & EDF_LOAD_PIXEL) ?
  1837. "Load Pixel" : "")));
  1838. cPreLoad = (LONG)pAAInfo->cPreLoad;
  1839. cAAData = (LONG)(cPreLoad >> 4);
  1840. cPreLoad = (cPreLoad & 0x0F) + cAAData;
  1841. while (cPreLoad--) {
  1842. //
  1843. // Scroll up one input scan line
  1844. //
  1845. prgb0 = prgbIn0;
  1846. prgbIn0 = prgbIn1;
  1847. prgbIn1 = prgbIn2;
  1848. prgbIn2 = prgb0;
  1849. prgb3 = prgbOut[++IdxOut & 0x03];
  1850. if (cAAData-- > 0) {
  1851. DBGP_IF(DBGP_EXPAND,
  1852. DBGP("FAKE SCAN: cPreLoad=%ld/cAAData=%ld, Compose IdxOut=%ld"
  1853. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)
  1854. ARGDW(IdxOut & 0x03)));
  1855. CopyMemory(prgbIn2, prgbIn1, cbrgbIn);
  1856. } else {
  1857. DBGP_IF(DBGP_EXPAND,
  1858. DBGP("REAL SCAN: cPreLoad=%ld, Compose IdxOut=%ld"
  1859. ARGDW(cPreLoad + 1) ARGDW(IdxOut & 0x03)));
  1860. GetFixupScan(&AAHdr, prgbIn2);
  1861. }
  1862. prgbS = SharpenInput(AAHdr.Flags,
  1863. prgbS,
  1864. prgbIn0,
  1865. prgbIn1,
  1866. prgbIn2,
  1867. cbrgbIn);
  1868. ExpYDIB_ExpCX(pEDCX,
  1869. (PBGR8)((LPBYTE)prgbS + cb1stSharpen),
  1870. prgb3,
  1871. (PBGR8)((LPBYTE)prgb3 + cbrgbY));
  1872. }
  1873. pED = (PEXPDATA)(pAAInfo->pAAData);
  1874. cAAData = pAAInfo->cAAData;
  1875. while (cAAData--) {
  1876. LONG Mul0;
  1877. LONG Mul1;
  1878. LONG Mul2;
  1879. LONG Mul3;
  1880. ed = *pED++;
  1881. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  1882. prgb0 = prgbIn0;
  1883. prgbIn0 = prgbIn1;
  1884. prgbIn1 = prgbIn2;
  1885. prgbIn2 = GetFixupScan(&AAHdr, prgb0);
  1886. prgbS = SharpenInput(AAHdr.Flags,
  1887. prgbS,
  1888. prgbIn0,
  1889. prgbIn1,
  1890. prgbIn2,
  1891. cbrgbIn);
  1892. prgb3 = prgbOut[++IdxOut & 0x03];
  1893. ExpYDIB_ExpCX(pEDCX,
  1894. (PBGR8)((LPBYTE)prgbS + cb1stSharpen),
  1895. prgb3,
  1896. (PBGR8)((LPBYTE)prgb3 + cbrgbY));
  1897. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  1898. }
  1899. //
  1900. // Build Mul Table here
  1901. //
  1902. pMap = pMap0;
  1903. Mul0 = -ed.Mul[0];
  1904. Mul1 = -ed.Mul[1];
  1905. Mul2 = -ed.Mul[2];
  1906. Mul3 = -ed.Mul[3];
  1907. prgb3 = prgbOut[(IdxOut ) & 0x03];
  1908. prgb2 = prgbOut[(IdxOut - 1) & 0x03];
  1909. pOCur = (PBGR8)AAHdr.pAABufBeg;
  1910. if (ed.Mul[0]) {
  1911. prgb1 = prgbOut[(IdxOut - 2) & 0x03];
  1912. prgb0 = prgbOut[(IdxOut - 3) & 0x03];
  1913. GET_EXP_PC(PMAP_EXP4, GET_EXP4, INC_EXP4, pOCur);
  1914. } else if (ed.Mul[1]) {
  1915. prgb1 = prgbOut[(IdxOut - 2) & 0x03];
  1916. GET_EXP_PC(PMAP_EXP3, GET_EXP3, INC_EXP3, pOCur);
  1917. } else if (ed.Mul[2]) {
  1918. GET_EXP_PC(PMAP_EXP2, GET_EXP2, INC_EXP2, pOCur);
  1919. } else {
  1920. GET_EXP_PC(PMAP_EXP1, GET_EXP1, INC_EXP1, pOCur);
  1921. }
  1922. OUTPUT_AA_CURSCAN;
  1923. }
  1924. return(AAHdr.DstSurfInfo.cy);
  1925. }
  1926. LONG
  1927. HTENTRY
  1928. ExpandDIB_CY(
  1929. PAAHEADER pAAHdr
  1930. )
  1931. /*++
  1932. Routine Description:
  1933. This funtion anti-alias the bitmap by query scanlines from CX direction
  1934. (may be Shrink(CX) or Expand(CX)) then compose current scanlines and output
  1935. it to real BGR8 final buffer,
  1936. The complication is need to have scanline one before current destination
  1937. scanline, this may be because the source is not available or because the
  1938. clipping is done on destination.
  1939. Since the anti-alias for expanding requred at least four surounding
  1940. scanlines to compose current scanline, it required large amount of
  1941. memory to retain the prevous result scanlines
  1942. The expanding is by sharpen the source pixel first before anti-aliasing
  1943. smooth through
  1944. prgbIn[0] - Previous un-sharpen source scan
  1945. AND Last The 4th composition sharpened scan after sharpen
  1946. prgbIn[1] - Current un-sharpen source scan
  1947. prgbIn[2] - Next un-sharpen source scan
  1948. prgbIn[3] - The 1st composition sharpened scan
  1949. prgbIn[4] - The 2nd composition sharpened scan
  1950. prgbIn[5] - The 3rd composition sharpened scan
  1951. Exp=Load Sharpen Exp
  1952. Srk=Load Srk Sharpen
  1953. Cpy=Load Cpy
  1954. Exp_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX) SharpenY ExpY
  1955. Exp_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX) SharpenY ExpY
  1956. Exp_CY:Cpy_CX Cpy_CX:(LoadX CpyX ) SharpenY ExpY
  1957. Srk_CY:Exp_CX InputCX SrkY SharpenY Exp_CX:(LoadX SharpenX ExpX)
  1958. Srk_CY:Srk_CX InputCX SrkY SharpenY Srk_CX:(LoadX SrkX SharpenX)
  1959. Srk_CY:Cpy_CX InputCX SrkY SharpenY Cpy_CX:(LoadX CpyX )
  1960. Cpy_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX)
  1961. Cpy_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX)
  1962. Cpy_CY:Cpy_CX Cpy_CX:(LoadX CpyX )
  1963. Arguments:
  1964. Return Value:
  1965. Author:
  1966. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  1967. Revision History:
  1968. --*/
  1969. {
  1970. AAHEADER AAHdr = *pAAHdr;
  1971. PEXPDATA pED;
  1972. PBGR8 prgbIn[6];
  1973. PLONG pMap;
  1974. PLONG pMap0;
  1975. PLONG pMap0End;
  1976. PBGR8 prgb0;
  1977. PBGR8 prgb1;
  1978. PBGR8 prgb2;
  1979. PBGR8 prgb3;
  1980. PBGR8 prgb4;
  1981. PBGR8 prgb5;
  1982. PBGR8 pOCur;
  1983. LPBYTE prgbYEnd;
  1984. LONG cbrgbY;
  1985. LONG cAAData;
  1986. LONG cPreLoad;
  1987. pMap0 = (PLONG)AAHdr.pAAInfoCY->pbExtra;
  1988. pMap0End = pMap0 + 256;
  1989. cbrgbY = (AAHdr.DstSurfInfo.cx + 6) * (LONG)sizeof(BGR8);
  1990. prgbIn[0] = (PBGR8)(pMap0 + (256 * 4)) + 3;
  1991. prgbIn[1] = (PBGR8)((LPBYTE)prgbIn[0] + cbrgbY);
  1992. prgbIn[2] = (PBGR8)((LPBYTE)prgbIn[1] + cbrgbY);
  1993. prgbIn[3] = (PBGR8)((LPBYTE)prgbIn[2] + cbrgbY);
  1994. prgbIn[4] = (PBGR8)((LPBYTE)prgbIn[3] + cbrgbY);
  1995. prgbIn[5] = (PBGR8)((LPBYTE)prgbIn[4] + cbrgbY);
  1996. cbrgbY -= (sizeof(BGR8) * 6);
  1997. //
  1998. // Always read first source
  1999. //
  2000. DBGP_IF(DBGP_EXPAND, DBGP("\nLoad First Scan"));
  2001. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2002. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2003. prgbIn[4],
  2004. (LPBYTE)prgbIn[4] + cbrgbY,
  2005. sizeof(BGR8));
  2006. //
  2007. // Load the PRE-SOURCE LEFT first source first
  2008. //
  2009. if (AAHdr.pAAInfoCY->Flags & AAIF_EXP_HAS_1ST_LEFT) {
  2010. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2011. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2012. prgbIn[5],
  2013. (LPBYTE)prgbIn[5] + cbrgbY,
  2014. sizeof(BGR8));
  2015. DBGP_IF(DBGP_EXPAND, DBGP("Load First Left"));
  2016. } else {
  2017. CopyMemory(prgbIn[5], prgbIn[4], cbrgbY);
  2018. DBGP_IF(DBGP_EXPAND, DBGP("Copy First Left"));
  2019. }
  2020. cPreLoad = (LONG)AAHdr.pAAInfoCY->cPreLoad;
  2021. cAAData = (LONG)(cPreLoad >> 4);
  2022. cPreLoad = (cPreLoad & 0x0F) + cAAData;
  2023. while (cPreLoad--) {
  2024. //
  2025. // Scroll up prgbIn by one scan
  2026. //
  2027. prgb5 = prgbIn[0];
  2028. CopyMemory(&prgbIn[0], &prgbIn[1], sizeof(prgbIn[0]) * 5);
  2029. prgbIn[5] = prgb5;
  2030. prgb3 = prgbIn[3];
  2031. prgb4 = prgbIn[4];
  2032. prgb5 = prgbIn[5];
  2033. prgbYEnd = (LPBYTE)prgb5 + cbrgbY;
  2034. if (cAAData-- > 0) {
  2035. DBGP_IF(DBGP_EXPAND,
  2036. DBGP("FAKE SCAN: cPreLoad=%ld/cAAData=%ld"
  2037. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)));
  2038. CopyMemory(prgb5, prgb4, cbrgbY);
  2039. } else {
  2040. DBGP_IF(DBGP_EXPAND,
  2041. DBGP("REAL SCAN: cPreLoad=%ld/cAAData=%ld"
  2042. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)));
  2043. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2044. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2045. prgb5,
  2046. prgbYEnd,
  2047. sizeof(BGR8));
  2048. }
  2049. DBGP_IF(DBGP_EXPAND,
  2050. DBGP("Compose Sharpen Scan=%ld" ARGDW(cPreLoad + 1)));
  2051. //
  2052. // Now, let's sharpen the input
  2053. //
  2054. if (AAHdr.Flags & AAHF_BBPF_AA_OFF) {
  2055. CopyMemory(prgb3, prgb4, cbrgbY);
  2056. } else {
  2057. do {
  2058. SHARPEN_PRGB_LR(prgb3, (*prgb3), (*prgb4), (*prgb5), 0);
  2059. prgb3++;
  2060. prgb4++;
  2061. } while (++prgb5 < (PBGR8)prgbYEnd);
  2062. }
  2063. }
  2064. pED = (PEXPDATA)(AAHdr.pAAInfoCY->pAAData);
  2065. cAAData = AAHdr.pAAInfoCY->cAAData;
  2066. while (cAAData--) {
  2067. EXPDATA ed = *pED++;
  2068. LONG Mul0;
  2069. LONG Mul1;
  2070. LONG Mul2;
  2071. LONG Mul3;
  2072. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  2073. prgb5 = prgbIn[0];
  2074. CopyMemory(&prgbIn[0], &prgbIn[1], sizeof(prgbIn[0]) * 5);
  2075. prgbIn[5] = prgb5;
  2076. prgb3 = prgbIn[3];
  2077. prgb4 = prgbIn[4];
  2078. prgb5 = prgbIn[5];
  2079. prgbYEnd = (LPBYTE)prgb5 + cbrgbY;
  2080. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2081. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2082. prgb5,
  2083. prgbYEnd,
  2084. sizeof(BGR8));
  2085. if (AAHdr.Flags & AAHF_BBPF_AA_OFF) {
  2086. CopyMemory(prgb3, prgb4, cbrgbY);
  2087. } else {
  2088. do {
  2089. SHARPEN_PRGB_LR(prgb3, (*prgb3), (*prgb4), (*prgb5), 0);
  2090. prgb3++;
  2091. prgb4++;
  2092. } while (++prgb5 < (PBGR8)prgbYEnd);
  2093. }
  2094. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  2095. }
  2096. //
  2097. // Build Mul Table here
  2098. //
  2099. pMap = pMap0;
  2100. Mul0 = -ed.Mul[0];
  2101. Mul1 = -ed.Mul[1];
  2102. Mul2 = -ed.Mul[2];
  2103. Mul3 = -ed.Mul[3];
  2104. prgb3 = prgbIn[3];
  2105. prgb2 = prgbIn[2];
  2106. pOCur = (PBGR8)AAHdr.pAABufBeg;
  2107. if (ed.Mul[0]) {
  2108. prgb1 = prgbIn[1];
  2109. prgb0 = prgbIn[0];
  2110. GET_EXP_PC(PMAP_EXP4, GET_EXP4, INC_EXP4, pOCur);
  2111. } else if (ed.Mul[1]) {
  2112. prgb1 = prgbIn[1];
  2113. GET_EXP_PC(PMAP_EXP3, GET_EXP3, INC_EXP3, pOCur);
  2114. } else if (ed.Mul[2]) {
  2115. GET_EXP_PC(PMAP_EXP2, GET_EXP2, INC_EXP2, pOCur);
  2116. } else {
  2117. GET_EXP_PC(PMAP_EXP1, GET_EXP1, INC_EXP1, pOCur);
  2118. }
  2119. OUTPUT_AA_CURSCAN;
  2120. }
  2121. return(AAHdr.DstSurfInfo.cy);
  2122. }
  2123. //
  2124. // Monochrome routine
  2125. //
  2126. LPBYTE
  2127. HTENTRY
  2128. GraySharpenInput(
  2129. DWORD AAHFlags,
  2130. LPBYTE pbS,
  2131. LPBYTE pb0,
  2132. LPBYTE pb1,
  2133. LPBYTE pb2,
  2134. LONG cbIn
  2135. )
  2136. /*++
  2137. Routine Description:
  2138. Arguments:
  2139. Return Value:
  2140. Author:
  2141. 24-Apr-1998 Fri 15:06:58 created -by- Daniel Chou (danielc)
  2142. Revision History:
  2143. --*/
  2144. {
  2145. LPBYTE pSBeg;
  2146. LPBYTE pSEnd;
  2147. LPBYTE pb1End;
  2148. pSBeg = pbS;
  2149. pSEnd = (LPBYTE)((LPBYTE)pbS + cbIn);
  2150. pb1End = (LPBYTE)((LPBYTE)pb1 + cbIn);
  2151. if (AAHFlags & AAHF_BBPF_AA_OFF) {
  2152. pSBeg = pb1;
  2153. pSEnd = pb1End;
  2154. } else {
  2155. *(pb1 - 1) = *pb1;
  2156. *pb1End = *(pb1End - 1);
  2157. #if defined(_X86_)
  2158. _asm {
  2159. cld
  2160. mov edi, pbS
  2161. mov ebx, pb0
  2162. mov esi, pb1
  2163. mov edx, pb2
  2164. mov eax, cbIn
  2165. shr eax, 2
  2166. jz DoneLoop1
  2167. push ebp
  2168. mov ebp, eax
  2169. jmp DoLoop1
  2170. DoSP1: shr eax, 24
  2171. not al
  2172. jmp StoreClr1
  2173. DoSP2: shr eax, 24
  2174. not al
  2175. jmp StoreClr2
  2176. DoSP3: shr eax, 24
  2177. not al
  2178. jmp StoreClr3
  2179. DoSP4: shr eax, 24
  2180. not al
  2181. jmp StoreClr4
  2182. DoLoop1:
  2183. movzx eax, BYTE PTR [esi]
  2184. lea eax, [eax * 2 + eax]
  2185. shl eax, 2
  2186. movzx ecx, BYTE PTR [esi - 1]
  2187. sub eax, ecx
  2188. movzx ecx, BYTE PTR [esi + 1]
  2189. sub eax, ecx
  2190. movzx ecx, BYTE PTR [ebx]
  2191. sub eax, ecx
  2192. movzx ecx, BYTE PTR [edx]
  2193. sub eax, ecx
  2194. sar eax, 3
  2195. or ah, ah
  2196. jnz DoSP1
  2197. StoreClr1:
  2198. stosb
  2199. movzx eax, BYTE PTR [esi + 1]
  2200. lea eax, [eax * 2 + eax]
  2201. shl eax, 2
  2202. movzx ecx, BYTE PTR [esi - 1 + 1]
  2203. sub eax, ecx
  2204. movzx ecx, BYTE PTR [esi + 1 + 1]
  2205. sub eax, ecx
  2206. movzx ecx, BYTE PTR [ebx + 1]
  2207. sub eax, ecx
  2208. movzx ecx, BYTE PTR [edx + 1]
  2209. sub eax, ecx
  2210. sar eax, 3
  2211. or ah, ah
  2212. jnz DoSP2
  2213. StoreClr2:
  2214. stosb
  2215. movzx eax, BYTE PTR [esi + 2]
  2216. lea eax, [eax * 2 + eax]
  2217. shl eax, 2
  2218. movzx ecx, BYTE PTR [esi - 1 + 2]
  2219. sub eax, ecx
  2220. movzx ecx, BYTE PTR [esi + 1 + 2]
  2221. sub eax, ecx
  2222. movzx ecx, BYTE PTR [ebx + 2]
  2223. sub eax, ecx
  2224. movzx ecx, BYTE PTR [edx + 2]
  2225. sub eax, ecx
  2226. sar eax, 3
  2227. or ah, ah
  2228. jnz DoSP3
  2229. StoreClr3:
  2230. stosb
  2231. movzx eax, BYTE PTR [esi + 3]
  2232. lea eax, [eax * 2 + eax]
  2233. shl eax, 2
  2234. movzx ecx, BYTE PTR [esi - 1 + 3]
  2235. sub eax, ecx
  2236. movzx ecx, BYTE PTR [esi + 1 + 3]
  2237. sub eax, ecx
  2238. movzx ecx, BYTE PTR [ebx + 3]
  2239. sub eax, ecx
  2240. movzx ecx, BYTE PTR [edx + 3]
  2241. sub eax, ecx
  2242. sar eax, 3
  2243. or ah, ah
  2244. jnz DoSP4
  2245. StoreClr4:
  2246. stosb
  2247. add ebx, 4
  2248. add edx, 4
  2249. add esi, 4
  2250. dec ebp
  2251. jnz DoLoop1
  2252. pop ebp
  2253. DoneLoop1:
  2254. mov eax, cbIn
  2255. and eax, 3
  2256. jz DoneLoop2
  2257. push ebp
  2258. mov ebp, eax
  2259. jmp DoLoop2
  2260. DoSP5: shr eax, 24
  2261. not al
  2262. jmp StoreClr5
  2263. DoLoop2:
  2264. movzx eax, BYTE PTR [esi]
  2265. lea eax, [eax * 2 + eax]
  2266. shl eax, 2
  2267. movzx ecx, BYTE PTR [esi - 1]
  2268. sub eax, ecx
  2269. movzx ecx, BYTE PTR [esi + 1]
  2270. sub eax, ecx
  2271. movzx ecx, BYTE PTR [ebx]
  2272. sub eax, ecx
  2273. movzx ecx, BYTE PTR [edx]
  2274. sub eax, ecx
  2275. sar eax, 3
  2276. or ah, ah
  2277. jnz DoSP5
  2278. StoreClr5:
  2279. stosb
  2280. inc esi
  2281. inc ebx
  2282. inc edx
  2283. dec ebp
  2284. jnz DoLoop2
  2285. pop ebp
  2286. DoneLoop2:
  2287. }
  2288. #else
  2289. while (pb1 < pb1End) {
  2290. SHARPEN_PB_LRTB(pbS, pb0, pb1, pb2, 0);
  2291. ++pbS;
  2292. ++pb0;
  2293. ++pb1;
  2294. ++pb2;
  2295. }
  2296. #endif
  2297. }
  2298. *(pSBeg - 3) =
  2299. *(pSBeg - 2) =
  2300. *(pSBeg - 1) = *pSBeg;
  2301. *(pSEnd ) =
  2302. *(pSEnd + 1) = *(pSEnd - 1);
  2303. return(pSBeg);
  2304. }
  2305. VOID
  2306. HTENTRY
  2307. GrayCopyDIB_CX(
  2308. PAAINFO pAAInfo,
  2309. LPBYTE pIn,
  2310. LPBYTE pOut,
  2311. LPBYTE pOutEnd,
  2312. LONG OutInc
  2313. )
  2314. /*++
  2315. Routine Description:
  2316. Arguments:
  2317. Return Value:
  2318. Author:
  2319. 26-Jun-1998 Fri 11:33:20 created -by- Daniel Chou (danielc)
  2320. Revision History:
  2321. --*/
  2322. {
  2323. do {
  2324. *pOut = *pIn++;
  2325. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  2326. }
  2327. VOID
  2328. HTENTRY
  2329. GrayExpYDIB_ExpCX(
  2330. PEXPDATA pED,
  2331. LPBYTE pIn,
  2332. LPBYTE pOut,
  2333. LPBYTE pOutEnd
  2334. )
  2335. /*++
  2336. Routine Description:
  2337. Arguments:
  2338. Return Value:
  2339. Author:
  2340. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2341. Revision History:
  2342. --*/
  2343. {
  2344. do {
  2345. EXPDATA ed = *pED++;
  2346. LONG Gray;
  2347. UINT Mul;
  2348. INC_PIN_BY_EDF_LOAD_PIXEL(pIn, ed.Mul[0]);
  2349. Mul = (UINT)ed.Mul[3];
  2350. Gray = MULRGB(*pIn, Mul);
  2351. if (Mul = (UINT)ed.Mul[2]) {
  2352. Gray += MULRGB(*(pIn - 1), Mul);
  2353. if (Mul = (UINT)ed.Mul[1]) {
  2354. Gray += MULRGB(*(pIn - 2), Mul);
  2355. if (Mul = (UINT)(ed.Mul[0] & ~(EDF_LOAD_PIXEL |
  2356. EDF_NO_NEWSRC))) {
  2357. Gray += MULRGB(*(pIn - 3), Mul);
  2358. }
  2359. }
  2360. }
  2361. GRAY_DIMAX_TO_BYTE(pOut, Gray);
  2362. } while (++pOut != pOutEnd);
  2363. }
  2364. LONG
  2365. HTENTRY
  2366. GrayExpandDIB_CY_ExpCX(
  2367. PAAHEADER pAAHdr
  2368. )
  2369. /*++
  2370. Routine Description:
  2371. This funtion anti-alias the bitmap by query scanlines from CX direction
  2372. (may be Shrink(CX) or Expand(CX)) then compose current scanlines and output
  2373. it to real BGR8 final buffer,
  2374. The complication is need to have scanline one before current destination
  2375. scanline, this may be because the source is not available or because the
  2376. clipping is done on destination.
  2377. Since the anti-alias for expanding requred at least four surounding
  2378. scanlines to compose current scanline, it required large amount of
  2379. memory to retain the prevous result scanlines
  2380. The expanding is by sharpen the source pixel first before anti-aliasing
  2381. smooth through
  2382. prgbIn[0] - Previous un-sharpen source scan
  2383. AND Last The 4th composition sharpened scan after sharpen
  2384. prgbIn[1] - Current un-sharpen source scan
  2385. prgbIn[2] - Next un-sharpen source scan
  2386. prgbIn[3] - The 1st composition sharpened scan
  2387. prgbIn[4] - The 2nd composition sharpened scan
  2388. prgbIn[5] - The 3rd composition sharpened scan
  2389. Exp=Load Sharpen Exp
  2390. Srk=Load Srk Sharpen
  2391. Cpy=Load Cpy
  2392. Exp_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX) SharpenY ExpY
  2393. Exp_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX) SharpenY ExpY
  2394. Exp_CY:Cpy_CX Cpy_CX:(LoadX CpyX ) SharpenY ExpY
  2395. Srk_CY:Exp_CX InputCX SrkY SharpenY Exp_CX:(LoadX SharpenX ExpX)
  2396. Srk_CY:Srk_CX InputCX SrkY SharpenY Srk_CX:(LoadX SrkX SharpenX)
  2397. Srk_CY:Cpy_CX InputCX SrkY SharpenY Cpy_CX:(LoadX CpyX )
  2398. Cpy_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX)
  2399. Cpy_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX)
  2400. Cpy_CY:Cpy_CX Cpy_CX:(LoadX CpyX )
  2401. Arguments:
  2402. Return Value:
  2403. Author:
  2404. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2405. Revision History:
  2406. --*/
  2407. {
  2408. AAHEADER AAHdr = *pAAHdr;
  2409. PAAINFO pAAInfo;
  2410. PEXPDATA pED;
  2411. PEXPDATA pEDCX;
  2412. LPBYTE pbOut[4];
  2413. LPBYTE pbS;
  2414. PLONG pMap;
  2415. PLONG pMap0;
  2416. PLONG pMap0End;
  2417. LPBYTE pbIn0;
  2418. LPBYTE pbIn1;
  2419. LPBYTE pbIn2;
  2420. LPBYTE pb0;
  2421. LPBYTE pb1;
  2422. LPBYTE pb2;
  2423. LPBYTE pb3;
  2424. PGRAYF pOCur;
  2425. EXPDATA ed;
  2426. LONG cb1stSharpen;
  2427. LONG cbY;
  2428. LONG cbIn;
  2429. LONG cAAData;
  2430. LONG cPreLoad;
  2431. UINT IdxOut;
  2432. //
  2433. // Figure out the horizontal scan line increment
  2434. //
  2435. pAAInfo = AAHdr.pAAInfoCX;
  2436. cPreLoad = (LONG)(pAAInfo->cPreLoad & 0x0F) - 1 +
  2437. (LONG)((pAAInfo->Flags & AAIF_EXP_HAS_1ST_LEFT) ? 1 : 0);
  2438. pEDCX = (PEXPDATA)(pAAInfo->pAAData);
  2439. pAAInfo = AAHdr.pAAInfoCY;
  2440. pMap0 = (PLONG)pAAInfo->pbExtra;
  2441. pMap0End = pMap0 + 256;
  2442. cbIn = AAHdr.SrcSurfInfo.cx * sizeof(BYTE);
  2443. cbY = AAHdr.DstSurfInfo.cx * sizeof(BYTE);
  2444. pbOut[0] = (LPBYTE)(pMap0 + (256 * 4));
  2445. pbOut[1] = (LPBYTE)((LPBYTE)pbOut[0] + cbY);
  2446. pbOut[2] = (LPBYTE)((LPBYTE)pbOut[1] + cbY);
  2447. pbOut[3] = (LPBYTE)((LPBYTE)pbOut[2] + cbY);
  2448. pbIn0 = (LPBYTE)((LPBYTE)pbOut[3] + cbY) + 3;
  2449. pbIn1 = (LPBYTE)((LPBYTE)pbIn0 + cbIn) + 6;
  2450. pbIn2 = (LPBYTE)((LPBYTE)pbIn1 + cbIn) + 6;
  2451. pbS = (LPBYTE)AAHdr.pInputBeg + 3;
  2452. cb1stSharpen = (LONG)(sizeof(BYTE) * cPreLoad);
  2453. IdxOut = ~0;
  2454. DBGP_IF(DBGP_AAHT_MEM,
  2455. DBGP("pbIn=%p:%p:%p, pbOut=%p:%p:%p:%p, pbS=%p, cb1stSharpen=%ld"
  2456. ARGPTR(pbIn0) ARGPTR(pbIn1) ARGPTR(pbIn2)
  2457. ARGPTR(pbOut[0]) ARGPTR(pbOut[1]) ARGPTR(pbOut[2])
  2458. ARGPTR(pbOut[3]) ARGPTR(pbS) ARGDW(cb1stSharpen)));
  2459. //
  2460. // Always read first source
  2461. //
  2462. DBGP_IF(DBGP_EXPAND, DBGP("\nExpand: PRE-LOAD FIRST SCAN"));
  2463. GetFixupScan(&AAHdr, (PBGR8)pbIn1);
  2464. if (pAAInfo->Flags & AAIF_EXP_HAS_1ST_LEFT) {
  2465. DBGP_IF(DBGP_EXPAND, DBGP("Expand: LOAD FIRST LEFT"));
  2466. GetFixupScan(&AAHdr, (PBGR8)pbIn2);
  2467. } else {
  2468. DBGP_IF(DBGP_EXPAND, DBGP("Expand: COPY FIRST LEFT"));
  2469. CopyMemory(pbIn2, pbIn1, cbIn);
  2470. }
  2471. //
  2472. // cPreLoad: Low 4 bits means real load, high 4 bit means imaginary load
  2473. //
  2474. DBGP_IF(DBGP_EXPAND,
  2475. DBGP("cPreLoad=%02lx: AAData[0]=%6ld:%6ld:%6ld:%6ld, %hs"
  2476. ARGDW(pAAInfo->cPreLoad)
  2477. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[0] &
  2478. ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC))
  2479. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[1])
  2480. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[2])
  2481. ARGDW(((PEXPDATA)(pAAInfo->pAAData))->Mul[3])
  2482. ARGPTR((((PEXPDATA)(pAAInfo->pAAData))->Mul[0] & EDF_LOAD_PIXEL) ?
  2483. "Load Pixel" : "")));
  2484. cPreLoad = (LONG)pAAInfo->cPreLoad;
  2485. cAAData = (LONG)(cPreLoad >> 4);
  2486. cPreLoad = (cPreLoad & 0x0F) + cAAData;
  2487. while (cPreLoad--) {
  2488. //
  2489. // Scroll up one input scan line
  2490. //
  2491. pb0 = pbIn0;
  2492. pbIn0 = pbIn1;
  2493. pbIn1 = pbIn2;
  2494. pbIn2 = pb0;
  2495. pb3 = pbOut[++IdxOut & 0x03];
  2496. if (cAAData-- > 0) {
  2497. DBGP_IF(DBGP_EXPAND,
  2498. DBGP("FAKE SCAN: cPreLoad=%ld/cAAData=%ld, Compose IdxOut=%ld"
  2499. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)
  2500. ARGDW(IdxOut & 0x03)));
  2501. CopyMemory(pbIn2, pbIn1, cbIn);
  2502. } else {
  2503. DBGP_IF(DBGP_EXPAND,
  2504. DBGP("REAL SCAN: cPreLoad=%ld, Compose IdxOut=%ld"
  2505. ARGDW(cPreLoad + 1) ARGDW(IdxOut & 0x03)));
  2506. GetFixupScan(&AAHdr, (PBGR8)pbIn2);
  2507. }
  2508. pbS = GraySharpenInput(AAHdr.Flags,
  2509. pbS,
  2510. pbIn0,
  2511. pbIn1,
  2512. pbIn2,
  2513. cbIn);
  2514. GrayExpYDIB_ExpCX(pEDCX,
  2515. (LPBYTE)((LPBYTE)pbS + cb1stSharpen),
  2516. (LPBYTE)pb3,
  2517. (LPBYTE)((LPBYTE)pb3 + cbY));
  2518. }
  2519. pED = (PEXPDATA)(pAAInfo->pAAData);
  2520. cAAData = pAAInfo->cAAData;
  2521. while (cAAData--) {
  2522. LONG Mul0;
  2523. LONG Mul1;
  2524. LONG Mul2;
  2525. LONG Mul3;
  2526. ed = *pED++;
  2527. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  2528. pb0 = pbIn0;
  2529. pbIn0 = pbIn1;
  2530. pbIn1 = pbIn2;
  2531. pbIn2 = (LPBYTE)GetFixupScan(&AAHdr, (PBGR8)pb0);
  2532. pbS = GraySharpenInput(AAHdr.Flags,
  2533. pbS,
  2534. pbIn0,
  2535. pbIn1,
  2536. pbIn2,
  2537. cbIn);
  2538. pb3 = pbOut[++IdxOut & 0x03];
  2539. GrayExpYDIB_ExpCX(pEDCX,
  2540. (LPBYTE)((LPBYTE)pbS + cb1stSharpen),
  2541. (LPBYTE)pb3,
  2542. (LPBYTE)((LPBYTE)pb3 + cbY));
  2543. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  2544. }
  2545. //
  2546. // Build Mul Table here
  2547. //
  2548. pMap = pMap0;
  2549. Mul0 = -ed.Mul[0];
  2550. Mul1 = -ed.Mul[1];
  2551. Mul2 = -ed.Mul[2];
  2552. Mul3 = -ed.Mul[3];
  2553. pb3 = pbOut[(IdxOut ) & 0x03];
  2554. pb2 = pbOut[(IdxOut - 1) & 0x03];
  2555. pOCur = (PGRAYF)AAHdr.pAABufBeg;
  2556. if (ed.Mul[0]) {
  2557. pb1 = pbOut[(IdxOut - 2) & 0x03];
  2558. pb0 = pbOut[(IdxOut - 3) & 0x03];
  2559. GRAY_GET_EXP_PC(PMAP_EXP4, GRAY_GET_EXP4, GRAY_INC_EXP4, pOCur);
  2560. } else if (ed.Mul[1]) {
  2561. pb1 = pbOut[(IdxOut - 2) & 0x03];
  2562. GRAY_GET_EXP_PC(PMAP_EXP3, GRAY_GET_EXP3, GRAY_INC_EXP3, pOCur);
  2563. } else if (ed.Mul[2]) {
  2564. GRAY_GET_EXP_PC(PMAP_EXP2, GRAY_GET_EXP2, GRAY_INC_EXP2, pOCur);
  2565. } else {
  2566. GRAY_GET_EXP_PC(PMAP_EXP1, GRAY_GET_EXP1, GRAY_INC_EXP1, pOCur);
  2567. }
  2568. OUTPUT_AA_CURSCAN;
  2569. }
  2570. return(AAHdr.DstSurfInfo.cy);
  2571. }
  2572. VOID
  2573. HTENTRY
  2574. GrayExpandDIB_CX(
  2575. PAAINFO pAAInfo,
  2576. LPBYTE pIn,
  2577. LPBYTE pOut,
  2578. LPBYTE pOutEnd,
  2579. LONG OutInc
  2580. )
  2581. /*++
  2582. Routine Description:
  2583. Arguments:
  2584. Return Value:
  2585. Author:
  2586. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2587. Revision History:
  2588. --*/
  2589. {
  2590. AAINFO AAI = *pAAInfo;
  2591. LPBYTE pInEnd;
  2592. PEXPDATA pED;
  2593. BYTE GrayIn[8];
  2594. LONG Gray;
  2595. UINT cPreLoad;
  2596. UINT cAAData;
  2597. UINT Idx;
  2598. pInEnd = pIn + AAI.cIn + 2;
  2599. *(pInEnd - 0) =
  2600. *(pInEnd - 1) =
  2601. *(pInEnd - 2) = *(pInEnd - 3);
  2602. GrayIn[5] = *pIn;
  2603. INC_PIN_BY_1ST_LEFT(pIn, AAI.Flags);
  2604. GrayIn[6] = *pIn++;
  2605. cPreLoad = (UINT)AAI.cPreLoad;
  2606. cAAData = (UINT)(cPreLoad >> 4);
  2607. if ((!(cPreLoad &= 0x0F)) && (cAAData)) {
  2608. GrayIn[6] = GrayIn[5];
  2609. ++cPreLoad;
  2610. --cAAData;
  2611. --pIn;
  2612. }
  2613. Idx = 4 - cPreLoad;
  2614. while (cPreLoad--) {
  2615. CopyMemory(&GrayIn[0], &GrayIn[1], sizeof(GrayIn[0]) * 6);
  2616. GrayIn[6] = *pIn++;
  2617. if (AAI.Flags & AAIF_EXP_NO_SHARPEN) {
  2618. GrayIn[3] = GrayIn[5];
  2619. } else {
  2620. SHARPEN_GRAY_LR(GrayIn[3], GrayIn[4], GrayIn[5], GrayIn[6], 0);
  2621. }
  2622. DBGP_IF(DBGP_EXP, DBGP("ExpDIB: PreLoad=%ld, pIn=%8lx"
  2623. ARGDW(cPreLoad) ARGPTR(pIn)));
  2624. }
  2625. GrayIn[7] = GrayIn[Idx--];
  2626. while (cAAData--) {
  2627. GrayIn[Idx--] = GrayIn[7];
  2628. }
  2629. pED = (PEXPDATA)(AAI.pAAData);
  2630. pOutEnd += OutInc;
  2631. do {
  2632. EXPDATA ed = *pED++;
  2633. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  2634. CopyMemory(&GrayIn[0], &GrayIn[1], sizeof(GrayIn[0]) * 6);
  2635. GrayIn[6] = *pIn++;
  2636. if (AAI.Flags & AAIF_EXP_NO_SHARPEN) {
  2637. GrayIn[3] = GrayIn[5];
  2638. } else {
  2639. SHARPEN_GRAY_LR(GrayIn[3], GrayIn[4], GrayIn[5], GrayIn[6], 0);
  2640. }
  2641. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  2642. }
  2643. Gray = MULRGB(GrayIn[3], ed.Mul[3]);
  2644. if (ed.Mul[2]) {
  2645. Gray += MULRGB(GrayIn[2], ed.Mul[2]);
  2646. if (ed.Mul[1]) {
  2647. Gray += MULRGB(GrayIn[1], ed.Mul[1]);
  2648. if (ed.Mul[0]) {
  2649. Gray += MULRGB(GrayIn[0], ed.Mul[0]);
  2650. }
  2651. }
  2652. }
  2653. GRAY_DIMAX_TO_BYTE(pOut, Gray);
  2654. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  2655. ASSERT(pIn <= pInEnd);
  2656. }
  2657. LONG
  2658. HTENTRY
  2659. GrayExpandDIB_CY(
  2660. PAAHEADER pAAHdr
  2661. )
  2662. /*++
  2663. Routine Description:
  2664. This funtion anti-alias the bitmap by query scanlines from CX direction
  2665. (may be Shrink(CX) or Expand(CX)) then compose current scanlines and output
  2666. it to real BGR8 final buffer,
  2667. The complication is need to have scanline one before current destination
  2668. scanline, this may be because the source is not available or because the
  2669. clipping is done on destination.
  2670. Since the anti-alias for expanding requred at least four surounding
  2671. scanlines to compose current scanline, it required large amount of
  2672. memory to retain the prevous result scanlines
  2673. The expanding is by sharpen the source pixel first before anti-aliasing
  2674. smooth through
  2675. prgbIn[0] - Previous un-sharpen source scan
  2676. AND Last The 4th composition sharpened scan after sharpen
  2677. prgbIn[1] - Current un-sharpen source scan
  2678. prgbIn[2] - Next un-sharpen source scan
  2679. prgbIn[3] - The 1st composition sharpened scan
  2680. prgbIn[4] - The 2nd composition sharpened scan
  2681. prgbIn[5] - The 3rd composition sharpened scan
  2682. Exp=Load Sharpen Exp
  2683. Srk=Load Srk Sharpen
  2684. Cpy=Load Cpy
  2685. Exp_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX) SharpenY ExpY
  2686. Exp_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX) SharpenY ExpY
  2687. Exp_CY:Cpy_CX Cpy_CX:(LoadX CpyX ) SharpenY ExpY
  2688. Srk_CY:Exp_CX InputCX SrkY SharpenY Exp_CX:(LoadX SharpenX ExpX)
  2689. Srk_CY:Srk_CX InputCX SrkY SharpenY Srk_CX:(LoadX SrkX SharpenX)
  2690. Srk_CY:Cpy_CX InputCX SrkY SharpenY Cpy_CX:(LoadX CpyX )
  2691. Cpy_CY:Exp_CX Exp_CX:(LoadX SharpenX ExpX)
  2692. Cpy_CY:Srk_CX Srk_CX:(LoadX SrkX SharpenX)
  2693. Cpy_CY:Cpy_CX Cpy_CX:(LoadX CpyX )
  2694. Arguments:
  2695. Return Value:
  2696. Author:
  2697. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2698. Revision History:
  2699. --*/
  2700. {
  2701. AAHEADER AAHdr = *pAAHdr;
  2702. PEXPDATA pED;
  2703. LPBYTE pbIn[6];
  2704. PLONG pMap;
  2705. PLONG pMap0;
  2706. PLONG pMap0End;
  2707. LPBYTE pb0;
  2708. LPBYTE pb1;
  2709. LPBYTE pb2;
  2710. LPBYTE pb3;
  2711. LPBYTE pb4;
  2712. LPBYTE pb5;
  2713. PGRAYF pOCur;
  2714. LPBYTE pbYEnd;
  2715. LONG cbScan;
  2716. LONG cAAData;
  2717. LONG cPreLoad;
  2718. pMap0 = (PLONG)AAHdr.pAAInfoCY->pbExtra;
  2719. pMap0End = pMap0 + 256;
  2720. cbScan = (AAHdr.DstSurfInfo.cx + 6) * (LONG)sizeof(BYTE);
  2721. pbIn[0] = (LPBYTE)(pMap0 + (256 * 4)) + 3;
  2722. pbIn[1] = (LPBYTE)((LPBYTE)pbIn[0] + cbScan);
  2723. pbIn[2] = (LPBYTE)((LPBYTE)pbIn[1] + cbScan);
  2724. pbIn[3] = (LPBYTE)((LPBYTE)pbIn[2] + cbScan);
  2725. pbIn[4] = (LPBYTE)((LPBYTE)pbIn[3] + cbScan);
  2726. pbIn[5] = (LPBYTE)((LPBYTE)pbIn[4] + cbScan);
  2727. cbScan -= (sizeof(BYTE) * 6);
  2728. //
  2729. // Always read first source
  2730. //
  2731. DBGP_IF(DBGP_EXPAND, DBGP("\nLoad First Scan"));
  2732. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2733. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2734. (PBGR8)pbIn[4],
  2735. (LPBYTE)pbIn[4] + cbScan,
  2736. sizeof(BYTE));
  2737. //
  2738. // Load the PRE-SOURCE LEFT first source first
  2739. //
  2740. if (AAHdr.pAAInfoCY->Flags & AAIF_EXP_HAS_1ST_LEFT) {
  2741. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2742. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2743. (PBGR8)pbIn[5],
  2744. (LPBYTE)pbIn[5] + cbScan,
  2745. sizeof(BYTE));
  2746. DBGP_IF(DBGP_EXPAND, DBGP("Load First Left"));
  2747. } else {
  2748. CopyMemory(pbIn[5], pbIn[4], cbScan);
  2749. DBGP_IF(DBGP_EXPAND, DBGP("Copy First Left"));
  2750. }
  2751. cPreLoad = (LONG)AAHdr.pAAInfoCY->cPreLoad;
  2752. cAAData = (LONG)(cPreLoad >> 4);
  2753. cPreLoad = (cPreLoad & 0x0F) + cAAData;
  2754. while (cPreLoad--) {
  2755. //
  2756. // Scroll up pbIn by one scan
  2757. //
  2758. pb5 = pbIn[0];
  2759. CopyMemory(&pbIn[0], &pbIn[1], sizeof(pbIn[0]) * 5);
  2760. pbIn[5] = pb5;
  2761. pb3 = pbIn[3];
  2762. pb4 = pbIn[4];
  2763. pb5 = pbIn[5];
  2764. pbYEnd = (LPBYTE)pb5 + cbScan;
  2765. if (cAAData-- > 0) {
  2766. DBGP_IF(DBGP_EXPAND,
  2767. DBGP("FAKE SCAN: cPreLoad=%ld/cAAData=%ld"
  2768. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)));
  2769. CopyMemory(pb5, pb4, cbScan);
  2770. } else {
  2771. DBGP_IF(DBGP_EXPAND,
  2772. DBGP("REAL SCAN: cPreLoad=%ld/cAAData=%ld"
  2773. ARGDW(cPreLoad + 1) ARGDW(cAAData + 1)));
  2774. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2775. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2776. (PBGR8)pb5,
  2777. pbYEnd,
  2778. sizeof(BYTE));
  2779. }
  2780. DBGP_IF(DBGP_EXPAND,
  2781. DBGP("Compose Sharpen Scan=%ld" ARGDW(cPreLoad + 1)));
  2782. //
  2783. // Now, let's sharpen the input
  2784. //
  2785. if (AAHdr.Flags & AAHF_BBPF_AA_OFF) {
  2786. CopyMemory(pb3, pb4, cbScan);
  2787. } else {
  2788. do {
  2789. SHARPEN_PGRAY_LR(pb3, (*pb3), (*pb4), (*pb5), 0);
  2790. pb3++;
  2791. pb4++;
  2792. } while (++pb5 < (LPBYTE)pbYEnd);
  2793. }
  2794. }
  2795. pED = (PEXPDATA)(AAHdr.pAAInfoCY->pAAData);
  2796. cAAData = AAHdr.pAAInfoCY->cAAData;
  2797. while (cAAData--) {
  2798. EXPDATA ed = *pED++;
  2799. LONG Mul0;
  2800. LONG Mul1;
  2801. LONG Mul2;
  2802. LONG Mul3;
  2803. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  2804. pb5 = pbIn[0];
  2805. CopyMemory(&pbIn[0], &pbIn[1], sizeof(pbIn[0]) * 5);
  2806. pbIn[5] = pb5;
  2807. pb3 = pbIn[3];
  2808. pb4 = pbIn[4];
  2809. pb5 = pbIn[5];
  2810. pbYEnd = (LPBYTE)pb5 + cbScan;
  2811. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  2812. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  2813. (PBGR8)pb5,
  2814. pbYEnd,
  2815. sizeof(BYTE));
  2816. if (AAHdr.Flags & AAHF_BBPF_AA_OFF) {
  2817. CopyMemory(pb3, pb4, cbScan);
  2818. } else {
  2819. do {
  2820. SHARPEN_PGRAY_LR(pb3, (*pb3), (*pb4), (*pb5), 0);
  2821. pb3++;
  2822. pb4++;
  2823. } while (++pb5 < (LPBYTE)pbYEnd);
  2824. }
  2825. ed.Mul[0] &= ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC);
  2826. }
  2827. //
  2828. // Build Mul Table here
  2829. //
  2830. pMap = pMap0;
  2831. Mul0 = -ed.Mul[0];
  2832. Mul1 = -ed.Mul[1];
  2833. Mul2 = -ed.Mul[2];
  2834. Mul3 = -ed.Mul[3];
  2835. pb3 = pbIn[3];
  2836. pb2 = pbIn[2];
  2837. pOCur = (PGRAYF)AAHdr.pAABufBeg;
  2838. if (ed.Mul[0]) {
  2839. pb1 = pbIn[1];
  2840. pb0 = pbIn[0];
  2841. GRAY_GET_EXP_PC(PMAP_EXP4, GRAY_GET_EXP4, GRAY_INC_EXP4, pOCur);
  2842. } else if (ed.Mul[1]) {
  2843. pb1 = pbIn[1];
  2844. GRAY_GET_EXP_PC(PMAP_EXP3, GRAY_GET_EXP3, GRAY_INC_EXP3, pOCur);
  2845. } else if (ed.Mul[2]) {
  2846. GRAY_GET_EXP_PC(PMAP_EXP2, GRAY_GET_EXP2, GRAY_INC_EXP2, pOCur);
  2847. } else {
  2848. GRAY_GET_EXP_PC(PMAP_EXP1, GRAY_GET_EXP1, GRAY_INC_EXP1, pOCur);
  2849. }
  2850. OUTPUT_AA_CURSCAN;
  2851. }
  2852. return(AAHdr.DstSurfInfo.cy);
  2853. }
  2854. VOID
  2855. HTENTRY
  2856. GrayShrinkDIB_CX(
  2857. PAAINFO pAAInfo,
  2858. LPBYTE pIn,
  2859. LPBYTE pOut,
  2860. LPBYTE pOutEnd,
  2861. LONG OutInc
  2862. )
  2863. /*++
  2864. Routine Description:
  2865. Arguments:
  2866. Return Value:
  2867. Author:
  2868. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2869. Revision History:
  2870. --*/
  2871. {
  2872. PSHRINKDATA pSD;
  2873. PLONG pMap;
  2874. PLONG pMap256X;
  2875. LPBYTE pInEnd;
  2876. LONG GrayOut[3];
  2877. LONG GrayT;
  2878. UINT Mul;
  2879. UINT cPreLoad;
  2880. pInEnd = pIn + pAAInfo->cIn;
  2881. if (Mul = (UINT)pAAInfo->PreMul) {
  2882. GrayOut[2] = MULRGB(*pIn, Mul);
  2883. pIn += pAAInfo->PreSrcInc;
  2884. } else {
  2885. ZeroMemory(&GrayOut[2], sizeof(GrayOut[2]));
  2886. }
  2887. pSD = (PSHRINKDATA)(pAAInfo->pAAData);
  2888. pMap256X = pAAInfo->pMapMul;
  2889. cPreLoad = (UINT)pAAInfo->cPreLoad;
  2890. while (cPreLoad) {
  2891. Mul = (UINT)((pSD++)->Mul);
  2892. pMap = (PLONG)((LPBYTE)pMap256X + GET_SDF_LARGE_OFF(Mul));
  2893. if (Mul & SDF_DONE) {
  2894. //
  2895. // Finished a pixel
  2896. //
  2897. Mul &= SDF_MUL_MASK;
  2898. GrayOut[2] += (GrayT = MULRGB(*pIn, Mul));
  2899. CopyMemory(&GrayOut[0], &GrayOut[1], sizeof(GrayOut[0]) * 2);
  2900. GrayOut[2] = pMap[*pIn++] - GrayT;
  2901. --cPreLoad;
  2902. } else {
  2903. GrayOut[2] += pMap[*pIn++];
  2904. }
  2905. }
  2906. if (pAAInfo->cPreLoad == 1) {
  2907. GrayOut[0] = GrayOut[1];
  2908. }
  2909. while (Mul = (UINT)((pSD++)->Mul)) {
  2910. pMap = (PLONG)((LPBYTE)pMap256X + GET_SDF_LARGE_OFF(Mul));
  2911. if (Mul & SDF_DONE) {
  2912. //
  2913. // Finished a pixel
  2914. //
  2915. Mul &= SDF_MUL_MASK;
  2916. GrayOut[2] += (GrayT = MULRGB(*pIn, Mul));
  2917. SHARPEN_PGRAY_LR(pOut,
  2918. GrayOut[0],
  2919. GrayOut[1],
  2920. GrayOut[2],
  2921. DI_R_SHIFT);
  2922. (LPBYTE)pOut += OutInc;
  2923. CopyMemory(&GrayOut[0], &GrayOut[1], sizeof(GrayOut[0]) * 2);
  2924. GrayOut[2] = pMap[*pIn++] - GrayT;
  2925. } else {
  2926. GrayOut[2] += pMap[*pIn++];
  2927. }
  2928. }
  2929. ASSERT(pIn == pInEnd);
  2930. if ((LPBYTE)pOut == (pOutEnd - OutInc)) {
  2931. SHARPEN_PGRAY_LR(pOut,
  2932. GrayOut[0],
  2933. GrayOut[1],
  2934. GrayOut[1],
  2935. DI_R_SHIFT);
  2936. }
  2937. }
  2938. LONG
  2939. HTENTRY
  2940. GrayShrinkDIB_CY(
  2941. PAAHEADER pAAHdr
  2942. )
  2943. /*++
  2944. Routine Description:
  2945. This function shrink the scanline down first in Y direction from source
  2946. bitmap when it is done for group of scanlines then it call AXFunc to
  2947. compose current scanline (it may be Shrink(CX) or Expand(CX)) to the
  2948. final output BGR8 buffer
  2949. The shrink is done by sharpen the current pixel first.
  2950. Arguments:
  2951. Return Value:
  2952. Author:
  2953. 11-Jul-1997 Fri 14:26:26 created -by- Daniel Chou (danielc)
  2954. Revision History:
  2955. --*/
  2956. {
  2957. AAHEADER AAHdr;
  2958. PSHRINKDATA pSD;
  2959. SHRINKDATA sd;
  2960. LPBYTE pIBuf;
  2961. LPBYTE pIBufEnd;
  2962. LPBYTE pICur;
  2963. PGRAYF pOCur;
  2964. PLONG pGrayIn[3];
  2965. PLONG pGray0;
  2966. PLONG pGray1;
  2967. PLONG pGray2;
  2968. PLONG pGray2End;
  2969. PLONG pMap;
  2970. PLONG pMapMul;
  2971. PLONG pMapMul2;
  2972. PLONG pMap256Y;
  2973. RGBL GrayT;
  2974. LONG cbGrayY;
  2975. LONG Mul;
  2976. LONG cAAData;
  2977. BOOL CopyFirst;
  2978. LONG cyOut;
  2979. INT cPreLoad;
  2980. BYTE Mask;
  2981. DEFDBGVAR(LONG, MulTot)
  2982. //
  2983. // Adding 3 to each side of pIBuf for ExpandDIB_CX
  2984. //
  2985. AAHdr = *pAAHdr;
  2986. pMap256Y = AAHdr.pAAInfoCY->pMapMul;
  2987. pMapMul = (PLONG)(AAHdr.pAAInfoCY->pbExtra);
  2988. pMapMul2 = pMapMul + 256;
  2989. cbGrayY = (LONG)(AAHdr.DstSurfInfo.cx * sizeof(LONG));
  2990. pGrayIn[0] = (PLONG)(pMapMul2 + 256);
  2991. pGrayIn[1] = (PLONG)( (LPBYTE)pGrayIn[0] + cbGrayY);
  2992. pGrayIn[2] = (PLONG)( (LPBYTE)pGrayIn[1] + cbGrayY);
  2993. pIBuf = (LPBYTE)((LPBYTE)pGrayIn[2] + cbGrayY);
  2994. pIBufEnd = pIBuf + AAHdr.DstSurfInfo.cx;
  2995. ASSERT_MEM_ALIGN(pGrayIn[0], sizeof(LONG));
  2996. ASSERT_MEM_ALIGN(pGrayIn[1], sizeof(LONG));
  2997. ASSERT_MEM_ALIGN(pGrayIn[2], sizeof(LONG));
  2998. if (Mul = AAHdr.pAAInfoCY->PreMul) {
  2999. pMap = pMapMul;
  3000. GrayT.r = -Mul;
  3001. do {
  3002. pMap[0] = (GrayT.r += Mul);
  3003. } while (++pMap < pMapMul2);
  3004. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  3005. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  3006. (PBGR8)(pICur = pIBuf),
  3007. pIBufEnd,
  3008. sizeof(BYTE));
  3009. pGray2 = pGrayIn[2];
  3010. pGray2End = (PLONG)((LPBYTE)pGray2 + cbGrayY);
  3011. do {
  3012. *pGray2 = pMapMul[*pICur++];
  3013. } while (++pGray2 < pGray2End);
  3014. //
  3015. // The AAInputFunc() will increment the pointer, so reduced it
  3016. //
  3017. if (!(AAHdr.pAAInfoCY->PreSrcInc)) {
  3018. AAHdr.Flags |= AAHF_GET_LAST_SCAN;
  3019. }
  3020. }
  3021. pSD = (PSHRINKDATA)(AAHdr.pAAInfoCY->pAAData);
  3022. cPreLoad = (INT)AAHdr.pAAInfoCY->cPreLoad;
  3023. CopyFirst = (BOOL)(cPreLoad == 1);
  3024. cAAData = AAHdr.pAAInfoCY->cAAData;
  3025. cyOut = 0;
  3026. SETDBGVAR(MulTot, Mul);
  3027. while (cAAData--) {
  3028. AAHdr.AACXFunc(AAHdr.pAAInfoCX,
  3029. GetFixupScan(&AAHdr, AAHdr.pInputBeg),
  3030. (PBGR8)(pICur = pIBuf),
  3031. pIBufEnd,
  3032. sizeof(BYTE));
  3033. sd = *pSD++;
  3034. pGray2 = pGrayIn[2];
  3035. pGray2End = (PLONG)((LPBYTE)pGray2 + cbGrayY);
  3036. Mask = GET_SDF_LARGE_MASK(sd.Mul);
  3037. if (sd.Mul & SDF_DONE) {
  3038. //
  3039. // Build current Mul Table
  3040. //
  3041. Mul = (LONG)(sd.Mul & SDF_MUL_MASK);
  3042. pMap = pMapMul;
  3043. GrayT.r = -Mul;
  3044. GrayT.b = (LONG)(pMap256Y[1] - Mul + (LONG)(Mask & 0x01));
  3045. GrayT.g = -GrayT.b;
  3046. do {
  3047. pMap[ 0] = (GrayT.r += Mul);
  3048. pMap[256] = (GrayT.g += GrayT.b);
  3049. } while (++pMap < pMapMul2);
  3050. //
  3051. // Finished a scanline, so to see if have prev/next to sharpen with
  3052. //
  3053. pGray0 = pGrayIn[0];
  3054. pGray1 = pGrayIn[1];
  3055. if (cPreLoad-- > 0) {
  3056. do {
  3057. *pGray2 += pMapMul[*pICur];
  3058. *pGray0++ = pMapMul[*pICur++ + 256];
  3059. } while (++pGray2 < pGray2End);
  3060. if (CopyFirst) {
  3061. CopyMemory(pGray1, pGrayIn[2], cbGrayY);
  3062. CopyFirst = FALSE;
  3063. }
  3064. } else {
  3065. pOCur = (PGRAYF)AAHdr.pAABufBeg;
  3066. do {
  3067. *pGray2 += pMapMul[*pICur];
  3068. SHARPEN_PWGRAY_LR(pOCur, (*pGray0), (*pGray1), (*pGray2));
  3069. (LPBYTE)pOCur += AAHdr.AABufInc;
  3070. *pGray0++ = pMapMul[*pICur++ + 256];
  3071. ++pGray1;
  3072. } while (++pGray2 < pGray2End);
  3073. DBGP_IF(DBGP_SRK2,
  3074. DBGP("*%ld**In=%3lx, Mul=%08lx [%08lx], (%p) Gray=%8lx [%08lx]"
  3075. ARGDW((cPreLoad > 0) ? cPreLoad : 0)
  3076. ARGDW(*pIBuf) ARGDW(Mul)
  3077. ARGDW(MulTot += Mul)
  3078. ARGPTR(pGrayIn[2])
  3079. ARGDW(*pGrayIn[2]) ARGDW(pMapMul[*(pICur - 1)])));
  3080. DBGP_IF(DBGP_SRK2,
  3081. DBGP(" *In=%3lx, Mul=%08lx [%08lx], (%p) Gray=%8lx [%08lx]"
  3082. ARGDW(*pIBuf) ARGDW(sd.Mul & SDF_MUL_MASK)
  3083. ARGDW(MulTot = GrayT.b)
  3084. ARGPTR(pGrayIn[0])
  3085. ARGDW(*pGrayIn[0])
  3086. ARGDW(pMapMul[*(pICur - 1) + 256])));
  3087. OUTPUT_AA_CURSCAN;
  3088. ++cyOut;
  3089. }
  3090. pGray2 = pGrayIn[0];
  3091. pGrayIn[0] = pGrayIn[1];
  3092. pGrayIn[1] = pGrayIn[2];
  3093. pGrayIn[2] = pGray2;
  3094. } else {
  3095. pMap = (PLONG)((LPBYTE)pMap256Y + GET_SDF_LARGE_OFF(sd.Mul));
  3096. do {
  3097. *pGray2 += pMap[*pICur++];
  3098. } while (++pGray2 < pGray2End);
  3099. DBGP_IF(DBGP_SRK2,
  3100. DBGP(" In=%3lx, Mul=%08lx [%08lx], (%p) Gray=%8lx [%08lx]"
  3101. ARGDW(*pIBuf) ARGDW(sd.Mul & SDF_MUL_MASK)
  3102. ARGDW(MulTot += (sd.Mul & SDF_MUL_MASK))
  3103. ARGPTR(pGrayIn[2])
  3104. ARGDW(*pGrayIn[2]) ARGDW(pMap[*(pICur - 1)])));
  3105. }
  3106. }
  3107. if (AAHdr.DstSurfInfo.pb != AAHdr.pOutLast) {
  3108. pOCur = (PGRAYF)AAHdr.pAABufBeg;
  3109. pGray0 = pGrayIn[0];
  3110. pGray2 = pGrayIn[1];
  3111. pGray2End = (PLONG)((LPBYTE)pGray2 + cbGrayY);
  3112. do {
  3113. SHARPEN_PWGRAY_LR(pOCur, (*pGray0), (*pGray2), (*pGray2));
  3114. (LPBYTE)pOCur += AAHdr.AABufInc;
  3115. ++pGray0;
  3116. } while (++pGray2 < pGray2End);
  3117. OUTPUT_AA_CURSCAN;
  3118. ++cyOut;
  3119. }
  3120. ASSERTMSG("Shrink: cScan not equal", cyOut == AAHdr.DstSurfInfo.cy);
  3121. return(cyOut);
  3122. }
  3123. //
  3124. //****************************************************************************
  3125. // Following ae defines and functions for VERY FAST Anti-Aliasing expansion,
  3126. // the Fast mode is turn on when is stretching up and both X and Y is less or
  3127. // equal to 500%
  3128. //****************************************************************************
  3129. //
  3130. #define MAC_FROM_2(Mac, pO, p1, p2, cCX) \
  3131. { \
  3132. LONG Count; \
  3133. \
  3134. Count = cCX >> 2; \
  3135. cCX &= 0x03; \
  3136. \
  3137. while (Count--) { \
  3138. \
  3139. *(pO + 0) = (BYTE)Mac((*(p1+0)), (*(p2+0))); \
  3140. *(pO + 1) = (BYTE)Mac((*(p1+1)), (*(p2+1))); \
  3141. *(pO + 2) = (BYTE)Mac((*(p1+2)), (*(p2+2))); \
  3142. *(pO + 3) = (BYTE)Mac((*(p1+3)), (*(p2+3))); \
  3143. \
  3144. pO += 4; \
  3145. p1 += 4; \
  3146. p2 += 4; \
  3147. } \
  3148. \
  3149. while (cCX--) { \
  3150. \
  3151. *pO++ = (BYTE)Mac((*p1), (*p2)); \
  3152. \
  3153. ++p1; \
  3154. ++p2; \
  3155. } \
  3156. }
  3157. #define MAC_FROM_3(Mac, pO, p1, p2, p3, cCX) \
  3158. { \
  3159. LONG Count; \
  3160. \
  3161. Count = cCX >> 2; \
  3162. cCX &= 0x03; \
  3163. \
  3164. while (Count--) { \
  3165. \
  3166. *(pO + 0) = (BYTE)Mac((*(p1+0)), (*(p2+0)), (*(p3+0))); \
  3167. *(pO + 1) = (BYTE)Mac((*(p1+1)), (*(p2+1)), (*(p3+1))); \
  3168. *(pO + 2) = (BYTE)Mac((*(p1+2)), (*(p2+2)), (*(p3+2))); \
  3169. *(pO + 3) = (BYTE)Mac((*(p1+3)), (*(p2+3)), (*(p3+3))); \
  3170. \
  3171. pO += 4; \
  3172. p1 += 4; \
  3173. p2 += 4; \
  3174. p3 += 4; \
  3175. } \
  3176. \
  3177. while (cCX--) { \
  3178. \
  3179. *pO++ = (BYTE)Mac((*p1), (*p2), (*p3)); \
  3180. \
  3181. ++p1; \
  3182. ++p2; \
  3183. ++p3; \
  3184. } \
  3185. }
  3186. VOID
  3187. HTENTRY
  3188. Do5225(
  3189. LPBYTE pO,
  3190. LPBYTE p1,
  3191. LPBYTE p2,
  3192. LPBYTE p3,
  3193. LONG cCX
  3194. )
  3195. /*++
  3196. Routine Description:
  3197. Arguments:
  3198. Return Value:
  3199. Author:
  3200. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3201. Revision History:
  3202. --*/
  3203. {
  3204. MAC_FROM_3(CLR_5225, pO, p1, p2, p3, cCX);
  3205. }
  3206. VOID
  3207. HTENTRY
  3208. Do1141(
  3209. LPBYTE pO,
  3210. LPBYTE p1,
  3211. LPBYTE p2,
  3212. LPBYTE p3,
  3213. LONG cCX
  3214. )
  3215. /*++
  3216. Routine Description:
  3217. Arguments:
  3218. Return Value:
  3219. Author:
  3220. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3221. Revision History:
  3222. --*/
  3223. {
  3224. MAC_FROM_3(CLR_1141, pO, p1, p2, p3, cCX);
  3225. }
  3226. VOID
  3227. HTENTRY
  3228. Do3121(
  3229. LPBYTE pO,
  3230. LPBYTE p1,
  3231. LPBYTE p2,
  3232. LPBYTE p3,
  3233. LONG cCX
  3234. )
  3235. /*++
  3236. Routine Description:
  3237. Arguments:
  3238. Return Value:
  3239. Author:
  3240. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3241. Revision History:
  3242. --*/
  3243. {
  3244. MAC_FROM_3(CLR_3121, pO, p1, p2, p3, cCX);
  3245. }
  3246. VOID
  3247. HTENTRY
  3248. Do6251(
  3249. LPBYTE pO,
  3250. LPBYTE p1,
  3251. LPBYTE p2,
  3252. LPBYTE p3,
  3253. LONG cCX
  3254. )
  3255. /*++
  3256. Routine Description:
  3257. Arguments:
  3258. Return Value:
  3259. Author:
  3260. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3261. Revision History:
  3262. --*/
  3263. {
  3264. MAC_FROM_3(CLR_6251, pO, p1, p2, p3, cCX);
  3265. }
  3266. VOID
  3267. HTENTRY
  3268. Do3263(
  3269. LPBYTE pO,
  3270. LPBYTE p1,
  3271. LPBYTE p2,
  3272. LPBYTE p3,
  3273. LONG cCX
  3274. )
  3275. /*++
  3276. Routine Description:
  3277. Arguments:
  3278. Return Value:
  3279. Author:
  3280. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3281. Revision History:
  3282. --*/
  3283. {
  3284. MAC_FROM_3(CLR_3263, pO, p1, p2, p3, cCX);
  3285. }
  3286. VOID
  3287. HTENTRY
  3288. Do1319(
  3289. LPBYTE pO,
  3290. LPBYTE p1,
  3291. LPBYTE p2,
  3292. LONG cCX
  3293. )
  3294. /*++
  3295. Routine Description:
  3296. Arguments:
  3297. Return Value:
  3298. Author:
  3299. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3300. Revision History:
  3301. --*/
  3302. {
  3303. MAC_FROM_2(CLR_1319, pO, p1, p2, cCX);
  3304. }
  3305. VOID
  3306. HTENTRY
  3307. Do35(
  3308. LPBYTE pO,
  3309. LPBYTE p1,
  3310. LPBYTE p2,
  3311. LONG cCX
  3312. )
  3313. /*++
  3314. Routine Description:
  3315. Arguments:
  3316. Return Value:
  3317. Author:
  3318. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3319. Revision History:
  3320. --*/
  3321. {
  3322. MAC_FROM_2(CLR_35, pO, p1, p2, cCX);
  3323. }
  3324. VOID
  3325. HTENTRY
  3326. Do13(
  3327. LPBYTE pO,
  3328. LPBYTE p1,
  3329. LPBYTE p2,
  3330. LONG cCX
  3331. )
  3332. /*++
  3333. Routine Description:
  3334. Arguments:
  3335. Return Value:
  3336. Author:
  3337. 22-Apr-1999 Thu 18:57:47 created -by- Daniel Chou (danielc)
  3338. Revision History:
  3339. --*/
  3340. {
  3341. MAC_FROM_2(CLR_13, pO, p1, p2, cCX);
  3342. }
  3343. VOID
  3344. HTENTRY
  3345. GrayFastExpAA_CX(
  3346. PAAINFO pAAInfo,
  3347. LPBYTE pIn,
  3348. PGRAYF pOut,
  3349. LPBYTE pOutEnd,
  3350. LONG OutInc
  3351. )
  3352. /*++
  3353. Routine Description:
  3354. Arguments:
  3355. Return Value:
  3356. Author:
  3357. 09-Dec-1998 Wed 15:54:25 created -by- Daniel Chou (danielc)
  3358. Revision History:
  3359. --*/
  3360. {
  3361. PREPDATA pRep;
  3362. PREPDATA pRepEnd;
  3363. DWORD cRep;
  3364. WORD wIn[3];
  3365. pRep = pAAInfo->Src.pRep;
  3366. pRepEnd = pAAInfo->Src.pRepEnd;
  3367. cRep = 1;
  3368. pIn += pAAInfo->Src.cPrevSrc;
  3369. wIn[1] = GRAY_B2W(*(pIn - 1));
  3370. wIn[2] = GRAY_B2W(*pIn++);
  3371. do {
  3372. ASSERT(pRep < pRepEnd);
  3373. cRep = (DWORD)pRep++->c;
  3374. wIn[0] = wIn[1];
  3375. wIn[1] = wIn[2];
  3376. wIn[2] = GRAY_B2W(*pIn++);
  3377. switch (cRep) {
  3378. case 1:
  3379. GRAY_MACRO3(pOut, CLR_5225, wIn[0], wIn[1], wIn[2]);
  3380. break;
  3381. case 2:
  3382. GRAY_MACRO(pOut, CLR_13, wIn[0], wIn[1]);
  3383. (LPBYTE)pOut += OutInc;
  3384. GRAY_MACRO(pOut, CLR_13, wIn[2], wIn[1]);
  3385. break;
  3386. case 3:
  3387. GRAY_MACRO(pOut, CLR_35, wIn[0], wIn[1]);
  3388. (LPBYTE)pOut += OutInc;
  3389. GRAY_MACRO3(pOut, CLR_1141, wIn[0], wIn[1], wIn[2]);
  3390. (LPBYTE)pOut += OutInc;
  3391. GRAY_MACRO(pOut, CLR_35, wIn[2], wIn[1]);
  3392. break;
  3393. case 4:
  3394. GRAY_MACRO(pOut, CLR_35, wIn[0], wIn[1]);
  3395. (LPBYTE)pOut += OutInc;
  3396. GRAY_MACRO3(pOut, CLR_3121, wIn[0], wIn[1], wIn[2]);
  3397. (LPBYTE)pOut += OutInc;
  3398. GRAY_MACRO3(pOut, CLR_3121, wIn[2], wIn[1], wIn[0]);
  3399. (LPBYTE)pOut += OutInc;
  3400. GRAY_MACRO(pOut, CLR_35, wIn[2], wIn[1]);
  3401. break;
  3402. case 5:
  3403. GRAY_MACRO(pOut, CLR_1319, wIn[0], wIn[1]);
  3404. (LPBYTE)pOut += OutInc;
  3405. GRAY_MACRO3(pOut, CLR_6251, wIn[0], wIn[1], wIn[2]);
  3406. (LPBYTE)pOut += OutInc;
  3407. GRAY_MACRO3(pOut, CLR_3263, wIn[0], wIn[1], wIn[2]);
  3408. (LPBYTE)pOut += OutInc;
  3409. GRAY_MACRO3(pOut, CLR_6251, wIn[2], wIn[1], wIn[0]);
  3410. (LPBYTE)pOut += OutInc;
  3411. GRAY_MACRO(pOut, CLR_1319, wIn[2], wIn[1]);
  3412. break;
  3413. default:
  3414. DBGP("GrayFastExpCX Error: Invalid cRep=%ld" ARGDW(cRep));
  3415. ASSERT(cRep <= FAST_MAX_CX);
  3416. break;
  3417. }
  3418. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  3419. }
  3420. VOID
  3421. HTENTRY
  3422. FastExpAA_CX(
  3423. PAAINFO pAAInfo,
  3424. PBGR8 pIn,
  3425. PBGR8 pOut,
  3426. LPBYTE pOutEnd,
  3427. LONG OutInc
  3428. )
  3429. /*++
  3430. Routine Description:
  3431. Arguments:
  3432. Return Value:
  3433. Author:
  3434. 09-Dec-1998 Wed 15:54:25 created -by- Daniel Chou (danielc)
  3435. Revision History:
  3436. --*/
  3437. {
  3438. PREPDATA pRep;
  3439. PREPDATA pRepEnd;
  3440. DWORD cRep;
  3441. BGR8 bgr8[3];
  3442. pRep = pAAInfo->Src.pRep;
  3443. pRepEnd = pAAInfo->Src.pRepEnd;
  3444. cRep = 1;
  3445. pIn += pAAInfo->Src.cPrevSrc;
  3446. bgr8[1] = *(pIn - 1);
  3447. bgr8[2] = *pIn++;
  3448. do {
  3449. // Bug 27036: ensure loop is exited
  3450. INT_PTR EntriesRemain = (pOutEnd - (LPBYTE)pOut) / OutInc ;
  3451. if (pRep >= pRepEnd) {
  3452. DBGP("pRep Too big=%ld" ARGDW(pRep - pRepEnd + 1));
  3453. ASSERT(pRep < pRepEnd);
  3454. break; // Bug 27036: ensure loop is exited
  3455. }
  3456. cRep = (DWORD)pRep++->c;
  3457. // Bug 27036: ensure loop is exited
  3458. if(cRep > (DWORD)EntriesRemain)
  3459. cRep = (DWORD)EntriesRemain ;
  3460. bgr8[0] = bgr8[1];
  3461. bgr8[1] = bgr8[2];
  3462. bgr8[2] = *pIn++;
  3463. switch (cRep) {
  3464. case 1:
  3465. BGR_MACRO3(pOut, CLR_5225, bgr8[0], bgr8[1], bgr8[2]);
  3466. break;
  3467. case 2:
  3468. BGR_MACRO(pOut, CLR_13, bgr8[0], bgr8[1]);
  3469. (LPBYTE)pOut += OutInc;
  3470. BGR_MACRO(pOut, CLR_13, bgr8[2], bgr8[1]);
  3471. break;
  3472. case 3:
  3473. BGR_MACRO(pOut, CLR_35, bgr8[0], bgr8[1]);
  3474. (LPBYTE)pOut += OutInc;
  3475. BGR_MACRO3(pOut, CLR_1141, bgr8[0], bgr8[1], bgr8[2]);
  3476. (LPBYTE)pOut += OutInc;
  3477. BGR_MACRO(pOut, CLR_35, bgr8[2], bgr8[1]);
  3478. break;
  3479. case 4:
  3480. BGR_MACRO(pOut, CLR_35, bgr8[0], bgr8[1]);
  3481. (LPBYTE)pOut += OutInc;
  3482. BGR_MACRO3(pOut, CLR_3121, bgr8[0], bgr8[1], bgr8[2]);
  3483. (LPBYTE)pOut += OutInc;
  3484. BGR_MACRO3(pOut, CLR_3121, bgr8[2], bgr8[1], bgr8[0]);
  3485. (LPBYTE)pOut += OutInc;
  3486. BGR_MACRO(pOut, CLR_35, bgr8[2], bgr8[1]);
  3487. break;
  3488. case 5:
  3489. BGR_MACRO(pOut, CLR_1319, bgr8[0], bgr8[1]);
  3490. (LPBYTE)pOut += OutInc;
  3491. BGR_MACRO3(pOut, CLR_6251, bgr8[0], bgr8[1], bgr8[2]);
  3492. (LPBYTE)pOut += OutInc;
  3493. BGR_MACRO3(pOut, CLR_3263, bgr8[0], bgr8[1], bgr8[2]);
  3494. (LPBYTE)pOut += OutInc;
  3495. BGR_MACRO3(pOut, CLR_6251, bgr8[2], bgr8[1], bgr8[0]);
  3496. (LPBYTE)pOut += OutInc;
  3497. BGR_MACRO(pOut, CLR_1319, bgr8[2], bgr8[1]);
  3498. break;
  3499. default:
  3500. DBGP("FastExpCX Error: Invalid cRep=%ld" ARGDW(cRep));
  3501. ASSERT(cRep <= FAST_MAX_CX);
  3502. break;
  3503. }
  3504. } while (((LPBYTE)pOut += OutInc) != pOutEnd);
  3505. }
  3506. LONG
  3507. HTENTRY
  3508. FastExpAA_CY(
  3509. PAAHEADER pAAHdr
  3510. )
  3511. /*++
  3512. Routine Description:
  3513. Arguments:
  3514. Return Value:
  3515. Author:
  3516. 09-Dec-1998 Wed 15:32:38 created -by- Daniel Chou (danielc)
  3517. Revision History:
  3518. --*/
  3519. {
  3520. AAHEADER AAHdr = *pAAHdr;
  3521. AASHARPENFUNC AASPFunc;
  3522. FASTEXPAACXFUNC FastExpAACXFunc;
  3523. LPBYTE pIn[6];
  3524. PAAINFO pAAInfo;
  3525. PREPDATA pRep;
  3526. PREPDATA pRepEnd;
  3527. LPBYTE pCur;
  3528. PBGRF pAABufBeg;
  3529. PBGRF pAABufEnd;
  3530. LONG AABufInc;
  3531. LONG cRep;
  3532. LONG iRep;
  3533. LONG cbSrc;
  3534. LONG iY;
  3535. LONG cbCX;
  3536. //
  3537. // Fixup the CX first, the *pRep and *(pRepEnd - 1) are fixed, pAABufBeg and
  3538. // pAABufEnd are expanded so we do not need to check the cRep during each
  3539. // of CX functions
  3540. //
  3541. pAAInfo = AAHdr.pAAInfoCX;
  3542. pRep = pAAInfo->Src.pRep;
  3543. pRepEnd = pAAInfo->Src.pRepEnd;
  3544. pAABufBeg = AAHdr.pAABufBeg;
  3545. pAABufEnd = AAHdr.pAABufEnd;
  3546. AABufInc = AAHdr.AABufInc;
  3547. pRep->c += pAAInfo->Src.cFirstSkip;
  3548. (pRepEnd - 1)->c += pAAInfo->Src.cLastSkip;
  3549. (LPBYTE)pAABufBeg -= ((LONG)pAAInfo->Src.cFirstSkip * AABufInc);
  3550. (LPBYTE)pAABufEnd += ((LONG)pAAInfo->Src.cLastSkip * AABufInc);
  3551. //
  3552. // Working on the CY now, fixup *(pRepEnd - 1) so it check the correct
  3553. // cRep
  3554. //
  3555. pAAInfo = AAHdr.pAAInfoCY;
  3556. pRep = pAAInfo->Src.pRep;
  3557. pRepEnd = pAAInfo->Src.pRepEnd;
  3558. (pRepEnd - 1)->c += pAAInfo->Src.cLastSkip;
  3559. cbSrc = (AAHdr.SrcSurfInfo.Flags & AASIF_GRAY) ? sizeof(BYTE) :
  3560. sizeof(BGR8);
  3561. pIn[0] = pAAInfo->pbExtra + (cbSrc * 3);
  3562. cbCX = (LONG)AAHdr.SrcSurfInfo.cbCX + (cbSrc * 6);
  3563. pIn[1] = (LPBYTE)pIn[0] + cbCX;
  3564. pIn[2] = (LPBYTE)pIn[1] + cbCX;
  3565. pIn[3] = (LPBYTE)pIn[2] + cbCX;
  3566. pIn[4] = (LPBYTE)pIn[3] + cbCX;
  3567. cbCX -= (cbSrc * 6);
  3568. if (cbSrc == 1) {
  3569. AASPFunc = (AASHARPENFUNC)GraySharpenInput;
  3570. FastExpAACXFunc = (FASTEXPAACXFUNC)GrayFastExpAA_CX;
  3571. } else {
  3572. AASPFunc = (AASHARPENFUNC)SharpenInput;
  3573. FastExpAACXFunc = (FASTEXPAACXFUNC)FastExpAA_CX;
  3574. }
  3575. iY = (LONG)pAAInfo->Src.cPrevSrc;
  3576. GetFixupScan(&AAHdr, (PBGR8)pIn[3]);
  3577. if (--iY < 0) {
  3578. AAHdr.Flags |= AAHF_GET_LAST_SCAN;
  3579. }
  3580. GetFixupScan(&AAHdr, (PBGR8)pIn[4]);
  3581. if (--iY < 0) {
  3582. AAHdr.Flags |= AAHF_GET_LAST_SCAN;
  3583. }
  3584. iY = -3;
  3585. AAHdr.pInputBeg += 3;
  3586. do {
  3587. pCur = pIn[0];
  3588. pIn[0] = pIn[1];
  3589. pIn[1] = pIn[2];
  3590. pIn[2] = pIn[3];
  3591. pIn[3] = pIn[4];
  3592. pIn[4] = pCur;
  3593. GetFixupScan(&AAHdr, (PBGR8)pCur);
  3594. AASPFunc(0, pIn[2], pIn[2], pIn[3], pIn[4], cbCX);
  3595. if (++iY < 0) {
  3596. continue;
  3597. }
  3598. iRep =
  3599. cRep = (LONG)pRep++->c;
  3600. if (!iY) {
  3601. cRep += pAAInfo->Src.cFirstSkip;
  3602. }
  3603. pCur = (LPBYTE)AAHdr.pInputBeg;
  3604. while ((iRep--) && (AAHdr.DstSurfInfo.cy)) {
  3605. switch (cRep) {
  3606. case 1:
  3607. Do5225(pCur, pIn[0], pIn[1], pIn[2], cbCX);
  3608. break;
  3609. case 2:
  3610. Do13(pCur, (iRep == 1) ? pIn[0] : pIn[2], pIn[1], cbCX);
  3611. break;
  3612. case 3:
  3613. if (iRep == 1) {
  3614. Do1141(pCur, pIn[0], pIn[1], pIn[2], cbCX);
  3615. } else {
  3616. Do35(pCur, (iRep == 2) ? pIn[0] : pIn[2], pIn[1], cbCX);
  3617. }
  3618. break;
  3619. case 4:
  3620. switch (iRep) {
  3621. case 3:
  3622. Do35(pCur, pIn[0], pIn[1], cbCX);
  3623. break;
  3624. case 2:
  3625. Do3121(pCur, pIn[0], pIn[1], pIn[2], cbCX);
  3626. break;
  3627. case 1:
  3628. Do3121(pCur, pIn[2], pIn[1], pIn[0], cbCX);
  3629. break;
  3630. case 0:
  3631. Do35(pCur, pIn[2], pIn[1], cbCX);
  3632. break;
  3633. }
  3634. break;
  3635. case 5:
  3636. switch (iRep) {
  3637. case 4:
  3638. Do1319(pCur, pIn[0], pIn[1], cbCX);
  3639. break;
  3640. case 3:
  3641. Do6251(pCur, pIn[0], pIn[1], pIn[2], cbCX);
  3642. break;
  3643. case 2:
  3644. Do3263(pCur, pIn[0], pIn[1], pIn[2], cbCX);
  3645. break;
  3646. case 1:
  3647. Do6251(pCur, pIn[2], pIn[1], pIn[0], cbCX);
  3648. break;
  3649. case 0:
  3650. Do1319(pCur, pIn[2], pIn[1], cbCX);
  3651. break;
  3652. }
  3653. break;
  3654. default:
  3655. DBGP("FastExpCY Invalid cRep=%ld" ARGDW(cRep));
  3656. ASSERT(cRep <= FAST_MAX_CY);
  3657. break;
  3658. }
  3659. CopyMemory(pCur - cbSrc, pCur, cbSrc);
  3660. CopyMemory(pCur + cbCX, pCur + cbCX - cbSrc, cbSrc);
  3661. FastExpAACXFunc(AAHdr.pAAInfoCX,
  3662. pCur,
  3663. (LPBYTE)pAABufBeg,
  3664. (LPBYTE)pAABufEnd,
  3665. AABufInc);
  3666. OUTPUT_AA_CURSCAN;
  3667. --AAHdr.DstSurfInfo.cy;
  3668. }
  3669. } while (AAHdr.DstSurfInfo.cy);
  3670. return(pAAHdr->DstSurfInfo.cy);
  3671. }