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.

4015 lines
120 KiB

  1. /*++
  2. Copyright (c) 1990-1991 Microsoft Corporation
  3. Module Name:
  4. htalias.c
  5. Abstract:
  6. This module contains all low levels halftone rendering functions.
  7. Author:
  8. 22-Jan-1991 Tue 12:49:03 created -by- Daniel Chou (danielc)
  9. [Environment:]
  10. GDI Device Driver - Halftone.
  11. [Notes:]
  12. Revision History:
  13. --*/
  14. #define DBGP_VARNAME dbgpHTAlias
  15. #include "htp.h"
  16. #include "htmapclr.h"
  17. #include "limits.h"
  18. #include "htpat.h"
  19. #include "htalias.h"
  20. #include "htstret.h"
  21. #include "htrender.h"
  22. #include "htgetbmp.h"
  23. #include "htsetbmp.h"
  24. #define DBGP_BUILD 0x00000001
  25. #define DBGP_BUILD2 0x00000002
  26. #define DBGP_BUILD3 0x00000004
  27. #define DBGP_EXPMATRIX 0x00000008
  28. #define DBGP_EXP 0x00000010
  29. #define DBGP_AAHEADER 0x00000020
  30. #define DBGP_OUTAA 0x00000040
  31. #define DBGP_FUNC 0x00000080
  32. #define DBGP_AAHT 0x00000100
  33. #define DBGP_AAHT_MEM 0x00000200
  34. #define DBGP_AAHT_TIME 0x00000400
  35. #define DBGP_AAHTPAT 0x00000800
  36. #define DBGP_FIXUPDIB 0x00001000
  37. #define DBGP_INPUT 0x00002000
  38. #define DBGP_VGA256XLATE 0x00004000
  39. #define DBGP_EXPAND 0x00008000
  40. #define DBGP_GETFIXUP 0x00010000
  41. #define DBGP_PSD 0x00020000
  42. #define DBGP_MASK 0x00040000
  43. #define DBGP_PALETTE 0x00080000
  44. #define DBGP_PAL_CHKSUM 0x00100000
  45. #define DBGP_LUT_MAP 0x00200000
  46. DEF_DBGPVAR(BIT_IF(DBGP_BUILD, 0) |
  47. BIT_IF(DBGP_BUILD2, 0) |
  48. BIT_IF(DBGP_BUILD3, 0) |
  49. BIT_IF(DBGP_EXPMATRIX, 0) |
  50. BIT_IF(DBGP_EXP, 0) |
  51. BIT_IF(DBGP_AAHEADER, 0) |
  52. BIT_IF(DBGP_OUTAA, 0) |
  53. BIT_IF(DBGP_FUNC, 0) |
  54. BIT_IF(DBGP_AAHT, 0) |
  55. BIT_IF(DBGP_AAHT_MEM, 0) |
  56. BIT_IF(DBGP_AAHT_TIME, 0) |
  57. BIT_IF(DBGP_AAHTPAT, 0) |
  58. BIT_IF(DBGP_FIXUPDIB, 0) |
  59. BIT_IF(DBGP_INPUT, 0) |
  60. BIT_IF(DBGP_VGA256XLATE, 0) |
  61. BIT_IF(DBGP_EXPAND, 0) |
  62. BIT_IF(DBGP_GETFIXUP, 0) |
  63. BIT_IF(DBGP_PSD, 0) |
  64. BIT_IF(DBGP_MASK, 0) |
  65. BIT_IF(DBGP_PALETTE, 0) |
  66. BIT_IF(DBGP_PAL_CHKSUM, 0) |
  67. BIT_IF(DBGP_LUT_MAP, 0))
  68. extern CONST RGBORDER SrcOrderTable[];
  69. extern DWORD dwABPreMul[256];
  70. #define SIZE_AAINFO _ALIGN_MEM(sizeof(AAINFO))
  71. //
  72. // Following computation is based on
  73. //
  74. // NTSC_R_INT = 299000
  75. // NTSC_G_INT = 587000
  76. // NTSC_B_INT = 114000
  77. // GRAY_MAX_IDX = 0xFFFF
  78. //
  79. // NTSC_R_GRAY_MAX = (((NTSC_R_INT * GRAY_MAX_IDX) + 500000) / 1000000)
  80. // NTSC_B_GRAY_MAX = (((NTSC_B_INT * GRAY_MAX_IDX) + 500000) / 1000000)
  81. // NTSC_G_GRAY_MAX = (GRAY_MAX_IDX - NTSC_R_GRAY_MAX - NTSC_B_GRAY_MAX)
  82. //
  83. #define NTSC_R_GRAY_MAX (DWORD)0x4c8b
  84. #define NTSC_B_GRAY_MAX (DWORD)0x1d2f
  85. #define NTSC_G_GRAY_MAX (DWORD)(0xFFFF - NTSC_R_GRAY_MAX - NTSC_B_GRAY_MAX)
  86. VOID
  87. HTENTRY
  88. SetGrayColorTable(
  89. PLONG pIdxBGR,
  90. PAASURFINFO pAASI
  91. )
  92. /*++
  93. Routine Description:
  94. Arguments:
  95. pIdxBGR - Pointer to how to translate from RGB to gray scale, typically
  96. this pointer is computed with NTSC gray standard plus any
  97. device transform or color adjustment, but if this pointer is
  98. NULL then we are reading from the device (1bpp, 8bpp) so we
  99. will only do NTSC standard mapping.
  100. Return Value:
  101. Author:
  102. 19-Feb-1999 Fri 13:14:01 created -by- Daniel Chou (danielc)
  103. Revision History:
  104. 08-Aug-2000 Tue 18:34:22 updated -by- Daniel Chou (danielc)
  105. Fixing bug for alpha blending, in gray scale mode, the destination
  106. can only be 1bpp or 8bpp mask mono, so when we read back from the
  107. destination to do alpha blending, it will double color mapping pixels.
  108. In gray scale mode, the input function will map the source RGB value
  109. to gray value with the current device transform, color adjustment and
  110. so on, so if we read back from destination then this transform is not
  111. desired.
  112. --*/
  113. {
  114. PRGB4B prgb4b;
  115. LONG cSrcTable;
  116. ASSERT(NTSC_R_INT == 299000);
  117. ASSERT(NTSC_G_INT == 587000);
  118. ASSERT(NTSC_B_INT == 114000);
  119. ASSERT(GRAY_MAX_IDX == 0xFFFF);
  120. if (cSrcTable = (LONG)pAASI->cClrTable) {
  121. prgb4b = pAASI->pClrTable;
  122. if (pIdxBGR) {
  123. //
  124. // This is a reading from the source
  125. //
  126. ASSERT(pAASI->Flags & AASIF_GRAY);
  127. ASSERT(pAASI->pIdxBGR == pIdxBGR);
  128. while (cSrcTable--) {
  129. prgb4b++->a = IDXBGR_2_GRAY_BYTE(pIdxBGR,
  130. prgb4b->b,
  131. prgb4b->g,
  132. prgb4b->r);
  133. }
  134. } else {
  135. //
  136. // We are reading from the destination so only do NTSC standard,
  137. // since the destination surface alreay halftoned.
  138. //
  139. while (cSrcTable--) {
  140. prgb4b++->a = (BYTE)((((DWORD)prgb4b->r * NTSC_R_GRAY_MAX) +
  141. ((DWORD)prgb4b->g * NTSC_G_GRAY_MAX) +
  142. ((DWORD)prgb4b->b * NTSC_B_GRAY_MAX) +
  143. (0x7FFF)) / 0xFFFF);
  144. }
  145. }
  146. } else if (pIdxBGR != pAASI->pIdxBGR) {
  147. //
  148. // This is the source surface info, we will see if this is the
  149. // gray color table
  150. //
  151. ASSERT(pAASI->Flags & AASIF_GRAY);
  152. ASSERT(pIdxBGR);
  153. ASSERT(pAASI->pIdxBGR);
  154. DBGP_IF(DBGP_INPUT,
  155. DBGP("Copy pIdxBGR [BGR] order from 012 to %ld%ld%ld"
  156. ARGDW(pAASI->AABFData.MaskRGB[2])
  157. ARGDW(pAASI->AABFData.MaskRGB[1])
  158. ARGDW(pAASI->AABFData.MaskRGB[0])));
  159. CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[2] * 256],
  160. &pIdxBGR[0 * 256], sizeof(LONG) * 256);
  161. CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[1] * 256],
  162. &pIdxBGR[1 * 256], sizeof(LONG) * 256);
  163. CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[0] * 256],
  164. &pIdxBGR[2 * 256], sizeof(LONG) * 256);
  165. }
  166. }
  167. VOID
  168. HTENTRY
  169. ComputeInputColorInfo(
  170. LPBYTE pSrcTable,
  171. UINT cPerTable,
  172. UINT PrimaryOrder,
  173. PBFINFO pBFInfo,
  174. PAASURFINFO pAASI
  175. )
  176. /*++
  177. Routine Description:
  178. Arguments:
  179. Return Value:
  180. Author:
  181. 19-Feb-1999 Fri 13:14:01 created -by- Daniel Chou (danielc)
  182. Revision History:
  183. --*/
  184. {
  185. PRGB4B prgb4b;
  186. PAABFDATA pAABFData;
  187. LONG cSrcTable;
  188. LONG Count;
  189. LONG LS;
  190. LONG RS;
  191. BYTE Mask;
  192. pAABFData = &pAASI->AABFData;
  193. if ((pSrcTable) &&
  194. (Count = cSrcTable = (LONG)pAASI->cClrTable)) {
  195. UINT iR;
  196. UINT iG;
  197. UINT iB;
  198. prgb4b = pAASI->pClrTable;
  199. iR = SrcOrderTable[PrimaryOrder].Order[0];
  200. iG = SrcOrderTable[PrimaryOrder].Order[1];
  201. iB = SrcOrderTable[PrimaryOrder].Order[2];
  202. switch (pAABFData->Format) {
  203. case BMF_1BPP:
  204. pAASI->InputFunc = (AAINPUTFUNC)Input1BPPToAA24;
  205. break;
  206. case BMF_4BPP_VGA16:
  207. case BMF_4BPP:
  208. pAASI->InputFunc = (AAINPUTFUNC)Input4BPPToAA24;
  209. break;
  210. case BMF_8BPP_VGA256:
  211. case BMF_8BPP:
  212. pAASI->InputFunc = (AAINPUTFUNC)Input8BPPToAA24;
  213. break;
  214. default:
  215. DBGP("ComputeInputColorInfo() Invalid Bitmap Format=%ld"
  216. ARGDW(pAABFData->Format));
  217. break;
  218. }
  219. while (Count--) {
  220. prgb4b->r = *(pSrcTable + iR);
  221. prgb4b->g = *(pSrcTable + iG);
  222. prgb4b->b = *(pSrcTable + iB);
  223. DBGP_IF(DBGP_PALETTE,
  224. DBGP("Source Pal [%3ld] = %3ld:%3ld:%3ld"
  225. ARGDW((LONG)cSrcTable - Count - 1) ARGDW(prgb4b->r)
  226. ARGDW(prgb4b->g) ARGDW(prgb4b->b)));
  227. ++prgb4b;
  228. pSrcTable += cPerTable;
  229. }
  230. } else {
  231. pAASI->InputFunc = InputAABFDATAToAA24;
  232. if (pBFInfo->Flags & BFIF_RGB_888) {
  233. pAABFData->Flags |= AABF_MASK_IS_ORDER;
  234. pAABFData->MaskRGB[0] = (BYTE)pBFInfo->RGBOrder.Order[0];
  235. pAABFData->MaskRGB[1] = (BYTE)pBFInfo->RGBOrder.Order[1];
  236. pAABFData->MaskRGB[2] = (BYTE)pBFInfo->RGBOrder.Order[2];
  237. } else {
  238. //
  239. // This is bitfield, figure out how to do it, we want to lshift to
  240. // to edge then right shift to 8bpp then mask off the unwanted bit
  241. //
  242. //
  243. cSrcTable = 3;
  244. while (cSrcTable--) {
  245. LS = 0;
  246. RS = (LONG)pBFInfo->BitStart[cSrcTable];
  247. Count = (LONG)pBFInfo->BitCount[cSrcTable];
  248. if (Count >= 8) {
  249. RS += (Count - 8);
  250. Mask = 0xFF;
  251. } else {
  252. LS = 8 - Count;
  253. Mask = (0xFF << LS);
  254. if ((RS -= LS) < 0) {
  255. LS = -RS;
  256. RS = 0;
  257. } else {
  258. LS = 0;
  259. }
  260. }
  261. pAABFData->MaskRGB[cSrcTable] = (BYTE)Mask;
  262. pAABFData->LShiftRGB[cSrcTable] = (BYTE)LS;
  263. pAABFData->RShiftRGB[cSrcTable] = (BYTE)RS;
  264. DBGP_IF(DBGP_FUNC | DBGP_PALETTE,
  265. DBGP("BFData[%ld]: Bits=%08lx, LS=%2ld, RS=%2ld, Mask=%02lx -->%02lx"
  266. ARGDW(cSrcTable)
  267. ARGDW(pBFInfo->BitsRGB[cSrcTable])
  268. ARGDW(LS) ARGDW(RS) ARGDW(Mask)
  269. ARGDW(((pBFInfo->BitsRGB[cSrcTable] >> RS) << LS) & Mask)));
  270. }
  271. }
  272. switch (pBFInfo->BitmapFormat) {
  273. case BMF_16BPP:
  274. case BMF_16BPP_555:
  275. case BMF_16BPP_565:
  276. pAABFData->cbSrcInc = 2;
  277. break;
  278. case BMF_24BPP:
  279. ASSERT(pAABFData->Flags & AABF_MASK_IS_ORDER);
  280. if (pBFInfo->RGBOrder.Index == PRIMARY_ORDER_BGR) {
  281. ASSERT((pAABFData->MaskRGB[0] == 2) &&
  282. (pAABFData->MaskRGB[1] == 1) &&
  283. (pAABFData->MaskRGB[2] == 0));
  284. pAABFData->Flags |= AABF_SRC_IS_BGR8;
  285. }
  286. pAABFData->cbSrcInc = 3;
  287. break;
  288. case BMF_32BPP:
  289. if (pAASI->Flags & AASIF_AB_PREMUL_SRC) {
  290. ASSERT(pAABFData->Flags & AABF_MASK_IS_ORDER);
  291. ASSERT(dwABPreMul[0] == 0);
  292. switch (pBFInfo->RGBOrder.Index) {
  293. case PRIMARY_ORDER_BGR:
  294. ASSERT((pAABFData->MaskRGB[0] == 2) &&
  295. (pAABFData->MaskRGB[1] == 1) &&
  296. (pAABFData->MaskRGB[2] == 0));
  297. pAABFData->Flags |= AABF_SRC_IS_BGR_ALPHA;
  298. break;
  299. case PRIMARY_ORDER_RGB:
  300. ASSERT((pAABFData->MaskRGB[0] == 0) &&
  301. (pAABFData->MaskRGB[1] == 1) &&
  302. (pAABFData->MaskRGB[2] == 2));
  303. pAABFData->Flags |= AABF_SRC_IS_RGB_ALPHA;
  304. break;
  305. default:
  306. break;
  307. }
  308. if (dwABPreMul[0] == 0) {
  309. pAASI->InputFunc = InputPreMul32BPPToAA24;
  310. }
  311. }
  312. pAABFData->cbSrcInc = 4;
  313. break;
  314. default:
  315. DBGP("ERROR: Invalid BFInfo Format=%ld" ARGDW(pBFInfo->BitmapFormat));
  316. break;
  317. }
  318. DBGP_IF(DBGP_FUNC,
  319. DBGP("Flags=%02lx. cbSrcInc=%ld, Mask=%02lx:%02lx:%02lx, LS=%2ld:%2ld:%2ld, RS=%2ld:%2ld:%2ld"
  320. ARGDW(pAABFData->Flags)
  321. ARGDW(pAABFData->cbSrcInc)
  322. ARGDW(pAABFData->MaskRGB[0])
  323. ARGDW(pAABFData->MaskRGB[1])
  324. ARGDW(pAABFData->MaskRGB[2])
  325. ARGDW(pAABFData->LShiftRGB[0])
  326. ARGDW(pAABFData->LShiftRGB[1])
  327. ARGDW(pAABFData->LShiftRGB[2])
  328. ARGDW(pAABFData->RShiftRGB[0])
  329. ARGDW(pAABFData->RShiftRGB[1])
  330. ARGDW(pAABFData->RShiftRGB[2])));
  331. }
  332. DBGP_IF(DBGP_FUNC,
  333. DBGP("+++++ InputFunc = %hs(SrcFmt=%ld), cClrTable=%ld\n"
  334. ARGPTR(GetAAInputFuncName(pAASI->InputFunc))
  335. ARGDW(pBFInfo->BitmapFormat) ARGDW(pAASI->cClrTable)));
  336. }
  337. PAAINFO
  338. HTENTRY
  339. BuildTileAAInfo(
  340. PDEVICECOLORINFO pDCI,
  341. DWORD AAHFlags,
  342. PLONG piSrcBeg,
  343. PLONG piSrcEnd,
  344. LONG SrcSize,
  345. LONG IdxDst,
  346. LONG IdxDstEnd,
  347. PLONG piDstBeg,
  348. PLONG piDstEnd,
  349. LONG cbExtra
  350. )
  351. /*++
  352. Routine Description:
  353. Arguments:
  354. piSrcBeg - Passed in as begining source index, When return this is the
  355. real source begining index. This always well ordered
  356. piSrcEnd - Passed in as ending source index, When return this is the
  357. real source ending index. This always well ordered
  358. SrcSize - The real size of source in pixel
  359. IdxDst - Starting index of destination pixel
  360. IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
  361. must be well ordered.
  362. piDstBeg - Clipped destination start index when passed in, at return
  363. it adjusted to the real destination starting index.
  364. piDstEnd - Clipped destination end index when passed in, at return
  365. it adjusted to the real destination ending index.
  366. cbExtra - Extra byte count to be allocated
  367. NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
  368. when it returned this is well ordered.
  369. Return Value:
  370. At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
  371. return from this function the *piSrcEnd and *piDstEnd is inclusive
  372. *piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
  373. is not NULL
  374. Author:
  375. 22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
  376. Revision History:
  377. --*/
  378. {
  379. PAAINFO pAAInfo;
  380. PEXPDATA pED;
  381. LONG cMatrix;
  382. LONG cM;
  383. LONG cIn;
  384. LONG cOut;
  385. LONG IdxSrc;
  386. LONG iSrcBeg;
  387. LONG iSrcEnd;
  388. LONG iDstBeg;
  389. LONG iDstEnd;
  390. LONG jSrcBeg;
  391. LONG jSrcEnd;
  392. LONG jDstBeg;
  393. LONG jDstEnd;
  394. LONG cLoop;
  395. LONG cAAData;
  396. iSrcBeg = *piSrcBeg;
  397. iSrcEnd = *piSrcEnd;
  398. //
  399. // The source always clipped to the visiable surface area
  400. //
  401. if (iSrcBeg < 0) {
  402. iSrcBeg = 0;
  403. }
  404. if (iSrcEnd > SrcSize) {
  405. iSrcEnd = SrcSize;
  406. }
  407. cIn = iSrcEnd - (IdxSrc = iSrcBeg);
  408. cOut = IdxDstEnd - IdxDst;
  409. if (cIn <= 0) {
  410. return(NULL);
  411. }
  412. ASSERT(cOut > 0);
  413. iDstBeg = *piDstBeg;
  414. iDstEnd = *piDstEnd;
  415. jSrcBeg = -1;
  416. ASSERT(iDstBeg < iDstEnd);
  417. DBGP_IF(DBGP_BUILD,
  418. DBGP("\nTile(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
  419. ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
  420. ARGDW(SrcSize) ARGDW(iDstBeg)
  421. ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
  422. ALIGN_MEM(cbExtra, cbExtra);
  423. if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
  424. HTMEM_BLTAA,
  425. LPTR,
  426. SIZE_AAINFO + cbExtra)) {
  427. SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + cbExtra);
  428. pAAInfo->pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
  429. cLoop = cOut;
  430. while (cLoop--) {
  431. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
  432. (IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
  433. if (jSrcBeg == -1) {
  434. jSrcBeg = IdxSrc;
  435. jDstBeg = IdxDst;
  436. }
  437. jSrcEnd = IdxSrc;
  438. jDstEnd = IdxDst;
  439. } else if (jSrcBeg != -1) {
  440. break;
  441. }
  442. if (++IdxSrc >= iSrcEnd) {
  443. IdxSrc = iSrcBeg;
  444. }
  445. ++IdxDst;
  446. }
  447. if (jSrcBeg == -1) {
  448. HTFreeMem(pAAInfo);
  449. return(NULL);
  450. }
  451. pAAInfo->iSrcBeg = jSrcBeg - iSrcBeg;
  452. jSrcBeg = iSrcBeg;
  453. jSrcEnd = iSrcEnd - 1;
  454. pAAInfo->Mask.iBeg =
  455. *piSrcBeg = jSrcBeg;
  456. *piSrcEnd = jSrcEnd;
  457. *piDstBeg = jDstBeg;
  458. *piDstEnd = jDstEnd;
  459. pAAInfo->Mask.iSize =
  460. pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
  461. pAAInfo->cOut = jDstEnd - jDstBeg + 1;
  462. pAAInfo->cAAData =
  463. pAAInfo->cAALoad = (DWORD)pAAInfo->cOut;
  464. pAAInfo->Mask.cIn = cIn;
  465. pAAInfo->Mask.cOut = cOut;
  466. DBGP_IF(DBGP_BUILD,
  467. DBGP("TILE(%ld->%ld): iSrc=%ld:%ld (%ld), iDst=%ld:%ld, cAAData=%ld, cbExtra=%ld, Flags=%04lx"
  468. ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
  469. ARGDW(*piSrcBeg) ARGDW(*piSrcEnd)
  470. ARGDW(pAAInfo->iSrcBeg) ARGDW(*piDstBeg)
  471. ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
  472. ARGDW(cbExtra) ARGDW(pAAInfo->Flags)));
  473. }
  474. return(pAAInfo);
  475. }
  476. PAAINFO
  477. HTENTRY
  478. BuildBltAAInfo(
  479. PDEVICECOLORINFO pDCI,
  480. DWORD AAHFlags,
  481. PLONG piSrcBeg,
  482. PLONG piSrcEnd,
  483. LONG SrcSize,
  484. LONG IdxDst,
  485. LONG IdxDstEnd,
  486. PLONG piDstBeg,
  487. PLONG piDstEnd,
  488. LONG cbExtra
  489. )
  490. /*++
  491. Routine Description:
  492. Arguments:
  493. piSrcBeg - Passed in as begining source index, When return this is the
  494. real source begining index. This always well ordered
  495. piSrcEnd - Passed in as ending source index, When return this is the
  496. real source ending index. This always well ordered
  497. SrcSize - The real size of source in pixel
  498. IdxDst - Starting index of destination pixel
  499. IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
  500. must be well ordered.
  501. piDstBeg - Clipped destination start index when passed in, at return
  502. it adjusted to the real destination starting index.
  503. piDstEnd - Clipped destination end index when passed in, at return
  504. it adjusted to the real destination ending index.
  505. cbExtra - Extra byte count to be allocated
  506. NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
  507. when it returned this is well ordered.
  508. Return Value:
  509. At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
  510. return from this function the *piSrcEnd and *piDstEnd is inclusive
  511. *piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
  512. is not NULL
  513. Author:
  514. 22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
  515. Revision History:
  516. --*/
  517. {
  518. PAAINFO pAAInfo;
  519. PEXPDATA pED;
  520. LONG cMatrix;
  521. LONG cM;
  522. LONG cIn;
  523. LONG cOut;
  524. LONG IdxSrc;
  525. LONG iSrcBeg;
  526. LONG iSrcEnd;
  527. LONG iDstBeg;
  528. LONG iDstEnd;
  529. LONG jSrcBeg;
  530. LONG jSrcEnd;
  531. LONG jDstBeg;
  532. LONG jDstEnd;
  533. LONG cLoop;
  534. LONG cAAData;
  535. cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
  536. cOut = IdxDstEnd - IdxDst;
  537. ASSERT(cOut > 0);
  538. if (iSrcBeg < 0) {
  539. iSrcBeg = 0;
  540. }
  541. if (iSrcEnd > SrcSize) {
  542. iSrcEnd = SrcSize;
  543. }
  544. iDstBeg = *piDstBeg;
  545. iDstEnd = *piDstEnd;
  546. jSrcBeg = -1;
  547. ASSERT(iDstBeg < iDstEnd);
  548. ASSERT(cIn == cOut);
  549. DBGP_IF(DBGP_BUILD,
  550. DBGP("\nBlt(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
  551. ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
  552. ARGDW(SrcSize) ARGDW(iDstBeg)
  553. ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
  554. ALIGN_MEM(cbExtra, cbExtra);
  555. if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
  556. HTMEM_BLTAA,
  557. LPTR,
  558. SIZE_AAINFO + cbExtra)) {
  559. SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + cbExtra);
  560. pAAInfo->pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
  561. cLoop = cOut;
  562. while (cLoop--) {
  563. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
  564. (IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
  565. if (jSrcBeg == -1) {
  566. jSrcBeg = IdxSrc;
  567. jDstBeg = IdxDst;
  568. }
  569. jSrcEnd = IdxSrc;
  570. jDstEnd = IdxDst;
  571. } else if (jSrcBeg != -1) {
  572. break;
  573. }
  574. ++IdxSrc;
  575. ++IdxDst;
  576. }
  577. if (jSrcBeg == -1) {
  578. HTFreeMem(pAAInfo);
  579. return(NULL);
  580. }
  581. pAAInfo->Mask.iBeg =
  582. *piSrcBeg = jSrcBeg;
  583. *piSrcEnd = jSrcEnd;
  584. *piDstBeg = jDstBeg;
  585. *piDstEnd = jDstEnd;
  586. pAAInfo->Mask.iSize =
  587. pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
  588. pAAInfo->cOut = jDstEnd - jDstBeg + 1;
  589. pAAInfo->cAAData =
  590. pAAInfo->cAALoad = (DWORD)pAAInfo->cOut;
  591. pAAInfo->Mask.cIn = cIn;
  592. pAAInfo->Mask.cOut = cOut;
  593. DBGP_IF(DBGP_BUILD,
  594. DBGP("BLT(%ld->%ld): iSrc=%ld:%ld, iDst=%ld:%ld, cAAData=%ld, cbExtra=%ld, Flags=%4lx"
  595. ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
  596. ARGDW(*piSrcBeg) ARGDW(*piSrcEnd) ARGDW(*piDstBeg)
  597. ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
  598. ARGDW(cbExtra) ARGDW(pAAInfo->Flags)));
  599. }
  600. return(pAAInfo);
  601. }
  602. #define _MATRIX_POW (FD6)1414214
  603. #if DBG
  604. FD6 MATRIX_POWER = _MATRIX_POW;
  605. #else
  606. #define MATRIX_POWER _MATRIX_POW
  607. #endif
  608. BOOL
  609. HTENTRY
  610. BuildRepData(
  611. PSRCBLTINFO pSBInfo,
  612. LONG IdxSrc,
  613. LONG IdxDst
  614. )
  615. /*++
  616. Routine Description:
  617. Arguments:
  618. piSrcBeg - Passed in as begining source index, When return this is the
  619. real source begining index. This always well ordered
  620. piSrcEnd - Passed in as ending source index, When return this is the
  621. real source ending index. This always well ordered
  622. SrcSize - The real size of source in pixel
  623. IdxDst - Starting index of destination pixel
  624. IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
  625. must be well ordered. (exclusive)
  626. piDstBeg - Clipped destination start index when passed in, at return
  627. it adjusted to the real destination starting index.
  628. piDstEnd - Clipped destination end index when passed in, at return
  629. it adjusted to the real destination ending index.
  630. cbExtra - Extra byte count to be allocated
  631. NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
  632. when it returned this is well ordered.
  633. Return Value:
  634. At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
  635. return from this function the *piSrcEnd and *piDstEnd is inclusive
  636. *piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
  637. is not NULL
  638. Author:
  639. 22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
  640. Revision History:
  641. --*/
  642. {
  643. PREPDATA pRep;
  644. PREPDATA pRepEnd;
  645. SRCBLTINFO SBInfo;
  646. PLONG pSrcInc;
  647. PLONG pDstInc;
  648. LONG MinRep;
  649. LONG MaxRep;
  650. LONG cRem;
  651. LONG iRep;
  652. LONG cRep;
  653. LONG cTot;
  654. LONG cIn;
  655. LONG cOut;
  656. LONG jSrcBeg;
  657. LONG jSrcEnd;
  658. LONG jDstBeg;
  659. LONG jDstEnd;
  660. UINT cPrevSrc;
  661. UINT cNextSrc;
  662. SBInfo = *pSBInfo;
  663. pRep = SBInfo.pRep;
  664. pRepEnd = SBInfo.pRepEnd;
  665. jSrcBeg = -1;
  666. if (SBInfo.cIn < SBInfo.cOut) {
  667. //
  668. // Expanding
  669. //
  670. cIn = SBInfo.cIn;
  671. cOut = SBInfo.cOut;
  672. pSrcInc = &IdxSrc;
  673. pDstInc = &IdxDst;
  674. } else if (SBInfo.cIn > SBInfo.cOut) {
  675. //
  676. // Shrinking
  677. //
  678. cIn = SBInfo.cOut;
  679. cOut = SBInfo.cIn;
  680. pSrcInc = &IdxDst;
  681. pDstInc = &IdxSrc;
  682. } else {
  683. ASSERT(SBInfo.cIn != SBInfo.cOut);
  684. return(FALSE);
  685. }
  686. MinRep = cOut / cIn;
  687. MaxRep = MinRep + 1;
  688. DBGP_IF(DBGP_BUILD,
  689. DBGP("\nEXPREP(%ld-%ld): iSrc=%ld-%ld, iDst=%ld-%ld, Idx=%ld:%ld"
  690. ARGDW(SBInfo.cIn) ARGDW(SBInfo.cOut)
  691. ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
  692. ARGDW(SBInfo.iDstBeg)
  693. ARGDW(SBInfo.iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
  694. SBInfo.cFirstSkip =
  695. SBInfo.cLastSkip = 0;
  696. iRep =
  697. cRep =
  698. cTot = 0;
  699. //
  700. // Multiply In/Out by 2, so we do not have run down/up problem, the
  701. // cRem will be initialized with extra 0.5 for rounding.
  702. //
  703. cRem = (cOut <<= 1) + cIn;
  704. cIn <<= 1;
  705. while (IdxDst < SBInfo.iDstEnd) {
  706. if ((cRem -= cIn) < 0) {
  707. ++*pSrcInc;
  708. if (jSrcBeg != -1) {
  709. ASSERT(pRep < pRepEnd);
  710. ASSERT(cRep > 0);
  711. ASSERT(cRep <= MaxRep);
  712. pRep++->c = (WORD)cRep;
  713. cTot += cRep;
  714. DBGP_IF(DBGP_BUILD2,
  715. DBGP(" Src=%4ld [%4ld-%4ld], Dst=%4ld [%4ld-%4ld], Rep %4ld=%3ld [%4ld -> %4ld, Rem=%4ld, cTot=%4ld]"
  716. ARGDW(IdxSrc) ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
  717. ARGDW(IdxDst) ARGDW(SBInfo.iDstBeg) ARGDW(SBInfo.iDstEnd)
  718. ARGDW(pRep - SBInfo.pRep) ARGDW(cRep)
  719. ARGDW(cIn) ARGDW(cOut) ARGDW(cRem) ARGDW(cTot)));
  720. }
  721. DBGP_IF(DBGP_BUILD3,
  722. DBGP("IdxSrc=%4ld, IdxDst=%4ld, Rep=%3ld / %3ld, Rem=%5ld, cIn=%5ld"
  723. ARGDW(IdxSrc) ARGDW(IdxDst)
  724. ARGDW(cRep) ARGDW(1) ARGDW(cRem) ARGDW(cIn)));
  725. cRem += cOut;
  726. iRep =
  727. cRep = 0;
  728. } else {
  729. DBGP_IF(DBGP_BUILD3,
  730. DBGP("IdxSrc=%4ld, IdxDst=%4ld, Rep=%3ld / %3ld, Rem=%5ld, cIn=%5ld"
  731. ARGDW(IdxSrc) ARGDW(IdxDst)
  732. ARGDW(cRep) ARGDW(iRep + 1) ARGDW(cRem) ARGDW(cIn)));
  733. }
  734. ++iRep;
  735. if ((IdxSrc >= SBInfo.iSrcBeg) && (IdxSrc < SBInfo.iSrcEnd) &&
  736. (IdxDst >= SBInfo.iDstBeg) && (IdxDst < SBInfo.iDstEnd)) {
  737. ++cRep;
  738. if (jSrcBeg == -1) {
  739. //
  740. // Any iRep will be the first pixel on the destination that
  741. // corresponding to the current source, so minus 1 is the
  742. // total count to be skip for this group of destination
  743. //
  744. jSrcBeg = IdxSrc;
  745. jDstBeg = IdxDst;
  746. SBInfo.cFirstSkip = (BYTE)(iRep - 1);
  747. DBGP_IF(DBGP_BUILD3,
  748. DBGP(" @@@ Set cFirstSkip=%ld at IdxDst=%ld @@@"
  749. ARGDW(SBInfo.cFirstSkip) ARGDW(IdxDst)));
  750. }
  751. jSrcEnd = IdxSrc;
  752. jDstEnd = IdxDst;
  753. } else if (jSrcBeg != -1) {
  754. break;
  755. }
  756. ++*pDstInc;
  757. }
  758. if (jSrcBeg == -1) {
  759. DBGP_IF(DBGP_BUILD3,
  760. DBGP(" Nothing in the source is on the destination"));
  761. return(FALSE);
  762. }
  763. if (cRep) {
  764. ASSERT(pRep < pRepEnd);
  765. pRep++->c = (WORD)cRep;
  766. cTot += cRep;
  767. DBGP_IF(DBGP_BUILD2,
  768. DBGP(" ****** Total pRep=%ld, Last cRep=%ld, cTot=%ld"
  769. ARGDW(pRep - SBInfo.pRep)
  770. ARGDW(cRep) ARGDW(cTot)));
  771. }
  772. while ((cRem -= cIn) >= 0) {
  773. ++SBInfo.cLastSkip;
  774. DBGP_IF(DBGP_BUILD3,
  775. DBGP(" @@@ Set cLastSkip=%4ld, cRem=%5ld @@@"
  776. ARGDW(SBInfo.cLastSkip) ARGDW(cRem)));
  777. }
  778. if (SBInfo.cIn < SBInfo.cOut) {
  779. //
  780. // Expanding, checking for maximum 2 sourcs pixels on each side
  781. //
  782. cPrevSrc =
  783. cNextSrc = 2;
  784. } else {
  785. //
  786. // Shrinking, checking only cFirstSkip and cLastSkip
  787. //
  788. cPrevSrc = (UINT)SBInfo.cFirstSkip;
  789. cNextSrc = (UINT)SBInfo.cLastSkip;
  790. }
  791. //
  792. // Check src begin
  793. //
  794. IdxSrc = jSrcBeg;
  795. while ((cPrevSrc) && (IdxSrc > SBInfo.iSrcBeg)) {
  796. --IdxSrc;
  797. --cPrevSrc;
  798. }
  799. SBInfo.cPrevSrc = (BYTE)(jSrcBeg - IdxSrc);
  800. IdxSrc = jSrcEnd;
  801. while ((cNextSrc) && (IdxSrc < (SBInfo.iSrcEnd - 1))) {
  802. ++IdxSrc;
  803. --cNextSrc;
  804. }
  805. SBInfo.cNextSrc = (BYTE)(IdxSrc - jSrcEnd);
  806. DBGP_IF(DBGP_BUILD3,
  807. DBGP("cFirstSkip=%ld (%ld), cLastSkip=%ld (%ld), cPrevSrc=%ld, cNextSrc=%ld"
  808. ARGDW(SBInfo.cFirstSkip) ARGDW(SBInfo.pRep->c)
  809. ARGDW(SBInfo.cLastSkip) ARGDW((pRep - 1)->c)
  810. ARGDW(SBInfo.cPrevSrc) ARGDW(SBInfo.cNextSrc)));
  811. // Bug 27036: ensure SBInfo.iSrcEnd is always exclusive
  812. SBInfo.iBeg =
  813. SBInfo.iSrcBeg = jSrcBeg;
  814. SBInfo.iSrcEnd = jSrcEnd + 1;
  815. SBInfo.iDstBeg = jDstBeg;
  816. SBInfo.iDstEnd = jDstEnd + 1;
  817. SBInfo.iSize = jSrcEnd - jSrcBeg + 1;
  818. SBInfo.pRepEnd = pRep;
  819. SBInfo.cRep = 1;
  820. DBGP_IF((DBGP_BUILD | DBGP_BUILD2 | DBGP_BUILD3),
  821. DBGP("EXPREP(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, iRepSize=%ld"
  822. ARGDW(SBInfo.cIn) ARGDW(SBInfo.cOut)
  823. ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
  824. ARGDW(SBInfo.iDstBeg) ARGDW(SBInfo.iDstEnd)
  825. ARGDW(SBInfo.pRepEnd - SBInfo.pRep)));
  826. *pSBInfo = SBInfo;
  827. return(TRUE);
  828. }
  829. PAAINFO
  830. HTENTRY
  831. BuildExpandAAInfo(
  832. PDEVICECOLORINFO pDCI,
  833. DWORD AAHFlags,
  834. PLONG piSrcBeg,
  835. PLONG piSrcEnd,
  836. LONG SrcSize,
  837. LONG IdxDst,
  838. LONG IdxDstEnd,
  839. PLONG piDstBeg,
  840. PLONG piDstEnd,
  841. LONG cbExtra
  842. )
  843. /*++
  844. Routine Description:
  845. Arguments:
  846. piSrcBeg - Passed in as begining source index, When return this is the
  847. real source begining index. This always well ordered
  848. piSrcEnd - Passed in as ending source index, When return this is the
  849. real source ending index. This always well ordered
  850. SrcSize - The real size of source in pixel
  851. IdxDst - Starting index of destination pixel
  852. IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
  853. must be well ordered. (exclusive)
  854. piDstBeg - Clipped destination start index when passed in, at return
  855. it adjusted to the real destination starting index.
  856. piDstEnd - Clipped destination end index when passed in, at return
  857. it adjusted to the real destination ending index.
  858. cbExtra - Extra byte count to be allocated
  859. NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
  860. when it returned this is well ordered.
  861. Return Value:
  862. At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
  863. return from this function the *piSrcEnd and *piDstEnd is inclusive
  864. *piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
  865. is not NULL
  866. Author:
  867. 22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
  868. Revision History:
  869. --*/
  870. {
  871. PAAINFO pAAInfo;
  872. PEXPDATA pED;
  873. LONG cMatrix;
  874. LONG cM;
  875. LONG cIn;
  876. LONG cOut;
  877. LONG IdxSrc;
  878. LONG iSrcBeg;
  879. LONG iSrcEnd;
  880. LONG iDstBeg;
  881. LONG iDstEnd;
  882. LONG jSrcBeg;
  883. LONG jSrcEnd;
  884. LONG jDstBeg;
  885. LONG jDstEnd;
  886. LONGLONG cTot;
  887. LONG MulAdd;
  888. LONG Mul;
  889. DWORD cAALoad;
  890. LONG cbRep;
  891. LONG cRem;
  892. DWORD cbED;
  893. cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
  894. cOut = IdxDstEnd - IdxDst;
  895. ASSERT(cOut > 0);
  896. if (iSrcBeg < 0) {
  897. iSrcBeg = 0;
  898. }
  899. if (iSrcEnd > SrcSize) {
  900. iSrcEnd = SrcSize;
  901. }
  902. iDstBeg = *piDstBeg;
  903. iDstEnd = *piDstEnd;
  904. jSrcBeg = -1;
  905. cAALoad = 0;
  906. ASSERT(iDstBeg < iDstEnd);
  907. ASSERT(cIn < cOut);
  908. DBGP_IF(DBGP_BUILD,
  909. DBGP("\nEXP(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
  910. ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
  911. ARGDW(SrcSize) ARGDW(iDstBeg)
  912. ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
  913. if (AAHFlags & (AAHF_HAS_MASK |
  914. AAHF_ALPHA_BLEND |
  915. AAHF_FAST_EXP_AA |
  916. AAHF_BBPF_AA_OFF)) {
  917. ALIGN_MEM(cbRep, (iSrcEnd - iSrcBeg + 3) * sizeof(REPDATA));
  918. } else {
  919. cbRep = 0;
  920. }
  921. if (AAHFlags & (AAHF_BBPF_AA_OFF | AAHF_FAST_EXP_AA)) {
  922. cMatrix =
  923. cbED =
  924. cM = 0;
  925. } else {
  926. cMatrix = (LONG)((((cOut + (cIn - 1)) / cIn) << 1) - 1);
  927. cM = sizeof(DWORD) * cMatrix;
  928. ALIGN_MEM(cbED, (iDstEnd - iDstBeg) * sizeof(EXPDATA));
  929. }
  930. DBGP_IF(DBGP_BUILD,
  931. DBGP("BuildEXP(%ld, %ld), cMatrix=%ld, cb=%ld+%ld+%ld=%ld"
  932. ARGDW(cIn) ARGDW(cOut) ARGDW(cMatrix)
  933. ARGDW(cbRep) ARGDW(cbED) ARGDW(cM)
  934. ARGDW(cbRep + cbED + cM)));
  935. ALIGN_MEM(cbExtra, cbExtra);
  936. if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
  937. HTMEM_EXPAA,
  938. LPTR,
  939. cbRep + cbED +
  940. cbExtra + cM + SIZE_AAINFO)) {
  941. LPBYTE pbExtra;
  942. SETDBGVAR(pAAInfo->cbAlloc, cbRep + cbED + cbExtra + cM + SIZE_AAINFO);
  943. pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
  944. if (cbExtra) {
  945. pAAInfo->pbExtra = (LPBYTE)pbExtra;
  946. pbExtra += cbExtra;
  947. }
  948. if (cbRep) {
  949. pAAInfo->Src.cIn = cIn;
  950. pAAInfo->Src.cOut = cOut;
  951. pAAInfo->Src.iSrcBeg = iSrcBeg;
  952. pAAInfo->Src.iSrcEnd = iSrcEnd;
  953. pAAInfo->Src.iDstBeg = iDstBeg;
  954. pAAInfo->Src.iDstEnd = iDstEnd;
  955. pAAInfo->Src.pRep = (PREPDATA)pbExtra;
  956. pAAInfo->Src.pRepEnd = pAAInfo->Src.pRep + (iSrcEnd - iSrcBeg);
  957. pbExtra += cbRep;
  958. if (!BuildRepData(&(pAAInfo->Src), IdxSrc, IdxDst)) {
  959. HTFreeMem(pAAInfo);
  960. return(NULL);
  961. }
  962. pAAInfo->AB =
  963. pAAInfo->Mask = pAAInfo->Src;
  964. if (AAHFlags & AAHF_FAST_EXP_AA) {
  965. pAAInfo->Src.iSrcBeg -= pAAInfo->Src.cPrevSrc;
  966. pAAInfo->Src.iSrcEnd += pAAInfo->Src.cNextSrc;
  967. }
  968. }
  969. if (cbED) {
  970. PEXPDATA pED;
  971. PEXPDATA pEDEnd;
  972. LPDWORD pM;
  973. LPDWORD pM1;
  974. LPDWORD pM2;
  975. LONG cRem2;
  976. LONG MincM;
  977. LONGLONG ExpMul[4];
  978. EXPDATA ed;
  979. WORD EDFlags;
  980. LONGLONG cNum;
  981. LONG cLoop;
  982. LONG cMul0;
  983. LONG cMul1;
  984. LONG cMaskRem;
  985. LONG iMaskBeg;
  986. LONG iMaskEnd;
  987. pED = (PEXPDATA)pbExtra;
  988. pAAInfo->pAAData = (LPVOID)pED;
  989. pM = (LPDWORD)((LPBYTE)pED + cbED);
  990. pM1 = pM;
  991. pM2 = pM1 + cMatrix - 1;
  992. cTot = 0;
  993. DBGP_IF(DBGP_BUILD,
  994. DBGP("Allocate cbExtra=%ld, pbExtra=%p:%p"
  995. ARGDW(cbExtra) ARGPTR(pAAInfo->pbExtra)
  996. ARGPTR((LPBYTE)pAAInfo->pbExtra + cbExtra)));
  997. pM2 = (pM1 += (cMatrix >> 1));
  998. cTot = (LONGLONG)(*pM1 = FD6_1);
  999. if (AAHFlags & AAHF_BBPF_AA_OFF) {
  1000. pAAInfo->Flags |= AAIF_EXP_NO_SHARPEN;
  1001. } else {
  1002. MulAdd = cOut;
  1003. while (((MulAdd -= cIn) > 0) && (--pM1 >= pM)) {
  1004. Mul = (LONG)DivFD6(MulAdd, cOut);
  1005. if (Mul != 500000) {
  1006. Mul = (LONG)RaisePower((FD6)Mul,
  1007. MATRIX_POWER,
  1008. (WORD)((Mul <= 500000) ?
  1009. 0 : RPF_RADICAL));
  1010. }
  1011. DBGP_IF(DBGP_EXPMATRIX,
  1012. DBGP("(%4ld, %4ld) = %s ^ %s = %s"
  1013. ARGDW(MulAdd) ARGDW(cOut)
  1014. ARGFD6((DivFD6(MulAdd, cOut)), 1, 6)
  1015. ARGFD6(MATRIX_POWER, 1, 6) ARGFD6(Mul, 1, 6)));
  1016. *pM1 =
  1017. *(++pM2) = Mul;
  1018. cTot += (Mul << 1);
  1019. }
  1020. }
  1021. #if DBG
  1022. {
  1023. FD6 PMPrev = FD6_0;
  1024. FD6 PMCur;
  1025. pM1 = pM;
  1026. cLoop = (LONG)cMatrix;
  1027. while (cLoop--) {
  1028. PMCur = DivFD6(*pM1, (FD6)cTot);
  1029. DBGP_IF(DBGP_EXPMATRIX, DBGP("%3ld: %7ld [%s], Dif=%s, cTot=%ld"
  1030. ARGDW((pM1 - pM) + 1) ARGDW(*pM1)
  1031. ARGFD6(PMCur, 1, 6) ARGFD6((PMCur - PMPrev), 1, 6)
  1032. ARGDW(cTot)));
  1033. PMPrev = PMCur;
  1034. ++pM1;
  1035. }
  1036. }
  1037. #endif
  1038. cTot *= (LONGLONG)cIn;
  1039. cRem = cOut + (cIn * (LONG)(cMatrix >> 1));
  1040. cLoop = cOut;
  1041. cMul0 =
  1042. cMul1 = 0;
  1043. while (cLoop--) {
  1044. cRem2 = cRem;
  1045. if ((cRem -= cIn) <= 0) {
  1046. cRem += cOut;
  1047. }
  1048. pM1 = pM;
  1049. cM = cMatrix;
  1050. MincM = (cMatrix >> 1) - cLoop;
  1051. EDFlags = 0;
  1052. ZeroMemory(ExpMul, sizeof(ExpMul));
  1053. while (cM--) {
  1054. LONG cMul;
  1055. Mul = *pM1++;
  1056. if ((cRem2 < cIn) && (cM >= MincM)) {
  1057. if (cMul = cRem2) {
  1058. ExpMul[3] += (LONGLONG)cRem2 * (LONGLONG)Mul;
  1059. }
  1060. cRem2 -= cIn;
  1061. ASSERTMSG("BuildEXP: Shift more than 3 times", !ExpMul[0]);
  1062. CopyMemory(&ExpMul[0], &ExpMul[1], sizeof(ExpMul[0]) * 3);
  1063. ExpMul[3] = (LONGLONG)-cRem2 * (LONGLONG)Mul;
  1064. cRem2 += cOut;
  1065. if (!cM) {
  1066. if ((++IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
  1067. EDFlags |= EDF_LOAD_PIXEL;
  1068. ++cAALoad;
  1069. ++IdxSrc;
  1070. if ((IdxSrc < iSrcBeg) ||
  1071. (IdxSrc >= iSrcEnd)) {
  1072. EDFlags |= EDF_NO_NEWSRC;
  1073. }
  1074. --IdxSrc;
  1075. }
  1076. }
  1077. } else {
  1078. ExpMul[3] += (LONGLONG)(cMul = cIn) * (LONGLONG)Mul;
  1079. cRem2 -= cIn;
  1080. }
  1081. DBGP_IF(DBGP_BUILD3,
  1082. DBGP("%5ld-%7ld:%7ld:%7ld:%7ld, %4ld+, cRem2=%4ld, cM=%5ld:%5ld, cMul=%5ldx%5ld%hs%hs"
  1083. ARGDW(cOut - cLoop - 1) ARGDW(ExpMul[0])
  1084. ARGDW(ExpMul[1]) ARGDW(ExpMul[2]) ARGDW(ExpMul[3])
  1085. ARGDW(cMul * Mul) ARGDW(cRem2) ARGDW(cM)
  1086. ARGDW(MincM) ARGDW(cMul) ARGDW(Mul)
  1087. ARGPTR((EDFlags & EDF_LOAD_PIXEL) ? ", Load Pixel" : "")
  1088. ARGPTR((EDFlags & EDF_NO_NEWSRC) ? ", NO New Src" : "")));
  1089. }
  1090. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
  1091. (IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
  1092. GET_FIRST_EDMUL(ed.Mul[3], ExpMul[3], cNum, cTot);
  1093. GET_NEXT_EDMUL( ed.Mul[2], ExpMul[2], cNum, cTot);
  1094. if (ExpMul[1]) {
  1095. ++cMul1;
  1096. GET_NEXT_EDMUL(ed.Mul[1], ExpMul[1], cNum, cTot);
  1097. if (ExpMul[0]) {
  1098. ++cMul0;
  1099. GET_NEXT_EDMUL(ed.Mul[0], ExpMul[0], cNum, cTot);
  1100. } else {
  1101. ed.Mul[0] = 0;
  1102. }
  1103. } else {
  1104. ed.Mul[1] =
  1105. ed.Mul[0] = 0;
  1106. }
  1107. ASSERTMSG("ed.Mul[0] > DI_MAX_NUM", ed.Mul[0] <= DI_MAX_NUM);
  1108. ASSERTMSG("ed.Mul[1] > DI_MAX_NUM", ed.Mul[1] <= DI_MAX_NUM);
  1109. ASSERTMSG("ed.Mul[2] > DI_MAX_NUM", ed.Mul[2] <= DI_MAX_NUM);
  1110. ASSERTMSG("ed.Mul[3] > DI_MAX_NUM", ed.Mul[3] <= DI_MAX_NUM);
  1111. DBGP_IF(DBGP_BUILD2,
  1112. DBGP("--%5ld=%7ld:%7ld:%7ld:%7ld, IdxSrc=%5ld --%hs%hs--"
  1113. ARGDW(IdxDst) ARGDW(ed.Mul[0])
  1114. ARGDW(ed.Mul[1]) ARGDW(ed.Mul[2])
  1115. ARGDW(ed.Mul[3]) ARGDW(IdxSrc)
  1116. ARGPTR((EDFlags & EDF_LOAD_PIXEL) ? ", Load Pixel" : "")
  1117. ARGPTR((EDFlags & EDF_NO_NEWSRC) ? ", NO New Src" : "")));
  1118. ed.Mul[0] |= EDFlags;
  1119. *pED++ = ed;
  1120. if (jSrcBeg == -1) {
  1121. iMaskBeg = (cOut - cLoop - 1);
  1122. jSrcBeg = IdxSrc;
  1123. jDstBeg = IdxDst;
  1124. }
  1125. jSrcEnd = IdxSrc;
  1126. jDstEnd = IdxDst;
  1127. } else if (jSrcBeg != -1) {
  1128. break;
  1129. }
  1130. ++IdxDst;
  1131. }
  1132. if (jSrcBeg == -1) {
  1133. HTFreeMem(pAAInfo);
  1134. return(NULL);
  1135. }
  1136. //
  1137. // 10-Jun-1998 Wed 08:41:16 updated -by- Daniel Chou (danielc)
  1138. // Fixed for the problem that we need to read extra source for the
  1139. // last loaded pixel because before expand we will sharpen the pixel
  1140. // by its 4 neighbors, this will make sure Last+1 pixel/scan line
  1141. // got read it for sharpen purpose
  1142. //
  1143. // BEGIN FIX
  1144. //
  1145. ++jSrcEnd;
  1146. if ((jSrcEnd < iSrcBeg) || (jSrcEnd >= iSrcEnd)) {
  1147. --jSrcEnd;
  1148. }
  1149. //
  1150. // END FIX
  1151. //
  1152. IdxSrc =
  1153. *piSrcBeg = jSrcBeg;
  1154. *piSrcEnd = jSrcEnd;
  1155. *piDstBeg = jDstBeg;
  1156. *piDstEnd = jDstEnd;
  1157. pEDEnd = pED;
  1158. pED = (PEXPDATA)(pAAInfo->pAAData);
  1159. pAAInfo->cAAData = (DWORD)(pEDEnd - pED);
  1160. pAAInfo->cAALoad = cAALoad;
  1161. pAAInfo->cMaxMul = (DWORD)((cMul1) ? ((cMul0) ? 4 : 3) : 2);
  1162. ed = *pED;
  1163. cLoop = 4;
  1164. if (ed.Mul[0] & EDF_LOAD_PIXEL) {
  1165. --IdxSrc;
  1166. --cLoop;
  1167. } else {
  1168. ++IdxSrc;
  1169. if ((IdxSrc < iSrcBeg) || (IdxSrc >= iSrcEnd)) {
  1170. pAAInfo->Flags |= AAIF_EXP_NO_LAST_RIGHT;
  1171. }
  1172. --IdxSrc;
  1173. }
  1174. cMul0 = 0;
  1175. while ((cMul0 < cLoop) &&
  1176. (!(ed.Mul[cMul0] & ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC)))) {
  1177. ++cMul0;
  1178. }
  1179. DBGP_IF(DBGP_BUILD,
  1180. DBGP("cMul0=%ld, cLoop=%ld, IdxSrc=%ld, iSrcBeg=%ld, iSrcEnd=%ld"
  1181. ARGDW(cMul0) ARGDW(cLoop) ARGDW(IdxSrc)
  1182. ARGDW(iSrcBeg) ARGDW(iSrcEnd)));
  1183. while (cLoop-- > cMul0) {
  1184. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
  1185. *piSrcBeg = IdxSrc;
  1186. pAAInfo->cPreLoad += 0x01;
  1187. } else {
  1188. pAAInfo->cPreLoad += 0x10;
  1189. }
  1190. --IdxSrc;
  1191. }
  1192. if (pAAInfo->cPreLoad) {
  1193. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
  1194. *piSrcBeg = IdxSrc;
  1195. pAAInfo->Flags |= AAIF_EXP_HAS_1ST_LEFT;
  1196. }
  1197. }
  1198. if (!(pAAInfo->cPreLoad)) {
  1199. DBGP("*** cPreLOAD=0, BuildExpandAAInfo [%04lx:%04lx:%04lx:%04lx], cPreload=0x%02lx, Flags=0x%04lx"
  1200. ARGDW(ed.Mul[0]) ARGDW(ed.Mul[1]) ARGDW(ed.Mul[2]) ARGDW(ed.Mul[3])
  1201. ARGDW(pAAInfo->cPreLoad) ARGDW(pAAInfo->Flags));
  1202. }
  1203. } else {
  1204. // Bug 27036: ensure jSrcEnd is less than iSrcEnd
  1205. *piSrcBeg = pAAInfo->Src.iSrcBeg;
  1206. *piSrcEnd = pAAInfo->Src.iSrcEnd - 1;
  1207. *piDstBeg = pAAInfo->Src.iDstBeg;
  1208. *piDstEnd = pAAInfo->Src.iDstEnd - 1;
  1209. }
  1210. pAAInfo->cIn = *piSrcEnd - *piSrcBeg + 1;
  1211. pAAInfo->cOut = *piDstEnd - *piDstBeg + 1;
  1212. DBGP_IF((DBGP_BUILD | DBGP_BUILD2 | DBGP_BUILD3),
  1213. DBGP("EXP(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, cAAData=%ld, cPreLoad=0x%02lx, Flags=0x%04lx"
  1214. ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
  1215. ARGDW(*piSrcBeg) ARGDW(*piSrcEnd) ARGDW(*piDstBeg)
  1216. ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
  1217. ARGDW(pAAInfo->cPreLoad) ARGDW(pAAInfo->Flags)));
  1218. }
  1219. return(pAAInfo);
  1220. }
  1221. PAAINFO
  1222. HTENTRY
  1223. BuildShrinkAAInfo(
  1224. PDEVICECOLORINFO pDCI,
  1225. DWORD AAHFlags,
  1226. PLONG piSrcBeg,
  1227. PLONG piSrcEnd,
  1228. LONG SrcSize,
  1229. LONG IdxDst,
  1230. LONG IdxDstEnd,
  1231. PLONG piDstBeg,
  1232. PLONG piDstEnd,
  1233. LONG cbExtra
  1234. )
  1235. /*++
  1236. Routine Description:
  1237. Arguments:
  1238. piSrcBeg - Passed in as begining source index, When return this is the
  1239. real source begining index. This always well ordered
  1240. piSrcEnd - Passed in as ending source index, When return this is the
  1241. real source ending index. This always well ordered
  1242. SrcSize - The real size of source in pixel
  1243. IdxDst - Starting index of destination pixel
  1244. IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
  1245. must be well ordered.
  1246. piDstBeg - Clipped destination start index when passed in, at return
  1247. it adjusted to the real destination starting index.
  1248. piDstEnd - Clipped destination end index when passed in, at return
  1249. it adjusted to the real destination ending index.
  1250. cbExtra - Extra byte count to be allocated
  1251. NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
  1252. when it returned this is well ordered.
  1253. Return Value:
  1254. PSHRINKINFO, if NULL then memory allocation failed
  1255. Author:
  1256. 20-Mar-1998 Fri 12:29:17 created -by- Daniel Chou (danielc)
  1257. Revision History:
  1258. --*/
  1259. {
  1260. PAAINFO pAAInfo;
  1261. PLONG pMap;
  1262. PLONG pMapEnd;
  1263. PSHRINKDATA pSD;
  1264. PSHRINKDATA pSDEnd;
  1265. LONG cIn;
  1266. LONG cOut;
  1267. LONG IdxSrc;
  1268. LONG IdxDstOrg;
  1269. LONG iSrcBeg;
  1270. LONG iSrcEnd;
  1271. LONG iDstBeg;
  1272. LONG iDstEnd;
  1273. LONG jSrcBeg;
  1274. LONG jSrcEnd;
  1275. LONG jDstBeg;
  1276. LONG jDstEnd;
  1277. LONG cLoop;
  1278. LONG cbRep;
  1279. LONG Mul;
  1280. LONG NextMul;
  1281. LONG CurMul;
  1282. LONG cCur;
  1283. LONG MinPixel;
  1284. DWORD cAAData;
  1285. DWORD cAADone;
  1286. LONGLONG cNum;
  1287. cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
  1288. cOut = IdxDstEnd - (IdxDstOrg = IdxDst);
  1289. ASSERT(cOut > 0);
  1290. if (iSrcBeg < 0) {
  1291. iSrcBeg = 0;
  1292. }
  1293. if (iSrcEnd > SrcSize) {
  1294. iSrcEnd = SrcSize;
  1295. }
  1296. //
  1297. // For shrinking we will enlarge the destination by 1 on both side to
  1298. // obtained the source pixel that for sharpening purpose
  1299. //
  1300. iDstBeg = *piDstBeg - 1;
  1301. iDstEnd = *piDstEnd;
  1302. jSrcBeg = -1;
  1303. cAADone = 0;
  1304. ASSERT(iDstBeg < iDstEnd);
  1305. ASSERT(cIn > cOut);
  1306. DBGP_IF(DBGP_BUILD,
  1307. DBGP("\nSRK(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld (%ld-%ld), Idx=%ld:%ld"
  1308. ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
  1309. ARGDW(SrcSize) ARGDW(iDstBeg) ARGDW(iDstEnd)
  1310. ARGDW(*piDstBeg) ARGDW(*piDstEnd)
  1311. ARGDW(IdxSrc) ARGDW(IdxDst)));
  1312. //
  1313. // Firstable figure out how may SHRINKDATA needed
  1314. //
  1315. cAAData = (DWORD)((((iDstEnd - iDstBeg + 1) * cIn) + (cOut-1)) / cOut) + 4;
  1316. if ((LONG)cAAData > cIn) {
  1317. (LONG)cAAData = cIn;
  1318. }
  1319. DBGP_IF(DBGP_BUILD,
  1320. DBGP("BuildShrink(%ld-%ld): cSD estimated=%ld (%ld), iDst=%ld-%ld=%ld"
  1321. ARGDW(cIn) ARGDW(cOut) ARGDW(cAAData) ARGDW(cIn)
  1322. ARGDW(iDstBeg) ARGDW(iDstEnd) ARGDW(iDstEnd - iDstBeg)));
  1323. ALIGN_MEM(CurMul, 256 * 2 * sizeof(LONG));
  1324. ALIGN_MEM(cCur, (cAAData + 1) * sizeof(SHRINKDATA));
  1325. CurMul += cCur;
  1326. MinPixel = (LONG)(((LONGLONG)cOut * (LONGLONG)DI_MAX_NUM) / (LONGLONG)cIn);
  1327. if (AAHFlags & (AAHF_HAS_MASK |
  1328. AAHF_ALPHA_BLEND |
  1329. AAHF_FAST_EXP_AA |
  1330. AAHF_BBPF_AA_OFF)) {
  1331. ALIGN_MEM(cbRep, (iDstEnd - iDstBeg + 4) * sizeof(REPDATA));
  1332. if (AAHFlags & AAHF_BBPF_AA_OFF) {
  1333. CurMul = 0;
  1334. }
  1335. } else {
  1336. cbRep = 0;
  1337. }
  1338. ALIGN_MEM(cbExtra, cbExtra);
  1339. if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
  1340. HTMEM_SRKAA,
  1341. LPTR,
  1342. SIZE_AAINFO + CurMul +
  1343. cbRep + cbExtra)) {
  1344. LPBYTE pbExtra;
  1345. SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + CurMul + cbRep + cbExtra);
  1346. pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
  1347. if (cbExtra) {
  1348. pAAInfo->pbExtra = (LPBYTE)pbExtra;
  1349. pbExtra += cbExtra;
  1350. }
  1351. if (cbRep) {
  1352. pAAInfo->Src.cIn = cIn;
  1353. pAAInfo->Src.cOut = cOut;
  1354. pAAInfo->Src.iSrcBeg = iSrcBeg;
  1355. pAAInfo->Src.iSrcEnd = iSrcEnd;
  1356. pAAInfo->Src.iDstBeg = iDstBeg + 1;
  1357. pAAInfo->Src.iDstEnd = iDstEnd;
  1358. pAAInfo->Src.pRep = (PREPDATA)pbExtra;
  1359. pAAInfo->Src.pRepEnd = pAAInfo->Src.pRep + (iDstEnd-iDstBeg+1);
  1360. pbExtra += cbRep;
  1361. if (!BuildRepData(&(pAAInfo->Src), IdxSrc, IdxDst)) {
  1362. HTFreeMem(pAAInfo);
  1363. return(NULL);
  1364. }
  1365. pAAInfo->AB =
  1366. pAAInfo->Mask = pAAInfo->Src;
  1367. }
  1368. if (CurMul) {
  1369. pAAInfo->cPreLoad = 1;
  1370. pMap =
  1371. pAAInfo->pMapMul = (PLONG)pbExtra;
  1372. pMapEnd = pMap + 256;
  1373. pSD = (PSHRINKDATA)(pMap + (256 * 2));
  1374. pSDEnd = pSD + cAAData;
  1375. pAAInfo->pAAData = (LPVOID)pSD;
  1376. Mul = -MinPixel;
  1377. CurMul = MinPixel + 1;
  1378. NextMul = -CurMul;
  1379. ASSERT_MEM_ALIGN(pAAInfo->pMapMul, sizeof(LONG));
  1380. //
  1381. // Build InMax 256 multiplication table
  1382. //
  1383. do {
  1384. pMap[ 0] = (Mul += MinPixel);
  1385. pMap[256] = (NextMul += CurMul);
  1386. } while (++pMap < pMapEnd);
  1387. //
  1388. // Build the SHRINKINFO table
  1389. //
  1390. CurMul = 0;
  1391. cCur =
  1392. cLoop = cIn;
  1393. cNum = (LONGLONG)0;
  1394. cAAData = 0;
  1395. --pSD;
  1396. while (cLoop--) {
  1397. WORD SDFlags;
  1398. if ((cCur -= cOut) <= 0) {
  1399. Mul = cCur + cOut;
  1400. NextMul = -cCur;
  1401. cCur += cIn;
  1402. SDFlags = SDF_DONE;
  1403. ++IdxDst;
  1404. } else {
  1405. Mul = cOut;
  1406. SDFlags = 0;
  1407. }
  1408. if ((IdxDst >= (iDstBeg - 1)) && (IdxDst <= iDstEnd)) {
  1409. cNum += ((LONGLONG)Mul * (LONGLONG)DI_MAX_NUM);
  1410. if ((Mul = (LONG)(cNum / cIn)) > MinPixel) {
  1411. SDFlags |= SDF_LARGE_MUL;
  1412. }
  1413. CurMul += Mul;
  1414. cNum %= cIn;
  1415. if (SDFlags & SDF_DONE) {
  1416. cNum = (LONGLONG)NextMul * (LONGLONG)DI_MAX_NUM;
  1417. NextMul = (LONG)(cNum / cIn);
  1418. if ((Mul + NextMul) > MinPixel) {
  1419. SDFlags |= SDF_LARGE_MUL;
  1420. } else {
  1421. SDFlags &= ~SDF_LARGE_MUL;
  1422. }
  1423. cNum %= cIn;
  1424. CurMul = NextMul;
  1425. NextMul = 0;
  1426. }
  1427. }
  1428. if ((IdxDst >= iDstBeg) && (IdxDst <= iDstEnd)) {
  1429. if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
  1430. //
  1431. // Save it first
  1432. //
  1433. cAADone += (SDFlags & SDF_DONE) ? 1 : 0;
  1434. if (++pSD >= pSDEnd) {
  1435. DBGP("Error(1): cAAData Overrun of %ld, Fixed it"
  1436. ARGDW(++cAAData));
  1437. ASSERT(pSD < pSDEnd);
  1438. --pSD;
  1439. }
  1440. pSD->Mul = (WORD)Mul | SDFlags;
  1441. ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
  1442. if (jSrcBeg == -1) {
  1443. jSrcBeg =
  1444. jSrcEnd = IdxSrc;
  1445. jDstBeg =
  1446. jDstEnd = IdxDst;
  1447. if (SDFlags & SDF_DONE) {
  1448. //
  1449. // If we just finished a pixel then we need to see
  1450. // if it is a source index or a detination index
  1451. // cause the output become valid
  1452. //
  1453. if (IdxDst == iDstBeg) {
  1454. //
  1455. // The destination just become valid now,
  1456. // PreMul is the start of current detination
  1457. // until next done pixel
  1458. //
  1459. DBGP_IF(DBGP_BUILD,
  1460. DBGP("@@ FIRST DEST: PreMul=CurMul=%ld, No PSD, IncSrc"
  1461. ARGDW(CurMul)));
  1462. pAAInfo->PreMul = (WORD)CurMul;
  1463. pAAInfo->PreSrcInc = 1;
  1464. --cAADone;
  1465. --pSD;
  1466. } else {
  1467. //
  1468. // The source just become valid now, need to
  1469. // PreMul all prev sources for this detination
  1470. // and save this pSD for done pixel
  1471. //
  1472. DBGP_IF(DBGP_BUILD,
  1473. DBGP("@@ FIRST SRC: PreMul=%ld - Mul (%ld)=%ld"
  1474. ARGDW(DI_MAX_NUM) ARGDW(Mul)
  1475. ARGDW(DI_MAX_NUM - Mul)));
  1476. pAAInfo->PreMul = (WORD)(DI_MAX_NUM - Mul);
  1477. --jDstBeg;
  1478. --jDstEnd;
  1479. ASSERTMSG("!!! Error: jDstBeg is WRONG",
  1480. (jDstBeg >= iDstBeg) &&
  1481. (jDstBeg <= iDstEnd));
  1482. }
  1483. } else {
  1484. //
  1485. // We are in the middle of compositions, so the
  1486. // source just become valid, notice that PreMul
  1487. // could be zero
  1488. //
  1489. DBGP_IF(DBGP_BUILD,
  1490. DBGP("@@ FIRST MIDDLE: PreMul=CurMul (%ld) - Mul (%ld)=%ld"
  1491. ARGDW(CurMul) ARGDW(Mul)
  1492. ARGDW(CurMul - Mul)));
  1493. pAAInfo->PreMul = (WORD)(CurMul - Mul);
  1494. }
  1495. } else {
  1496. jSrcEnd = IdxSrc;
  1497. jDstEnd = IdxDst;
  1498. }
  1499. } else if (jSrcBeg != -1) {
  1500. //
  1501. // Source got cut off early, so wrap it up now
  1502. //
  1503. DBGP_IF(DBGP_BUILD,
  1504. DBGP("@@ END SRC: Mul=%ld, CurMul=%ld"
  1505. ARGDW(Mul) ARGDW(CurMul)));
  1506. if (++pSD >= pSDEnd) {
  1507. DBGP("Error(2): cAAData Overrun of %ld, Fixed it"
  1508. ARGDW(++cAAData));
  1509. ASSERT(pSD < pSDEnd);
  1510. --pSD;
  1511. }
  1512. if (!(SDFlags & SDF_DONE)) {
  1513. Mul += (DI_MAX_NUM - CurMul);
  1514. }
  1515. pSD->Mul = (WORD)Mul | (SDFlags |= SDF_DONE);
  1516. cLoop = 0;
  1517. ++cAADone;
  1518. ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
  1519. }
  1520. } else if (jSrcBeg != -1) {
  1521. //
  1522. // we just pass the iDstEnd so this one MUST have SDF_DONE
  1523. // bit set and we need to save this one, if this one is not
  1524. // SDF_DONE then something is wrong
  1525. //
  1526. ASSERTMSG("End Dest but not SDF_DONE", SDFlags & SDF_DONE);
  1527. DBGP_IF(DBGP_BUILD,
  1528. DBGP("@@ PASS IdxDst: Mul=%ld, CurMul=%ld"
  1529. ARGDW(Mul) ARGDW(CurMul)));
  1530. if (++pSD >= pSDEnd) {
  1531. DBGP("Error(3): cAAData Overrun of %ld, Fixed it"
  1532. ARGDW(++cAAData));
  1533. ASSERT(pSD < pSDEnd);
  1534. --pSD;
  1535. }
  1536. jSrcEnd = IdxSrc;
  1537. Mul = DI_MAX_NUM - CurMul;
  1538. pSD->Mul = (WORD)Mul | (SDFlags = SDF_DONE);
  1539. cLoop = 0;
  1540. ++cAADone;
  1541. ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
  1542. }
  1543. #if DBG
  1544. if ((pSD >= (PSHRINKDATA)(pAAInfo->pAAData)) ||
  1545. (pAAInfo->PreSrcInc)) {
  1546. BOOL HasSD;
  1547. HasSD = (BOOL)(pSD >= (PSHRINKDATA)(pAAInfo->pAAData));
  1548. if (SDFlags & SDF_DONE) {
  1549. DBGP_IF(DBGP_BUILD2,
  1550. DBGP("%hscLoop=%5ld (%5ld/%5ld), iSrc=%5ld, Mul=%5ld [%5ld], Flags=0x%04lx%hs, Done Pixel"
  1551. ARGPTR((HasSD) ? "" : " >>")
  1552. ARGDW(cIn - cLoop - 1) ARGDW(IdxDst)
  1553. ARGDW(IdxDst - iDstBeg)
  1554. ARGDW(IdxSrc)
  1555. ARGDW((Mul) ? Mul :
  1556. ((SDFlags & SDF_LARGE_MUL) ?
  1557. MinPixel + 1 : MinPixel))
  1558. ARGDW(CurMul)
  1559. ARGDW(SDFlags)
  1560. ARGPTR((SDFlags & SDF_LARGE_MUL) ? ", Large Mul" : "")));
  1561. } else {
  1562. DBGP_IF(DBGP_BUILD2,
  1563. DBGP("%hscLoop=%5ld iSrc=%5ld, Mul=%5ld [%5ld], Flags=0x%04lx%hs"
  1564. ARGPTR((HasSD) ? "" : " >>")
  1565. ARGDW(cIn - cLoop - 1)
  1566. ARGDW(IdxSrc)
  1567. ARGDW((Mul) ? Mul : ((SDFlags & SDF_LARGE_MUL) ?
  1568. MinPixel + 1 : MinPixel))
  1569. ARGDW(CurMul)
  1570. ARGDW(SDFlags)
  1571. ARGPTR((SDFlags & SDF_LARGE_MUL) ? ", Large Mul" : "")));
  1572. }
  1573. }
  1574. #endif
  1575. ++IdxSrc;
  1576. }
  1577. //
  1578. // For the last one ZERO
  1579. //
  1580. ++pSD;
  1581. if ((jSrcBeg == -1) || (pSD == (PSHRINKDATA)(pAAInfo->pAAData))) {
  1582. HTFreeMem(pAAInfo);
  1583. return(NULL);
  1584. }
  1585. ++iDstBeg;
  1586. DBGP_IF(DBGP_BUILD,
  1587. DBGP("*** Final jDstBeg/End=%ld:%ld, REAL=(%ld:%ld)"
  1588. ARGDW(jDstBeg) ARGDW(jDstEnd) ARGDW(iDstBeg) ARGDW(iDstEnd)));
  1589. // Bug 27036: ensure jSrcEnd is less than iSrcEnd
  1590. if (jSrcEnd >= iSrcEnd)
  1591. {
  1592. jSrcEnd = iSrcEnd - 1;
  1593. }
  1594. if (jDstBeg < iDstBeg) {
  1595. ++(pAAInfo->cPreLoad);
  1596. jDstBeg = iDstBeg;
  1597. }
  1598. if (jDstEnd >= iDstEnd) {
  1599. jDstEnd = iDstEnd - 1;
  1600. }
  1601. if ((pAAInfo->PreSrcInc) && (pAAInfo->PreMul == 0)) {
  1602. pAAInfo->PreSrcInc = 0;
  1603. ++jSrcBeg;
  1604. }
  1605. #if 0
  1606. //
  1607. // 04-Aug-2000 Fri 15:31:03 updated -by- Daniel Chou (danielc)
  1608. // This assert does not applyed here when anti-aliasing will use
  1609. // surounding 3 pixels (L/T/R/B) if source available (when clipped
  1610. // source) but the Rep does not use suround pixels.
  1611. //
  1612. if (cbRep) {
  1613. ASSERT(jSrcBeg == pAAInfo->Mask.iBeg);
  1614. if (jSrcEnd != (pAAInfo->Mask.iBeg + pAAInfo->Mask.iSize - 1)) {
  1615. DBGP("jSrcEnd=%ld, Mask: iBeg=%ld, iSize=%ld"
  1616. ARGDW(jSrcEnd) ARGDW(pAAInfo->Mask.iBeg)
  1617. ARGDW(pAAInfo->Mask.iSize));
  1618. ASSERT(jSrcEnd == pAAInfo->Mask.iBeg + pAAInfo->Mask.iSize - 1);
  1619. }
  1620. }
  1621. #endif
  1622. pAAInfo->cAAData = (DWORD)(pSD - (PSHRINKDATA)(pAAInfo->pAAData));
  1623. pAAInfo->cAADone = cAADone;
  1624. pSD->Mul = 0;
  1625. } else {
  1626. ASSERT(cbRep);
  1627. // Bug 27036: ensure jSrcEnd is less than iSrcEnd
  1628. jSrcBeg = pAAInfo->Src.iSrcBeg;
  1629. jSrcEnd = pAAInfo->Src.iSrcEnd - 1;
  1630. jDstBeg = pAAInfo->Src.iDstBeg;
  1631. jDstEnd = pAAInfo->Src.iDstEnd - 1;
  1632. }
  1633. *piSrcBeg = jSrcBeg;
  1634. *piSrcEnd = jSrcEnd;
  1635. *piDstBeg = jDstBeg;
  1636. *piDstEnd = jDstEnd;
  1637. pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
  1638. pAAInfo->cOut = jDstEnd - jDstBeg + 1;
  1639. DBGP_IF(DBGP_BUILD,
  1640. DBGP("SRK(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, cAAData=%ld, cAADone=%ld, PreMul=%4ld, PresrcInc=%ld, cPreLoad=%ld"
  1641. ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
  1642. ARGDW(jSrcBeg) ARGDW(jSrcEnd) ARGDW(jDstBeg) ARGDW(jDstEnd)
  1643. ARGDW(pAAInfo->cAAData) ARGDW(cAADone) ARGDW(pAAInfo->PreMul)
  1644. ARGDW(pAAInfo->PreSrcInc) ARGDW(pAAInfo->cPreLoad)));
  1645. }
  1646. return(pAAInfo);
  1647. }
  1648. #if DBG
  1649. BOOL ExpExp = TRUE;
  1650. BOOL SrkSrk = TRUE;
  1651. #endif
  1652. LONG
  1653. HTENTRY
  1654. ComputeAABBP(
  1655. PBITBLTPARAMS pBBP,
  1656. PHTSURFACEINFO pDstSI,
  1657. PAABBP pAABBP,
  1658. BOOL GrayFunc
  1659. )
  1660. /*++
  1661. Routine Description:
  1662. Arguments:
  1663. Return Value:
  1664. Author:
  1665. 01-Apr-1998 Wed 20:32:36 created -by- Daniel Chou (danielc)
  1666. Revision History:
  1667. 05-Aug-1998 Wed 19:38:56 updated -by- Daniel Chou (danielc)
  1668. Fix banding problem
  1669. 10-Aug-1998 Mon 16:05:32 updated -by- Daniel Chou (danielc)
  1670. Fix rectangle banding with flip (X or Y) computation, the computation
  1671. is done first by flip the Destination rectangles (Orginal and final)
  1672. first by compute from right to left for flipping X, and bottom to
  1673. top for flipping Y, after computation for stretch, we flip all the
  1674. rectangles back
  1675. --*/
  1676. {
  1677. BITBLTPARAMS BBP;
  1678. RECTL rclSurf;
  1679. RECTL rclPhyDst;
  1680. LONG cxIn;
  1681. LONG cyIn;
  1682. LONG cxOut;
  1683. LONG cyOut;
  1684. LONG Tmp;
  1685. DWORD AAHFlags;
  1686. BBP = *pBBP;
  1687. AAHFlags = pAABBP->AAHFlags;
  1688. DBGP_IF(DBGP_AAHEADER,
  1689. DBGP(" Input: rclSrc=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1690. ARGDW(pBBP->rclSrc.left) ARGDW(pBBP->rclSrc.top)
  1691. ARGDW(pBBP->rclSrc.right) ARGDW(pBBP->rclSrc.bottom)
  1692. ARGDW(pBBP->rclSrc.right - pBBP->rclSrc.left)
  1693. ARGDW(pBBP->rclSrc.bottom - pBBP->rclSrc.top)));
  1694. DBGP_IF(DBGP_AAHEADER,
  1695. DBGP(" Input: rclDst=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1696. ARGDW(pBBP->rclDest.left) ARGDW(pBBP->rclDest.top)
  1697. ARGDW(pBBP->rclDest.right) ARGDW(pBBP->rclDest.bottom)
  1698. ARGDW(pBBP->rclDest.right - pBBP->rclDest.left)
  1699. ARGDW(pBBP->rclDest.bottom - pBBP->rclDest.top)));
  1700. if (BBP.Flags & BBPF_HAS_DEST_CLIPRECT) {
  1701. DBGP_IF(DBGP_AAHEADER,
  1702. DBGP(" Input: rclClip=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1703. ARGDW(pBBP->rclClip.left) ARGDW(pBBP->rclClip.top)
  1704. ARGDW(pBBP->rclClip.right) ARGDW(pBBP->rclClip.bottom)
  1705. ARGDW(pBBP->rclClip.right - pBBP->rclClip.left)
  1706. ARGDW(pBBP->rclClip.bottom - pBBP->rclClip.top)));
  1707. }
  1708. if (BBP.Flags & BBPF_HAS_BANDRECT) {
  1709. DBGP_IF(DBGP_AAHEADER,
  1710. DBGP(" Input: rclBand=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1711. ARGDW(pBBP->rclBand.left) ARGDW(pBBP->rclBand.top)
  1712. ARGDW(pBBP->rclBand.right) ARGDW(pBBP->rclBand.bottom)
  1713. ARGDW(pBBP->rclBand.right - pBBP->rclBand.left)
  1714. ARGDW(pBBP->rclBand.bottom - pBBP->rclBand.top)));
  1715. }
  1716. DBGP_IF(DBGP_AAHEADER,
  1717. DBGP("Input: ptlBrushOrg=(%6ld, %6ld)"
  1718. ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)));
  1719. DBGP_IF(DBGP_AAHEADER,
  1720. DBGP("Input: ptlSrcMask=(%6ld, %6ld)"
  1721. ARGDW(pBBP->ptlSrcMask.x) ARGDW(pBBP->ptlSrcMask.y)));
  1722. if (BBP.rclDest.right < BBP.rclDest.left) {
  1723. XCHG(BBP.rclDest.left, BBP.rclDest.right, Tmp);
  1724. AAHFlags |= AAHF_FLIP_X;
  1725. }
  1726. if (BBP.rclDest.bottom < BBP.rclDest.top) {
  1727. XCHG(BBP.rclDest.top, BBP.rclDest.bottom, Tmp);
  1728. AAHFlags |= AAHF_FLIP_Y;
  1729. }
  1730. //
  1731. // The source RECT is always well ordered
  1732. //
  1733. if (BBP.rclSrc.right < BBP.rclSrc.left) {
  1734. XCHG(BBP.rclSrc.left, BBP.rclSrc.right, Tmp);
  1735. AAHFlags ^= AAHF_FLIP_X;
  1736. }
  1737. if (BBP.rclSrc.bottom < BBP.rclSrc.top) {
  1738. XCHG(BBP.rclSrc.top, BBP.rclSrc.bottom, Tmp);
  1739. AAHFlags ^= AAHF_FLIP_Y;
  1740. }
  1741. if ((BBP.rclSrc.left >= BBP.rclSrc.right) ||
  1742. (BBP.rclSrc.top >= BBP.rclSrc.bottom)) {
  1743. DBGP_IF(DBGP_AAHEADER,
  1744. DBGP("EMPTY rclSrc: (%ld, %ld)-(%ld, %ld)=%ldx%ld"
  1745. ARGDW(BBP.rclSrc.left) ARGDW(BBP.rclSrc.top)
  1746. ARGDW(BBP.rclSrc.right) ARGDW(BBP.rclSrc.bottom)
  1747. ARGDW(BBP.rclSrc.right - BBP.rclSrc.left)
  1748. ARGDW(BBP.rclSrc.bottom - BBP.rclSrc.top)));
  1749. return(0);
  1750. }
  1751. if ((BBP.rclDest.left >= BBP.rclDest.right) ||
  1752. (BBP.rclDest.top >= BBP.rclDest.bottom)) {
  1753. DBGP_IF(DBGP_AAHEADER,
  1754. DBGP("EMPTY rclDest: (%ld, %ld)-(%ld, %ld)=%ldx%ld"
  1755. ARGDW(BBP.rclDest.left) ARGDW(BBP.rclDest.top)
  1756. ARGDW(BBP.rclDest.right) ARGDW(BBP.rclDest.bottom)
  1757. ARGDW(BBP.rclDest.right - BBP.rclDest.left)
  1758. ARGDW(BBP.rclDest.bottom - BBP.rclDest.top)));
  1759. return(0);
  1760. }
  1761. //
  1762. // set the cxIn, cyIn for no sign
  1763. //
  1764. cxIn = BBP.rclSrc.right - BBP.rclSrc.left;
  1765. cyIn = BBP.rclSrc.bottom - BBP.rclSrc.top;
  1766. cxOut = BBP.rclDest.right - BBP.rclDest.left;
  1767. cyOut = BBP.rclDest.bottom - BBP.rclDest.top;
  1768. pAABBP->ptlBrushOrg = BBP.ptlBrushOrg;
  1769. if (((((cxOut * 1000) + 500) / cxIn) > 667) &&
  1770. ((((cyOut * 1000) + 500) / cyIn) > 667)) {
  1771. AAHFlags |= AAHF_DO_FIXUPDIB;
  1772. }
  1773. if ((cxOut * cyOut) < (cxIn * cyIn)) {
  1774. AAHFlags |= AAHF_SHRINKING;
  1775. AAHFlags |= AAHF_DO_DST_CLR_MAPPING;
  1776. } else {
  1777. AAHFlags |= AAHF_DO_SRC_CLR_MAPPING;
  1778. }
  1779. if (cyIn == cyOut) {
  1780. pAABBP->AAMaskCYFunc = BltMask_CY;
  1781. pAABBP->GetAVCYFunc = BltAV_CY;
  1782. pAABBP->AABuildCYFunc = BuildBltAAInfo;
  1783. pAABBP->CYFuncMode = AACYMODE_BLT;
  1784. } else if (cyIn < cyOut) {
  1785. pAABBP->AAMaskCYFunc = ExpandMask_CY;
  1786. pAABBP->GetAVCYFunc = ExpandAV_CY;
  1787. pAABBP->AABuildCYFunc = BuildExpandAAInfo;
  1788. if (cxOut > cxIn) {
  1789. if ((!(AAHFlags & AAHF_BBPF_AA_OFF)) &&
  1790. ((cyIn * FAST_MAX_CY) >= cyOut) &&
  1791. ((cxIn * FAST_MAX_CX) >= cxOut)) {
  1792. AAHFlags |= AAHF_FAST_EXP_AA;
  1793. }
  1794. pAABBP->CYFuncMode = AACYMODE_EXPAND_EXPCX;
  1795. } else {
  1796. pAABBP->CYFuncMode = AACYMODE_EXPAND;
  1797. }
  1798. #if DBG
  1799. if (!ExpExp) {
  1800. pAABBP->CYFuncMode = AACYMODE_EXPAND;
  1801. }
  1802. #endif
  1803. } else {
  1804. pAABBP->AAMaskCYFunc = ShrinkMask_CY;
  1805. pAABBP->GetAVCYFunc = ShrinkAV_CY;
  1806. pAABBP->AABuildCYFunc = BuildShrinkAAInfo;
  1807. pAABBP->CYFuncMode = ((cxOut < cxIn) && (!GrayFunc)) ?
  1808. AACYMODE_SHRINK_SRKCX : AACYMODE_SHRINK;
  1809. #if DBG
  1810. if (!SrkSrk) {
  1811. pAABBP->CYFuncMode = AACYMODE_SHRINK;
  1812. }
  1813. #endif
  1814. }
  1815. DBGP_IF(DBGP_FUNC, DBGP("\n+++++ AACYFuncMode = %ld"
  1816. ARGDW(pAABBP->CYFuncMode)));
  1817. if (cxIn == cxOut) {
  1818. pAABBP->CXFuncMode = AACXMODE_BLT;
  1819. pAABBP->AAMaskCXFunc = BltMask_CX;
  1820. pAABBP->GetAVCXFunc = BltAV_CX;
  1821. pAABBP->AABuildCXFunc = BuildBltAAInfo;
  1822. pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayCopyDIB_CX :
  1823. (AACXFUNC)CopyDIB_CX;
  1824. DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = CopyDIB_CX()"));
  1825. } else if (cxIn < cxOut) {
  1826. pAABBP->CXFuncMode = AACXMODE_EXPAND;
  1827. pAABBP->AAMaskCXFunc = ExpandMask_CX;
  1828. pAABBP->GetAVCXFunc = ExpandAV_CX;
  1829. pAABBP->AABuildCXFunc = BuildExpandAAInfo;
  1830. pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayExpandDIB_CX :
  1831. (AACXFUNC)ExpandDIB_CX;
  1832. DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = ExpandDIB_CX()"));
  1833. } else {
  1834. pAABBP->CXFuncMode = AACXMODE_SHRINK;
  1835. pAABBP->AAMaskCXFunc = ShrinkMask_CX;
  1836. AAHFlags |= AAHF_OR_AV;
  1837. pAABBP->GetAVCXFunc = ShrinkAV_CX;
  1838. pAABBP->AABuildCXFunc = BuildShrinkAAInfo;
  1839. pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayShrinkDIB_CX :
  1840. (AACXFUNC)ShrinkDIB_CX;
  1841. DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = ShrinkDIB_CX()"));
  1842. }
  1843. if (BBP.Flags & BBPF_TILE_SRC) {
  1844. pAABBP->CYFuncMode = AACYMODE_TILE;
  1845. pAABBP->AAMaskCXFunc = BltMask_CX;
  1846. pAABBP->AAMaskCYFunc = BltMask_CY;
  1847. pAABBP->GetAVCXFunc = NULL;
  1848. pAABBP->GetAVCYFunc = TileAV_CY;
  1849. pAABBP->AABuildCYFunc =
  1850. pAABBP->AABuildCXFunc = BuildTileAAInfo;
  1851. pAABBP->AACXFunc = NULL;
  1852. DBGP_IF(DBGP_FUNC, DBGP("+++ TILE: TileBlt_CY(), AACXFunc = NULL"));
  1853. }
  1854. pAABBP->AAHFlags = AAHFlags;
  1855. pAABBP->rclSrc = BBP.rclSrc;
  1856. pAABBP->ptlMask.x = BBP.ptlSrcMask.x - BBP.rclSrc.left;
  1857. pAABBP->ptlMask.y = BBP.ptlSrcMask.y - BBP.rclSrc.top;
  1858. rclSurf = BBP.rclDest;
  1859. if (BBP.Flags & BBPF_HAS_DEST_CLIPRECT) {
  1860. if (!IntersectRECTL(&rclSurf, &BBP.rclClip)) {
  1861. DBGP_IF(DBGP_AAHEADER,
  1862. DBGP("rclClip=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
  1863. ARGDW(BBP.rclClip.left) ARGDW(BBP.rclClip.top)
  1864. ARGDW(BBP.rclClip.right) ARGDW(BBP.rclClip.bottom)
  1865. ARGDW(BBP.rclClip.right - BBP.rclClip.left)
  1866. ARGDW(BBP.rclClip.bottom - BBP.rclClip.top)
  1867. ARGDW(rclSurf.left) ARGDW(rclSurf.top)
  1868. ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
  1869. ARGDW(rclSurf.right - rclSurf.left)
  1870. ARGDW(rclSurf.bottom - rclSurf.top)));
  1871. return(0);
  1872. }
  1873. }
  1874. if (BBP.Flags & BBPF_HAS_BANDRECT) {
  1875. ASSERT(BBP.rclBand.left >= 0);
  1876. ASSERT(BBP.rclBand.top >= 0);
  1877. ASSERT(BBP.rclBand.right > BBP.rclBand.left);
  1878. ASSERT(BBP.rclBand.bottom > BBP.rclBand.top);
  1879. if (!IntersectRECTL(&rclSurf, &BBP.rclBand)) {
  1880. DBGP_IF(DBGP_AAHEADER,
  1881. DBGP("rclBand=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
  1882. ARGDW(BBP.rclBand.left) ARGDW(BBP.rclBand.top)
  1883. ARGDW(BBP.rclBand.right) ARGDW(BBP.rclBand.bottom)
  1884. ARGDW(BBP.rclBand.right - BBP.rclBand.left)
  1885. ARGDW(BBP.rclBand.bottom - BBP.rclBand.top)
  1886. ARGDW(rclSurf.left) ARGDW(rclSurf.top)
  1887. ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
  1888. ARGDW(rclSurf.right - rclSurf.left)
  1889. ARGDW(rclSurf.bottom - rclSurf.top)));
  1890. return(0);
  1891. }
  1892. //
  1893. // 05-Aug-1998 Wed 19:38:56 updated -by- Daniel Chou (danielc)
  1894. // Fixed the banding problem when mirrored or upside down stretch
  1895. // The fixes is simple by offset all the Dest rects for the left/top
  1896. // of the band, and reset the cx/cy destination size according to the
  1897. // band size and then offset the brush origin according the the band's
  1898. // left/top position, after these all other codes should run the same
  1899. // excpet we do not need to check BBPF_HAS_BANDRECT at later time.
  1900. //
  1901. BBP.rclDest.left -= BBP.rclBand.left;
  1902. BBP.rclDest.right -= BBP.rclBand.left;
  1903. BBP.rclDest.top -= BBP.rclBand.top;
  1904. BBP.rclDest.bottom -= BBP.rclBand.top;
  1905. rclSurf.left -= BBP.rclBand.left;
  1906. rclSurf.right -= BBP.rclBand.left;
  1907. rclSurf.top -= BBP.rclBand.top;
  1908. rclSurf.bottom -= BBP.rclBand.top;
  1909. pAABBP->ptlBrushOrg.x -= BBP.rclBand.left;
  1910. pAABBP->ptlBrushOrg.y -= BBP.rclBand.top;
  1911. ASSERT((BBP.rclBand.right - BBP.rclBand.left) <= pDstSI->Width);
  1912. ASSERT((BBP.rclBand.bottom - BBP.rclBand.top) <= pDstSI->Height);
  1913. DBGP_IF(DBGP_AAHEADER,
  1914. DBGP("BAND Output: Dest: %ld x %ld --> BAND: %ld x %ld"
  1915. ARGDW(pDstSI->Width) ARGDW(pDstSI->Height)
  1916. ARGDW(BBP.rclBand.right - BBP.rclBand.left)
  1917. ARGDW(BBP.rclBand.bottom - BBP.rclBand.top)));
  1918. }
  1919. rclPhyDst.left =
  1920. rclPhyDst.top = 0;
  1921. rclPhyDst.right = pDstSI->Width;
  1922. rclPhyDst.bottom = pDstSI->Height;
  1923. if (!IntersectRECTL(&rclSurf, &rclPhyDst)) {
  1924. DBGP_IF(DBGP_AAHEADER,
  1925. DBGP("PhyDest=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
  1926. ARGDW(rclPhyDst.left) ARGDW(rclPhyDst.top)
  1927. ARGDW(rclPhyDst.right) ARGDW(rclPhyDst.bottom)
  1928. ARGDW(rclPhyDst.right - rclPhyDst.left)
  1929. ARGDW(rclPhyDst.bottom - rclPhyDst.top)
  1930. ARGDW(rclSurf.left) ARGDW(rclSurf.top)
  1931. ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
  1932. ARGDW(rclSurf.right - rclSurf.left)
  1933. ARGDW(rclSurf.bottom - rclSurf.top)));
  1934. return(0);
  1935. }
  1936. //
  1937. // 10-Aug-1998 Mon 16:09:13 updated -by- Daniel Chou (danielc)
  1938. // flipping X computation: When we flip in X direction, we will first
  1939. // compute the destination original rectangle and final destination
  1940. // rectangle by compute its offset from right hand side so later at
  1941. // stretch computation is easier, after finished stretch computation
  1942. // (BuildExpand or BuildShrink) we will flip the rectangle back by
  1943. // substract it from ptlFlip.x.
  1944. //
  1945. if (AAHFlags & AAHF_FLIP_X) {
  1946. DBGP_IF(DBGP_AAHEADER,
  1947. DBGP("*** FLIP X: rclDstOrg=(%6ld - %6ld)=%6ld"
  1948. ARGDW(BBP.rclDest.left) ARGDW(BBP.rclDest.right)
  1949. ARGDW(BBP.rclDest.right - BBP.rclDest.left)));
  1950. DBGP_IF(DBGP_AAHEADER,
  1951. DBGP("*** FLIP X: rclDst=(%6ld - %6ld)=%6ld, ptlFlip.x=%ld"
  1952. ARGDW(rclSurf.left) ARGDW(rclSurf.right)
  1953. ARGDW(rclSurf.right - rclSurf.left)
  1954. ARGDW(BBP.rclDest.right)));
  1955. Tmp = rclSurf.right - rclSurf.left;
  1956. rclSurf.left = BBP.rclDest.right - rclSurf.right;
  1957. rclSurf.right = rclSurf.left + Tmp;
  1958. pAABBP->ptlFlip.x = BBP.rclDest.right;
  1959. BBP.rclDest.right -= BBP.rclDest.left;
  1960. BBP.rclDest.left = 0;
  1961. }
  1962. //
  1963. // 10-Aug-1998 Mon 16:09:13 updated -by- Daniel Chou (danielc)
  1964. // flipping Y computation: When we flip in Y direction, we will first
  1965. // compute the destination original rectangle and final destination
  1966. // rectangle by compute its offset from bottom hand side so later at
  1967. // stretch computation is easier, after finished stretch computation
  1968. // (BuildExpand or BuildShrink) we will flip the rectangle back by
  1969. // substract it from ptlFlip.y.
  1970. //
  1971. if (AAHFlags & AAHF_FLIP_Y) {
  1972. DBGP_IF(DBGP_AAHEADER,
  1973. DBGP("*** FLIP Y: rclDstOrg=(%6ld - %6ld)=%6ld"
  1974. ARGDW(BBP.rclDest.top) ARGDW(BBP.rclDest.bottom)
  1975. ARGDW(BBP.rclDest.bottom - BBP.rclDest.top)));
  1976. DBGP_IF(DBGP_AAHEADER,
  1977. DBGP("*** FLIP Y: rclDst=(%6ld - %6ld)=%6ld, ptlFlip.y=%ld"
  1978. ARGDW(rclSurf.top) ARGDW(rclSurf.bottom)
  1979. ARGDW(rclSurf.bottom - rclSurf.top)
  1980. ARGDW(BBP.rclDest.bottom)));
  1981. Tmp = rclSurf.bottom - rclSurf.top;
  1982. rclSurf.top = BBP.rclDest.bottom - rclSurf.bottom;
  1983. rclSurf.bottom = rclSurf.top + Tmp;
  1984. pAABBP->ptlFlip.y = BBP.rclDest.bottom;
  1985. BBP.rclDest.bottom -= BBP.rclDest.top;
  1986. BBP.rclDest.top = 0;
  1987. }
  1988. pAABBP->rclDstOrg = BBP.rclDest;
  1989. pAABBP->rclDst = rclSurf;
  1990. DBGP_IF(DBGP_AAHEADER,
  1991. DBGP("Output: rclSrc=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1992. ARGDW(pAABBP->rclSrc.left) ARGDW(pAABBP->rclSrc.top)
  1993. ARGDW(pAABBP->rclSrc.right) ARGDW(pAABBP->rclSrc.bottom)
  1994. ARGDW(pAABBP->rclSrc.right - pAABBP->rclSrc.left)
  1995. ARGDW(pAABBP->rclSrc.bottom - pAABBP->rclSrc.top)));
  1996. DBGP_IF(DBGP_AAHEADER,
  1997. DBGP("Output: rclDstOrg=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  1998. ARGDW(pAABBP->rclDstOrg.left) ARGDW(pAABBP->rclDstOrg.top)
  1999. ARGDW(pAABBP->rclDstOrg.right) ARGDW(pAABBP->rclDstOrg.bottom)
  2000. ARGDW(pAABBP->rclDstOrg.right - pAABBP->rclDstOrg.left)
  2001. ARGDW(pAABBP->rclDstOrg.bottom - pAABBP->rclDstOrg.top)));
  2002. DBGP_IF(DBGP_AAHEADER,
  2003. DBGP("Output: rclDst=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
  2004. ARGDW(pAABBP->rclDst.left) ARGDW(pAABBP->rclDst.top)
  2005. ARGDW(pAABBP->rclDst.right) ARGDW(pAABBP->rclDst.bottom)
  2006. ARGDW(pAABBP->rclDst.right - pAABBP->rclDst.left)
  2007. ARGDW(pAABBP->rclDst.bottom - pAABBP->rclDst.top)));
  2008. DBGP_IF(DBGP_AAHEADER,
  2009. DBGP("Output: ptlBrushOrg=(%6ld, %6ld)"
  2010. ARGDW(pAABBP->ptlBrushOrg.x) ARGDW(pAABBP->ptlBrushOrg.y)));
  2011. DBGP_IF(DBGP_AAHEADER,
  2012. DBGP("Output: ptlSrcMask=(%6ld, %6ld)"
  2013. ARGDW(pAABBP->ptlMask.x) ARGDW(pAABBP->ptlMask.y)));
  2014. return(1);
  2015. }
  2016. #if DBG
  2017. extern INT cCXMask;
  2018. LPSTR
  2019. GetAACXFuncName(
  2020. AACXFUNC AACXFunc
  2021. )
  2022. /*++
  2023. Routine Description:
  2024. Arguments:
  2025. Return Value:
  2026. Author:
  2027. 06-Jan-1999 Wed 19:11:27 created -by- Daniel Chou (danielc)
  2028. Revision History:
  2029. --*/
  2030. {
  2031. if (AACXFunc == (AACXFUNC)RepDIB_CX) {
  2032. return("RepDIB_CX");
  2033. } else if (AACXFunc == (AACXFUNC)SkipDIB_CX) {
  2034. return("SkipDIB_CX");
  2035. } else if (AACXFunc == (AACXFUNC)CopyDIB_CX) {
  2036. return("CopyDIB_CX");
  2037. } else if (AACXFunc == (AACXFUNC)ShrinkDIB_CX) {
  2038. return("ShrinkDIB_CX");
  2039. } else if (AACXFunc == (AACXFUNC)ExpandDIB_CX) {
  2040. return("ExpandDIB_CX");
  2041. } else if (AACXFunc == (AACXFUNC)GrayRepDIB_CX) {
  2042. return("GrayRepDIB_CX");
  2043. } else if (AACXFunc == (AACXFUNC)GraySkipDIB_CX) {
  2044. return("GraySkipDIB_CX");
  2045. } else if (AACXFunc == (AACXFUNC)GrayCopyDIB_CXGray) {
  2046. return("GrayCopyDIB_CXGray");
  2047. } else if (AACXFunc == (AACXFUNC)GrayCopyDIB_CX) {
  2048. return("GrayCopyDIB_CX");
  2049. } else if (AACXFunc == (AACXFUNC)GrayExpandDIB_CX) {
  2050. return("GrayExpandDIB_CX");
  2051. } else if (AACXFunc == (AACXFUNC)GrayShrinkDIB_CX) {
  2052. return("GrayShrinkDIB_CX");
  2053. } else {
  2054. DBGP("ERROR: Unknown AACXFUNC=%p, Function" ARGPTR(AACXFunc));
  2055. return("Unknown AACXFUNC");
  2056. }
  2057. }
  2058. LPSTR
  2059. GetAACYFuncName(
  2060. AACYFUNC AACYFunc
  2061. )
  2062. /*++
  2063. Routine Description:
  2064. Arguments:
  2065. Return Value:
  2066. Author:
  2067. 06-Jan-1999 Wed 19:11:27 created -by- Daniel Chou (danielc)
  2068. Revision History:
  2069. --*/
  2070. {
  2071. if (AACYFunc == (AACYFUNC)TileDIB_CY) {
  2072. return("TileDIB_CY");
  2073. } else if (AACYFunc == (AACYFUNC)RepDIB_CY) {
  2074. return("RepDIB_CY");
  2075. } else if (AACYFunc == (AACYFUNC)FastExpAA_CY) {
  2076. return("FastExpAA_CY");
  2077. } else if (AACYFunc == (AACYFUNC)SkipDIB_CY) {
  2078. return("SkipDIB_CY");
  2079. } else if (AACYFunc == (AACYFUNC)BltDIB_CY) {
  2080. return("BltDIB_CY");
  2081. } else if (AACYFunc == (AACYFUNC)ShrinkDIB_CY) {
  2082. return("ShrinkDIB_CY");
  2083. } else if (AACYFunc == (AACYFUNC)ShrinkDIB_CY_SrkCX) {
  2084. return("ShrinkDIB_CY_SrkCX");
  2085. } else if (AACYFunc == (AACYFUNC)ExpandDIB_CY_ExpCX) {
  2086. return("ExpandDIB_CY_ExpCX");
  2087. } else if (AACYFunc == (AACYFUNC)ExpandDIB_CY) {
  2088. return("ExpandDIB_CY");
  2089. } else if (AACYFunc == (AACYFUNC)GrayExpandDIB_CY_ExpCX) {
  2090. return("GrayExpandDIB_CY_ExpCX");
  2091. } else if (AACYFunc == (AACYFUNC)GrayExpandDIB_CY) {
  2092. return("GrayExpandDIB_CY");
  2093. } else if (AACYFunc == (AACYFUNC)GrayShrinkDIB_CY) {
  2094. return("GrayShrinkDIB_CY");
  2095. } else {
  2096. DBGP("ERROR: Unknown AACYFUNC=%p, Function" ARGPTR(AACYFunc));
  2097. return("Unknown AACYFUNC");
  2098. }
  2099. }
  2100. #endif
  2101. LONG
  2102. HTENTRY
  2103. SetupAAHeader(
  2104. PHALFTONERENDER pHR,
  2105. PDEVICECOLORINFO pDCI,
  2106. PAAHEADER pAAHdr,
  2107. AACYFUNC *pAACYFunc
  2108. )
  2109. /*++
  2110. Routine Description:
  2111. Arguments:
  2112. Return Value:
  2113. Author:
  2114. 03-Apr-1998 Fri 04:27:16 created -by- Daniel Chou (danielc)
  2115. Revision History:
  2116. 07-Aug-1998 Fri 19:28:21 updated -by- Daniel Chou (danielc)
  2117. Fix the mirror/upside-down banding problems, the problem is when we
  2118. flip the destination original size rectangle we did not flip the
  2119. the real destination rectangle, this cause the the offset getting too
  2120. big and its pointer offset passed the end of the bitmap, it also
  2121. has problem that when we did not flip the destination rectangle
  2122. the wrong portion of the bitmap will be in the band.
  2123. --*/
  2124. {
  2125. PAAINFO pAAInfoCX;
  2126. PAAINFO pAAInfoCY;
  2127. PBITBLTPARAMS pBBP;
  2128. PHTSURFACEINFO pSrcSI;
  2129. PHTSURFACEINFO pDstSI;
  2130. PHTSURFACEINFO pMaskSI;
  2131. LPBYTE pbExtra;
  2132. AACYFUNC AACYFunc;
  2133. AABBP aabbp;
  2134. LONG iFree;
  2135. LONG cbFreeBuf;
  2136. LONG Top;
  2137. LONG Bottom;
  2138. LONG cyNext;
  2139. LONG cxSize;
  2140. LONG cbMaskSrc;
  2141. LONG cIn;
  2142. LONG cOut;
  2143. LONG cbCYExtra;
  2144. LONG cbCXExtra;
  2145. LONG cbInBuf;
  2146. LONG cbFUDI;
  2147. LONG cbVGA256Xlate;
  2148. LONG cbOutBuf;
  2149. LONG cbAlphaBuf;
  2150. LONG cbIdxBGR;
  2151. LONG Result;
  2152. LONG cbSrcPel;
  2153. DWORD PrimAdjFlags;
  2154. UINT DstSurfFmt;
  2155. pBBP = pHR->pBitbltParams;
  2156. pSrcSI = pHR->pSrcSI;
  2157. pDstSI = pHR->pDestSI;
  2158. pMaskSI = pHR->pSrcMaskSI;
  2159. DstSurfFmt = (UINT)pDstSI->SurfaceFormat;
  2160. PrimAdjFlags = (DWORD)pHR->pDevClrAdj->PrimAdj.Flags;
  2161. cbSrcPel = (pHR->pDevClrAdj->DMI.Flags & DMIF_GRAY) ? sizeof(BYTE) :
  2162. sizeof(BGR8);
  2163. DBGP_IF(DBGP_AAHEADER,
  2164. DBGP("\nSrcSI=%ld x %ld [Format=%ld], DestSI=%ld x %ld [Format=%ld]"
  2165. ARGDW(pSrcSI->Width) ARGDW(pSrcSI->Height)
  2166. ARGDW(pSrcSI->SurfaceFormat)
  2167. ARGDW(pDstSI->Width) ARGDW(pDstSI->Height)
  2168. ARGDW(pDstSI->SurfaceFormat)));
  2169. aabbp.AAHFlags = (PrimAdjFlags & DCA_BBPF_AA_OFF) ? AAHF_BBPF_AA_OFF : 0;
  2170. if (pBBP->Flags & BBPF_TILE_SRC) {
  2171. aabbp.AAHFlags |= AAHF_TILE_SRC;
  2172. aabbp.AAHFlags |= AAHF_BBPF_AA_OFF;
  2173. }
  2174. if (ComputeAABBP(pBBP, pDstSI, &aabbp, cbSrcPel == sizeof(BYTE)) <= 0) {
  2175. return(0);
  2176. }
  2177. cbCXExtra = sizeof(RGBLUTAA);
  2178. if (PrimAdjFlags & DCA_ALPHA_BLEND) {
  2179. aabbp.AAHFlags |= AAHF_ALPHA_BLEND;
  2180. if (PrimAdjFlags & DCA_CONST_ALPHA) {
  2181. aabbp.AAHFlags |= AAHF_CONST_ALPHA;
  2182. cbCXExtra += (AB_BGR_CA_SIZE + AB_CONST_SIZE);
  2183. } else {
  2184. if (PrimAdjFlags & DCA_AB_PREMUL_SRC) {
  2185. //
  2186. // Set the flag so we will try to compute premul's orginal src
  2187. //
  2188. pAAHdr->SrcSurfInfo.Flags |= AASIF_AB_PREMUL_SRC;
  2189. }
  2190. if (PrimAdjFlags & DCA_AB_DEST) {
  2191. aabbp.AAHFlags |= AAHF_AB_DEST;
  2192. }
  2193. cbCXExtra += AB_BGR_SIZE;
  2194. }
  2195. }
  2196. if (PrimAdjFlags & DCA_NO_MAPPING_TABLE) {
  2197. aabbp.AAHFlags &= ~AAHF_DO_CLR_MAPPING;
  2198. }
  2199. ALIGN_MEM(cbCXExtra, cbCXExtra);
  2200. DBGP_IF(DBGP_LUT_MAP,
  2201. DBGP("CXExtra=%ld (RGBLUTAA) + 0 (Mapping=%hs) = %ld"
  2202. ARGDW(sizeof(RGBLUTAA))
  2203. ARGPTR((aabbp.AAHFlags & AAHF_DO_SRC_CLR_MAPPING) ?
  2204. "SRC" : "DST")
  2205. ARGDW(sizeof(RGBLUTAA) + 0)));
  2206. //
  2207. // This flag is set when reading the source bitmap, so the pointer will
  2208. // advanced to next scanline, this flag will not set for the destiantion
  2209. // since when blending and we reading from destination, we do not want to
  2210. // advanced the destination pointer because it will be done during output
  2211. //
  2212. ComputeInputColorInfo((LPBYTE)pSrcSI->pColorTriad->pColorTable,
  2213. (UINT)pSrcSI->pColorTriad->BytesPerEntry,
  2214. (UINT)pSrcSI->pColorTriad->PrimaryOrder,
  2215. &(pHR->BFInfo),
  2216. &(pAAHdr->SrcSurfInfo));
  2217. pAAHdr->SrcSurfInfo.Flags |= AASIF_INC_PB |
  2218. ((cbSrcPel == sizeof(BYTE)) ? AASIF_GRAY : 0);
  2219. if (PrimAdjFlags & DCA_USE_ADDITIVE_PRIMS) {
  2220. aabbp.AAHFlags |= AAHF_ADDITIVE;
  2221. }
  2222. if (pBBP->Flags & BBPF_TILE_SRC) {
  2223. aabbp.AAHFlags &= ~AAHF_DO_FIXUPDIB;
  2224. }
  2225. if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
  2226. aabbp.AAHFlags &= ~AAHF_DO_FIXUPDIB;
  2227. }
  2228. if (aabbp.AAHFlags & AAHF_DO_FIXUPDIB) {
  2229. CheckBMPNeedFixup(pDCI, pAAHdr, pSrcSI, &aabbp);
  2230. if (aabbp.AAHFlags & AAHF_SHRINKING) {
  2231. if (PrimAdjFlags & DCA_BBPF_AA_OFF) {
  2232. aabbp.AAHFlags |= AAHF_BBPF_AA_OFF;
  2233. } else {
  2234. aabbp.AAHFlags &= ~AAHF_BBPF_AA_OFF;
  2235. }
  2236. }
  2237. }
  2238. if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
  2239. aabbp.AAHFlags &= ~AAHF_FAST_EXP_AA;
  2240. }
  2241. if (pMaskSI) {
  2242. aabbp.AAHFlags |= AAHF_HAS_MASK;
  2243. }
  2244. if (!(pAAInfoCX = aabbp.AABuildCXFunc(pDCI,
  2245. aabbp.AAHFlags,
  2246. &aabbp.rclSrc.left,
  2247. &aabbp.rclSrc.right,
  2248. pSrcSI->Width,
  2249. aabbp.rclDstOrg.left,
  2250. aabbp.rclDstOrg.right,
  2251. &aabbp.rclDst.left,
  2252. &aabbp.rclDst.right,
  2253. cbCXExtra))) {
  2254. //
  2255. // Remove cbCXExtra (use pDCI's rgbLUT and BGRMapTable, AlphaBlendBGR)
  2256. //
  2257. if (!(pAAInfoCX = aabbp.AABuildCXFunc(pDCI,
  2258. aabbp.AAHFlags,
  2259. &aabbp.rclSrc.left,
  2260. &aabbp.rclSrc.right,
  2261. pSrcSI->Width,
  2262. aabbp.rclDstOrg.left,
  2263. aabbp.rclDstOrg.right,
  2264. &aabbp.rclDst.left,
  2265. &aabbp.rclDst.right,
  2266. cbCXExtra = 0))) {
  2267. return(HTERR_INSUFFICIENT_MEMORY);
  2268. }
  2269. }
  2270. // Bug 27036: reject empty rectangles
  2271. if(!pAAInfoCX->cIn || !pAAInfoCX->cOut)
  2272. {
  2273. #if 0
  2274. LONG crash = 1 ; // empty src or dest rectangle!
  2275. crash /= (pAAInfoCX->cIn * pAAInfoCX->cOut); // delete when debugging is complete.
  2276. if(crash)
  2277. return 0 ;
  2278. #endif
  2279. HTFreeMem(pAAInfoCX);
  2280. return 0 ;
  2281. }
  2282. if (cbCXExtra) {
  2283. pAAHdr->prgbLUT = (PRGBLUTAA)(pbExtra = pAAInfoCX->pbExtra);
  2284. pbExtra += sizeof(RGBLUTAA);
  2285. ASSERT_MEM_ALIGN(pAAHdr->prgbLUT, sizeof(LONG));
  2286. if (aabbp.AAHFlags & AAHF_ALPHA_BLEND) {
  2287. pAAHdr->pAlphaBlendBGR = (LPBYTE)pbExtra;
  2288. if (PrimAdjFlags & DCA_CONST_ALPHA) {
  2289. pbExtra += (AB_BGR_CA_SIZE + AB_CONST_SIZE);
  2290. } else {
  2291. pbExtra += AB_BGR_SIZE;
  2292. }
  2293. }
  2294. } else {
  2295. ASSERT_MEM_ALIGN(&pDCI->rgbLUT, sizeof(LONG));
  2296. aabbp.AAHFlags |= AAHF_USE_DCI_DATA;
  2297. pAAHdr->prgbLUT = &pDCI->rgbLUT;
  2298. if (aabbp.AAHFlags & AAHF_ALPHA_BLEND) {
  2299. pAAHdr->pAlphaBlendBGR = pDCI->pAlphaBlendBGR;
  2300. if (PrimAdjFlags & DCA_CONST_ALPHA) {
  2301. pAAHdr->pAlphaBlendBGR += AB_BGR_SIZE;
  2302. }
  2303. }
  2304. }
  2305. pAAHdr->pIdxBGR = pAAHdr->prgbLUT->IdxBGR;
  2306. if (aabbp.AAHFlags & AAHF_FLIP_X) {
  2307. DBGP_IF(DBGP_AAHEADER,
  2308. DBGP("X Dst=(%ld - %ld)=%ld change it to (%ld - %ld), ptlFlip.x=%ld"
  2309. ARGDW(aabbp.rclDst.left) ARGDW(aabbp.rclDst.right)
  2310. ARGDW(aabbp.rclDst.right - aabbp.rclDst.left)
  2311. ARGDW(aabbp.ptlFlip.x - aabbp.rclDst.left - 1)
  2312. ARGDW(aabbp.ptlFlip.x - aabbp.rclDst.right - 1)
  2313. ARGDW(aabbp.ptlFlip.x)));
  2314. aabbp.rclDst.left = aabbp.ptlFlip.x - aabbp.rclDst.left - 1;
  2315. aabbp.rclDst.right = aabbp.ptlFlip.x - aabbp.rclDst.right - 1;
  2316. }
  2317. //
  2318. // cbCYExtra is for the input scan line, add one because we want to
  2319. // run it in DWORD mode so we need at least an extra byte at end
  2320. // of input buffer
  2321. //
  2322. cIn = pAAInfoCX->cIn;
  2323. cOut = pAAInfoCX->cOut;
  2324. cbInBuf = cIn + 6; // left extra=3, right extra=3
  2325. cbFreeBuf =
  2326. cbCYExtra = 0;
  2327. AACYFunc = NULL;
  2328. if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
  2329. switch (aabbp.CYFuncMode) {
  2330. case AACYMODE_SHRINK:
  2331. case AACYMODE_SHRINK_SRKCX:
  2332. AACYFunc = (AACYFUNC)SkipDIB_CY;
  2333. break;
  2334. case AACYMODE_EXPAND:
  2335. case AACYMODE_EXPAND_EXPCX:
  2336. cbCYExtra = (aabbp.AAHFlags & AAHF_ALPHA_BLEND) ?
  2337. (sizeof(BGR8) * (cOut + 6)) : 0;
  2338. AACYFunc = (AACYFUNC)RepDIB_CY;
  2339. break;
  2340. case AACYMODE_BLT:
  2341. AACYFunc = (AACYFUNC)BltDIB_CY;
  2342. break;
  2343. }
  2344. if (AACYFunc) {
  2345. switch (aabbp.CXFuncMode) {
  2346. case AACXMODE_BLT:
  2347. aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
  2348. (AACXFUNC)GrayCopyDIB_CXGray :
  2349. (AACXFUNC)CopyDIB_CX;
  2350. break;
  2351. case AACXMODE_SHRINK:
  2352. aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
  2353. (AACXFUNC)GraySkipDIB_CX :
  2354. (AACXFUNC)SkipDIB_CX;
  2355. break;
  2356. case AACXMODE_EXPAND:
  2357. aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
  2358. (AACXFUNC)GrayRepDIB_CX :
  2359. (AACXFUNC)RepDIB_CX;
  2360. break;
  2361. }
  2362. aabbp.CYFuncMode = AACYMODE_NONE;
  2363. }
  2364. }
  2365. switch (aabbp.CYFuncMode) {
  2366. case AACYMODE_TILE:
  2367. AACYFunc = TileDIB_CY;
  2368. cbCYExtra = (cbSrcPel == sizeof(BYTE)) ? (cIn * sizeof(WORD)) : 0;
  2369. break;
  2370. case AACYMODE_BLT:
  2371. AACYFunc = (AACYFUNC)BltDIB_CY;
  2372. break;
  2373. case AACYMODE_SHRINK:
  2374. //
  2375. // We need to make sure Off555Buf does not changed
  2376. //
  2377. cbFreeBuf = (sizeof(LONG) * 256 * 2);
  2378. if (cbSrcPel == sizeof(BYTE)) {
  2379. AACYFunc = GrayShrinkDIB_CY;
  2380. cbCYExtra = (sizeof(LONG) * cOut * 3) + cbFreeBuf +
  2381. ((cOut + 6) * cbSrcPel);
  2382. } else {
  2383. AACYFunc = ShrinkDIB_CY;
  2384. cbCYExtra = (sizeof(RGBL) * cIn * 3) + cbFreeBuf +
  2385. (cbInBuf * cbSrcPel);
  2386. }
  2387. break;
  2388. case AACYMODE_SHRINK_SRKCX:
  2389. AACYFunc = ShrinkDIB_CY_SrkCX;
  2390. cbFreeBuf = (sizeof(LONG) * 256 * 2);
  2391. cbCYExtra = (sizeof(RGBL) * (pAAInfoCX->cAADone + 2) * 3) + cbFreeBuf;
  2392. break;
  2393. case AACYMODE_EXPAND:
  2394. AACYFunc = (cbSrcPel == sizeof(BYTE)) ? GrayExpandDIB_CY :
  2395. ExpandDIB_CY;
  2396. cbCYExtra = (cbFreeBuf = (sizeof(LONG) * 256 * 4)) +
  2397. ((cOut + 6) * cbSrcPel * 6);
  2398. break;
  2399. case AACYMODE_EXPAND_EXPCX:
  2400. //
  2401. // This function use IputBufBeg to sharpening the input scanline so we
  2402. // need 4 extra BGR8 for running the expand pre-read
  2403. //
  2404. if (aabbp.AAHFlags & AAHF_FAST_EXP_AA) {
  2405. DBGP_IF(DBGP_AAHEADER, DBGP("Use FastExpAA_CY functions"));
  2406. cbCYExtra = (cbInBuf * 5 * cbSrcPel);
  2407. AACYFunc = (AACYFUNC)FastExpAA_CY;
  2408. } else {
  2409. AACYFunc = (cbSrcPel == sizeof(BYTE)) ? GrayExpandDIB_CY_ExpCX :
  2410. ExpandDIB_CY_ExpCX;
  2411. cbCYExtra = (cbFreeBuf = (sizeof(LONG) * 256 * 4)) +
  2412. (cbInBuf * cbSrcPel * 3) + ((cOut + 6) * cbSrcPel * 4);
  2413. }
  2414. break;
  2415. }
  2416. cbAlphaBuf = (aabbp.AAHFlags & AAHF_ALPHA_BLEND) ? cOut : 0;
  2417. pAAHdr->DstSurfInfo.Flags = (cbSrcPel == sizeof(BYTE)) ? AASIF_GRAY : 0;
  2418. pAAHdr->DstSurfInfo.cbCX = cbAlphaBuf * cbSrcPel;
  2419. ALIGN_MEM(cbAlphaBuf, (cbAlphaBuf + 2 + 6) * cbSrcPel);
  2420. ALIGN_MEM(cbCYExtra, cbCYExtra);
  2421. //
  2422. // cbInBuf is for the input scan line of EXPAND/SHRINK mode, add one
  2423. // because we want to run it in DWORD mode so we need at least an extra
  2424. // byte at end of input buffer
  2425. //
  2426. // 26-Jun-1998 Fri 16:03:26 updated -by- Daniel Chou (danielc)
  2427. // The cbOutBuf is used only when we flipping in X direction, this is
  2428. // needed since the input/output buffer may collide into each other
  2429. //
  2430. ALIGN_MEM(cbInBuf, (cbInBuf + 2) * cbSrcPel);
  2431. ALIGN_MEM(cbOutBuf, (cOut + (FAST_MAX_CX * 2)) * sizeof(BGRF));
  2432. cbMaskSrc = (aabbp.AAHFlags & AAHF_HAS_MASK) ?
  2433. (ComputeBytesPerScanLine(BMF_1BPP, 4, cIn) + 4) : 0;
  2434. cbMaskSrc = _ALIGN_MEM(cbMaskSrc);
  2435. if (cbInBuf < cbAlphaBuf) {
  2436. cbInBuf = cbAlphaBuf;
  2437. }
  2438. if ((aabbp.AAHFlags & (AAHF_ALPHA_BLEND | AAHF_CONST_ALPHA)) ==
  2439. AAHF_ALPHA_BLEND) {
  2440. ALIGN_MEM(cbAlphaBuf, cOut);
  2441. } else {
  2442. cbAlphaBuf = 0;
  2443. }
  2444. DBGP_IF(DBGP_FIXUPDIB,
  2445. DBGP("** Allocate cIn=%ld, cOut=%ld, cbInBuf=%ld, cbOutBuf=%ld, cbMaskSrc=%ld"
  2446. ARGDW(cIn) ARGDW(cOut) ARGDW(cbInBuf) ARGDW(cbOutBuf)
  2447. ARGDW(cbMaskSrc)));
  2448. if ((DstSurfFmt == BMF_8BPP_VGA256) && (pHR->pXlate8BPP)) {
  2449. ALIGN_MEM(cbVGA256Xlate, SIZE_XLATE_666);
  2450. DBGP_IF((DBGP_AAHTPAT | DBGP_AAHT_MEM),
  2451. DBGP("Allocate %ld bytes of Xlate8BPP" ARGDW(cbVGA256Xlate)));
  2452. } else {
  2453. cbVGA256Xlate = 0;
  2454. }
  2455. if (aabbp.AAHFlags & AAHF_DO_FIXUPDIB) {
  2456. ALIGN_MEM(cbFUDI, (cIn + 4) * cbSrcPel);
  2457. } else {
  2458. cbFUDI = 0;
  2459. }
  2460. if ((pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY) &&
  2461. (pHR->BFInfo.Flags & BFIF_RGB_888) &&
  2462. (pAAHdr->SrcSurfInfo.AABFData.Flags & AABF_MASK_IS_ORDER) &&
  2463. (pHR->BFInfo.RGBOrder.Index != PRIMARY_ORDER_BGR)) {
  2464. //
  2465. // This is for mapping >= 16bpp source's IdxBGR to gray, when mapping
  2466. // to gray we will make IdxBGR to a correct source order so that it
  2467. // will optimized the source input function speed
  2468. //
  2469. // The AABF_MASK_IS_ORDER indicate the source is 8-bits each of Red,
  2470. // green and blue and it is only occuply lower 24-bits of either
  2471. // a 24-bits or a 32-bits data
  2472. //
  2473. ALIGN_MEM(cbIdxBGR, sizeof(LONG) * 256 * 3);
  2474. DBGP_IF(DBGP_AAHEADER,
  2475. DBGP("Allocate gray non 24bits BGR [%ld] IDXBGR of %ld bytes"
  2476. ARGDW(pHR->BFInfo.RGBOrder.Index) ARGDW(cbIdxBGR)));
  2477. } else {
  2478. cbIdxBGR = 0;
  2479. }
  2480. if (pAAInfoCY = aabbp.AABuildCYFunc(pDCI,
  2481. aabbp.AAHFlags,
  2482. &aabbp.rclSrc.top,
  2483. &aabbp.rclSrc.bottom,
  2484. pSrcSI->Height,
  2485. aabbp.rclDstOrg.top,
  2486. aabbp.rclDstOrg.bottom,
  2487. &aabbp.rclDst.top,
  2488. &aabbp.rclDst.bottom,
  2489. cbInBuf + cbOutBuf + cbMaskSrc +
  2490. (cbFUDI * 6) + cbAlphaBuf +
  2491. cbIdxBGR +
  2492. cbVGA256Xlate + cbCYExtra))
  2493. {
  2494. // Bug 27036: reject empty rectangles
  2495. if(!pAAInfoCY->cIn || !pAAInfoCY->cOut)
  2496. {
  2497. #if 0
  2498. LONG crash = 1 ; // empty src or dest rectangle!
  2499. crash /= (pAAInfoCY->cIn * pAAInfoCY->cOut); // delete when debugging is complete.
  2500. if(crash)
  2501. return 0 ;
  2502. #endif
  2503. HTFreeMem(pAAInfoCX);
  2504. HTFreeMem(pAAInfoCY);
  2505. return 0 ;
  2506. }
  2507. pbExtra = pAAInfoCY->pbExtra + cbCYExtra;
  2508. pAAHdr->Flags = aabbp.AAHFlags;
  2509. pAAHdr->SrcSurfInfo.cbCX = cbSrcPel * cIn;
  2510. pAAHdr->pInputBeg = (PBGR8)pbExtra;
  2511. pbExtra += cbInBuf;
  2512. if (cbAlphaBuf) {
  2513. //
  2514. // 04-Aug-2000 Fri 10:31:45 updated -by- Daniel Chou (danielc)
  2515. // Since cbAlphaBuf is Memoey Aliged Adjusted, we want the
  2516. // pSrcAVEnd to be at exactly count of cOut not cbAlphaBuf
  2517. //
  2518. pAAHdr->pSrcAV =
  2519. pAAHdr->pSrcAVBeg = (LPBYTE)pbExtra;
  2520. pAAHdr->pSrcAVEnd = (LPBYTE)pbExtra + cOut;
  2521. pbExtra += cbAlphaBuf;
  2522. pAAHdr->SrcAVInc = sizeof(BYTE);
  2523. }
  2524. if (cbFUDI) {
  2525. pAAHdr->pbFixupDIB = (LPBYTE)pbExtra;
  2526. pAAHdr->FUDI.cbbgr = (DWORD)cbFUDI;
  2527. for (Top = 0; Top < 6; Top++) {
  2528. pAAHdr->FUDI.prgbD[Top] = (PBGR8)pbExtra;
  2529. pbExtra += cbFUDI;
  2530. }
  2531. }
  2532. if (cbVGA256Xlate) {
  2533. pAAHdr->pXlate8BPP = pbExtra;
  2534. pbExtra += cbVGA256Xlate;
  2535. }
  2536. if (cbMaskSrc) {
  2537. pAAHdr->pMaskSrc = pbExtra;
  2538. pbExtra += cbMaskSrc;
  2539. }
  2540. if (cbIdxBGR) {
  2541. //
  2542. // The pIdxBGR is a local version that will be later re-arranged
  2543. // from pAAHdr->pIdxBGR to correct source byte order in
  2544. // SetGrayColorTable() function
  2545. //
  2546. pAAHdr->SrcSurfInfo.pIdxBGR = (PLONG)pbExtra;
  2547. pbExtra += cbIdxBGR;
  2548. } else {
  2549. pAAHdr->SrcSurfInfo.pIdxBGR = pAAHdr->pIdxBGR;
  2550. }
  2551. DBGP_IF(DBGP_AAHEADER,
  2552. DBGP("cbInBuf=%ld, %p-%p" ARGDW(cbInBuf)
  2553. ARGPTR(pAAHdr->pInputBeg)
  2554. ARGPTR((LPBYTE)pAAHdr->pInputBeg + cbInBuf)));
  2555. //
  2556. // FAST_MAX_CX are added to both end of AABuf, this is needed when
  2557. // we want to process the output fast, since we may need to extended
  2558. // the computation to the neighbor pixels
  2559. //
  2560. pAAHdr->pOutputBeg =
  2561. pAAHdr->pRealOutBeg =
  2562. pAAHdr->pAABufBeg = (PBGRF)pbExtra + FAST_MAX_CX;
  2563. pAAHdr->pRealOutEnd =
  2564. pAAHdr->pOutputEnd = pAAHdr->pAABufBeg + cOut;
  2565. pAAHdr->pAABufEnd = pAAHdr->pOutputEnd;
  2566. //
  2567. // Set the BGRF's Flags to 0xFF first, the 0xFF indicate that this
  2568. // pixel need to be output (masked).
  2569. //
  2570. FillMemory((LPBYTE)pAAHdr->pOutputBeg,
  2571. (LPBYTE)pAAHdr->pOutputEnd - (LPBYTE)pAAHdr->pOutputBeg,
  2572. PBGRF_MASK_FLAG);
  2573. //
  2574. // We mirror the image by composed the source the the AABuf in
  2575. // reverse way. Reading the source from left to right but when
  2576. // composed the source buffer (AABuf) we put it from right to left
  2577. //
  2578. if (aabbp.rclDst.left > aabbp.rclDst.right) {
  2579. XCHG(aabbp.rclDst.left, aabbp.rclDst.right, Result);
  2580. pAAHdr->pAABufBeg = pAAHdr->pOutputEnd - 1;
  2581. pAAHdr->pAABufEnd = pAAHdr->pOutputBeg - 1;
  2582. pAAHdr->AABufInc = -(LONG)sizeof(BGRF);
  2583. pAAHdr->pSrcAVBeg = pAAHdr->pSrcAVEnd - 1;
  2584. pAAHdr->pSrcAVEnd = pAAHdr->pSrcAV - 1;
  2585. pAAHdr->SrcAVInc = -pAAHdr->SrcAVInc;
  2586. } else {
  2587. pAAHdr->AABufInc = (LONG)sizeof(BGRF);
  2588. }
  2589. pAAHdr->ptlBrushOrg.x = aabbp.rclDst.left - aabbp.ptlBrushOrg.x;
  2590. DBGP_IF(DBGP_AAHEADER,
  2591. DBGP("pInput=%p-%p (%ld), pAABuf=%p-%p (%ld), pOutput=%p-%p, DstLeft=%ld"
  2592. ARGPTR(pAAHdr->pInputBeg)
  2593. ARGPTR((LPBYTE)pAAHdr->pInputBeg +
  2594. pAAHdr->SrcSurfInfo.cbCX)
  2595. ARGL(pAAHdr->SrcSurfInfo.cbCX)
  2596. ARGPTR(pAAHdr->pAABufBeg) ARGPTR(pAAHdr->pAABufEnd)
  2597. ARGDW(pAAHdr->AABufInc)
  2598. ARGPTR(pAAHdr->pOutputBeg) ARGPTR(pAAHdr->pOutputEnd)
  2599. ARGDW(aabbp.rclDst.left)));
  2600. if (aabbp.AAHFlags & AAHF_FLIP_Y) {
  2601. DBGP_IF(DBGP_AAHEADER,
  2602. DBGP("Y Dst=(%ld - %ld)=%ld change it to (%ld - %ld), ptlFlip.y=%ld"
  2603. ARGDW(aabbp.rclDst.top) ARGDW(aabbp.rclDst.bottom)
  2604. ARGDW(aabbp.rclDst.bottom - aabbp.rclDst.top)
  2605. ARGDW(aabbp.ptlFlip.y - aabbp.rclDst.top - 1)
  2606. ARGDW(aabbp.ptlFlip.y - aabbp.rclDst.bottom - 1)
  2607. ARGDW(aabbp.ptlFlip.y)));
  2608. aabbp.rclDst.top = aabbp.ptlFlip.y - aabbp.rclDst.top - 1;
  2609. aabbp.rclDst.bottom = aabbp.ptlFlip.y - aabbp.rclDst.bottom - 1;
  2610. }
  2611. pAAHdr->ptlBrushOrg.y = aabbp.rclDst.top - aabbp.ptlBrushOrg.y;
  2612. DBGP_IF(DBGP_AAHEADER,
  2613. DBGP("BrushOrg=(%ld, %ld) ---> (%ld, %ld)"
  2614. ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)
  2615. ARGDW(pAAHdr->ptlBrushOrg.x) ARGDW(pAAHdr->ptlBrushOrg.y)));
  2616. pAAHdr->pAAInfoCX = pAAInfoCX;
  2617. pAAHdr->pAAInfoCY = pAAInfoCY;
  2618. pAAHdr->AACXFunc = aabbp.AACXFunc;
  2619. pAAHdr->SrcSurfInfo.cx = pAAInfoCX->cIn;
  2620. pAAHdr->SrcSurfInfo.cyOrg =
  2621. pAAHdr->SrcSurfInfo.cy = pAAInfoCY->cIn;
  2622. if (aabbp.AAHFlags & AAHF_HAS_MASK) {
  2623. POINTL MaskEnd;
  2624. cyNext =
  2625. cxSize = GET_PHTSI_CXSIZE(pMaskSI);
  2626. aabbp.ptlMask.x += pAAInfoCX->Mask.iBeg;
  2627. aabbp.ptlMask.y += pAAInfoCY->Mask.iBeg;
  2628. MaskEnd.x = aabbp.ptlMask.x + pAAInfoCX->Mask.iSize;
  2629. MaskEnd.y = aabbp.ptlMask.y + pAAInfoCY->Mask.iSize;
  2630. if ((aabbp.ptlMask.x < 0) ||
  2631. (aabbp.ptlMask.y < 0) ||
  2632. (MaskEnd.x > pMaskSI->Width) ||
  2633. (MaskEnd.y > pMaskSI->Height)) {
  2634. HTFreeMem(pAAInfoCX);
  2635. HTFreeMem(pAAInfoCY);
  2636. return(HTERR_SRC_MASK_BITS_TOO_SMALL);
  2637. }
  2638. pAAHdr->cyMaskNext = cyNext;
  2639. pAAHdr->cyMaskIn = pAAInfoCY->Mask.iSize;
  2640. iFree = ComputeByteOffset(BMF_1BPP,
  2641. MaskEnd.x,
  2642. &(pAAHdr->MaskBitOff));
  2643. cbFreeBuf = ComputeByteOffset(BMF_1BPP,
  2644. aabbp.ptlMask.x,
  2645. &(pAAHdr->MaskBitOff));
  2646. pAAHdr->cbMaskSrc = iFree - cbFreeBuf + 1;
  2647. pAAHdr->pMaskIn = pMaskSI->pPlane +
  2648. (aabbp.ptlMask.y * cxSize) + cbFreeBuf;
  2649. DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
  2650. DBGP("CX: iMaskBeg=%ld, iMaskSize=%ld, cMaskIn=%ld, cMaskOut=%ld"
  2651. ARGDW(pAAInfoCX->Mask.iBeg) ARGDW(pAAInfoCX->Mask.iSize)
  2652. ARGDW(pAAInfoCX->Mask.cIn) ARGDW(pAAInfoCX->Mask.cOut)));
  2653. DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
  2654. DBGP("CY: iMaskBeg=%ld, iMaskSize=%ld, cMaskIn=%ld, cMaskOut=%ld"
  2655. ARGDW(pAAInfoCY->Mask.iBeg) ARGDW(pAAInfoCY->Mask.iSize)
  2656. ARGDW(pAAInfoCY->Mask.cIn) ARGDW(pAAInfoCY->Mask.cOut)));
  2657. DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
  2658. DBGP("aabbp.ptlMask x=%ld - %ld, cb=%ld, MaskBitOff=%02lx [%ld]"
  2659. ARGDW(aabbp.ptlMask.x) ARGDW(MaskEnd.x)
  2660. ARGDW(pAAHdr->cbMaskSrc) ARGDW(pAAHdr->MaskBitOff)
  2661. ARGDW(cbFreeBuf)));
  2662. //
  2663. // 0x01 in the source means use modified pixel, for the
  2664. // reason of or in the mask, we will use 0=0xFF, 1=0x00
  2665. // in the mask
  2666. //
  2667. if (pBBP->Flags & BBPF_INVERT_SRC_MASK) {
  2668. aabbp.AAHFlags |= AAHF_INVERT_MASK;
  2669. }
  2670. pAAHdr->AAMaskCXFunc = aabbp.AAMaskCXFunc;
  2671. pAAHdr->AAMaskCYFunc = aabbp.AAMaskCYFunc;
  2672. SETDBGVAR(cCXMask, 0);
  2673. DBGP_IF(DBGP_AAHEADER,
  2674. DBGP("--- SrcMask=(%5ld, %5ld)->(%5ld, %5ld) ---"
  2675. ARGDW(pBBP->ptlSrcMask.x) ARGDW(pBBP->ptlSrcMask.y)
  2676. ARGDW(aabbp.ptlMask.x) ARGDW(aabbp.ptlMask.y)));
  2677. }
  2678. cyNext =
  2679. cxSize = GET_PHTSI_CXSIZE(pSrcSI);
  2680. pAAHdr->cyABNext =
  2681. pAAHdr->SrcSurfInfo.cyNext = cyNext;
  2682. pAAHdr->SrcSurfInfo.pbOrg =
  2683. pAAHdr->SrcSurfInfo.pb =
  2684. pSrcSI->pPlane + (aabbp.rclSrc.top * cxSize) +
  2685. ComputeByteOffset((UINT)pSrcSI->SurfaceFormat,
  2686. aabbp.rclSrc.left,
  2687. &(pAAHdr->SrcSurfInfo.BitOffset));
  2688. pAAHdr->GetAVCXFunc = aabbp.GetAVCXFunc;
  2689. pAAHdr->GetAVCYFunc = aabbp.GetAVCYFunc;
  2690. DBGP_IF(DBGP_AAHEADER,
  2691. DBGP("** pIn: (%p-%p), Beg=(%4ld, %4ld)=%p [%5ld], XOff=%4ld:%ld, cbCYExtra=%p-%p (%ld)"
  2692. ARGPTR(pSrcSI->pPlane)
  2693. ARGPTR(pSrcSI->pPlane + (cxSize * pSrcSI->Height))
  2694. ARGDW(aabbp.rclSrc.left) ARGDW(aabbp.rclSrc.top)
  2695. ARGPTR(pAAHdr->SrcSurfInfo.pb)
  2696. ARGDW(pAAHdr->SrcSurfInfo.cyNext)
  2697. ARGDW(ComputeByteOffset((UINT)pSrcSI->SurfaceFormat,
  2698. aabbp.rclSrc.left,
  2699. &(pAAHdr->SrcSurfInfo.BitOffset)))
  2700. ARGDW(pAAHdr->SrcSurfInfo.BitOffset)
  2701. ARGPTR(pAAInfoCY->pbExtra)
  2702. ARGPTR(pAAInfoCY->pbExtra + cbCYExtra)
  2703. ARGDW(cbCYExtra)));
  2704. //
  2705. // We do up-side-down output by writing to the destination scan lines
  2706. // in reverse order.
  2707. //
  2708. cxSize = GET_PHTSI_CXSIZE(pDstSI);
  2709. cyNext = (aabbp.rclDst.top > aabbp.rclDst.bottom) ? -cxSize :
  2710. cxSize;
  2711. pAAHdr->DstSurfInfo.cyNext = cyNext;
  2712. pAAHdr->DstSurfInfo.pbOrg =
  2713. pAAHdr->DstSurfInfo.pb =
  2714. pDstSI->pPlane + (aabbp.rclDst.top * cxSize) +
  2715. ComputeByteOffset((UINT)DstSurfFmt,
  2716. aabbp.rclDst.left,
  2717. &(pAAHdr->DstSurfInfo.BitOffset));
  2718. pAAHdr->pOutLast = pAAHdr->DstSurfInfo.pb +
  2719. (pAAHdr->DstSurfInfo.cyNext *
  2720. pAAInfoCY->cOut);
  2721. pAAHdr->DstSurfInfo.cx = cOut;
  2722. pAAHdr->DstSurfInfo.cyOrg =
  2723. pAAHdr->DstSurfInfo.cy = pAAInfoCY->cOut;
  2724. pAAHdr->Flags = aabbp.AAHFlags; // Re-Save
  2725. *pAACYFunc = AACYFunc;
  2726. #if DBG
  2727. pAAHdr->pOutBeg = pDstSI->pPlane +
  2728. (aabbp.rclDst.top * cxSize) +
  2729. ComputeByteOffset((UINT)DstSurfFmt,
  2730. aabbp.rclDst.left,
  2731. (LPBYTE)&iFree);
  2732. pAAHdr->pOutEnd = pDstSI->pPlane +
  2733. (aabbp.rclDst.bottom * cxSize) +
  2734. ComputeByteOffset((UINT)DstSurfFmt,
  2735. aabbp.rclDst.right,
  2736. (LPBYTE)&iFree);
  2737. if (pAAHdr->pOutBeg > pAAHdr->pOutEnd) {
  2738. pAAHdr->pOutEnd = pDstSI->pPlane +
  2739. (aabbp.rclDst.top * cxSize) +
  2740. ComputeByteOffset((UINT)DstSurfFmt,
  2741. aabbp.rclDst.right,
  2742. (LPBYTE)&iFree);
  2743. pAAHdr->pOutBeg = pDstSI->pPlane +
  2744. (aabbp.rclDst.bottom * cxSize) +
  2745. ComputeByteOffset((UINT)DstSurfFmt,
  2746. aabbp.rclDst.left,
  2747. (LPBYTE)&iFree);
  2748. }
  2749. #endif
  2750. //
  2751. // Check it out if we need to fixup the input source bitmap
  2752. //
  2753. if (aabbp.AAHFlags & AAHF_TILE_SRC) {
  2754. //
  2755. // Increase the source cy and adjust pIn now
  2756. //
  2757. pAAHdr->SrcSurfInfo.Flags |= AASIF_TILE_SRC;
  2758. DBGP_IF(DBGP_AAHEADER,
  2759. DBGP("Advance pIn by iSrcBeg=%ld x %ld=%ld"
  2760. ARGDW(pAAInfoCY->iSrcBeg)
  2761. ARGDW(pAAHdr->SrcSurfInfo.cyNext)
  2762. ARGDW(pAAInfoCY->iSrcBeg *
  2763. pAAHdr->SrcSurfInfo.cyNext)));
  2764. pAAHdr->SrcSurfInfo.pb += pAAInfoCY->iSrcBeg *
  2765. pAAHdr->SrcSurfInfo.cyNext;
  2766. pAAHdr->SrcSurfInfo.cy -= pAAInfoCY->iSrcBeg;
  2767. }
  2768. pAAHdr->pbgrfAB = (PBGRF)pAAHdr->SrcSurfInfo.pb;
  2769. pAAHdr->cybgrfAB = pAAHdr->SrcSurfInfo.cy;
  2770. DBGP_IF(DBGP_AAHEADER,
  2771. DBGP("** pOut: (%p-%p), Beg=(%4ld, %4ld)=%p-%p (%p-%p) [%5ld], XOff=%4ld:%ld, cbCYExtra=%5ld"
  2772. ARGPTR(pDstSI->pPlane)
  2773. ARGPTR(pDstSI->pPlane + (cxSize * pDstSI->Height))
  2774. ARGDW(aabbp.rclDst.left) ARGDW(aabbp.rclDst.top)
  2775. ARGPTR(pAAHdr->DstSurfInfo.pb) ARGPTR(pAAHdr->pOutLast)
  2776. ARGPTR(pAAHdr->pOutBeg) ARGPTR(pAAHdr->pOutEnd)
  2777. ARGDW(pAAHdr->DstSurfInfo.cyNext)
  2778. ARGDW(ComputeByteOffset((UINT)DstSurfFmt,
  2779. aabbp.rclDst.left,
  2780. &(pAAHdr->DstSurfInfo.BitOffset)))
  2781. ARGDW(pAAHdr->DstSurfInfo.BitOffset)
  2782. ARGDW(cbCYExtra)));
  2783. DBGP_IF(DBGP_AAHEADER,
  2784. DBGP("--- BrushOrg=(%5ld, %5ld)->(%5ld, %5ld) ---"
  2785. ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)
  2786. ARGDW(pAAHdr->ptlBrushOrg.x) ARGDW(pAAHdr->ptlBrushOrg.y)));
  2787. DBGP_IF(DBGP_AAHEADER,
  2788. DBGP("pAAHdr=%p - %p, (%ld bytes)"
  2789. ARGPTR(pAAHdr) ARGPTR((LPBYTE)pAAHdr + pAAHdr->cbAlloc)
  2790. ARGDW(pAAHdr->cbAlloc)));
  2791. DBGP_IF(DBGP_AAHEADER,
  2792. DBGP("pAAInfoCX=%p-%p (%ld), pAAInfoCY=%p-%p (%ld)"
  2793. ARGPTR(pAAInfoCX)
  2794. ARGPTR((LPBYTE)pAAInfoCX + pAAInfoCX->cbAlloc)
  2795. ARGDW(pAAInfoCX->cbAlloc)
  2796. ARGPTR(pAAInfoCY)
  2797. ARGPTR((LPBYTE)pAAInfoCY + pAAInfoCY->cbAlloc)
  2798. ARGDW(pAAInfoCY->cbAlloc)));
  2799. DBGP_IF(DBGP_FUNC,
  2800. DBGP("AACYFunc=%hs, AACXFunc=%hs"
  2801. ARGPTR(GetAACYFuncName(*pAACYFunc))
  2802. ARGPTR(GetAACXFuncName(aabbp.AACXFunc))));
  2803. return(1);
  2804. }
  2805. HTFreeMem(pAAInfoCX);
  2806. return(HTERR_INSUFFICIENT_MEMORY);
  2807. }