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.

1542 lines
38 KiB

  1. /*++
  2. Copyright (c) 1990-1991 Microsoft Corporation
  3. Module Name:
  4. htrender.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. 12-Jan-1999 Tue 11:09:50 updated -by- Daniel Chou (danielc)
  14. --*/
  15. #define DBGP_VARNAME dbgpHTRender
  16. #include "htp.h"
  17. #include "htmapclr.h"
  18. #include "htpat.h"
  19. #include "limits.h"
  20. #include "htalias.h"
  21. #include "htrender.h"
  22. #include "htstret.h"
  23. #include "htgetbmp.h"
  24. #include "htsetbmp.h"
  25. #define DBGP_BFINFO 0x00000001
  26. #define DBGP_FUNC 0x00000002
  27. #define DBGP_AAHT_MEM 0x00000004
  28. DEF_DBGPVAR(BIT_IF(DBGP_BFINFO, 0) |
  29. BIT_IF(DBGP_FUNC, 0) |
  30. BIT_IF(DBGP_AAHT_MEM, 0))
  31. extern CONST RGBORDER SrcOrderTable[PRIMARY_ORDER_MAX + 1];
  32. extern const RGBORDER DstOrderTable[PRIMARY_ORDER_MAX + 1];
  33. extern CONST BYTE RGB666Xlate[];
  34. extern CONST BYTE CMY666Xlate[];
  35. extern CONST BYTE RGB555Xlate[];
  36. extern CONST BYTE CMY555Xlate[];
  37. extern CONST LPBYTE p8BPPXlate[];
  38. #define COLOR_SWAP_BC 0x01
  39. #define COLOR_SWAP_AB 0x02
  40. #define COLOR_SWAP_AC 0x04
  41. #if DBG
  42. CHAR *pOrderName[] = { "RGB", "RBG", "GRB", "GBR", "BGR", "BRG" };
  43. #endif
  44. #define BFINFO_BITS_A BFInfo.BitsRGB[0]
  45. #define BFINFO_BITS_B BFInfo.BitsRGB[1]
  46. #define BFINFO_BITS_C BFInfo.BitsRGB[2]
  47. #define PHR_BFINFO_BITS_A pHR->BFInfo.BitsRGB[0]
  48. #define PHR_BFINFO_BITS_B pHR->BFInfo.BitsRGB[1]
  49. #define PHR_BFINFO_BITS_C pHR->BFInfo.BitsRGB[2]
  50. BOOL
  51. HTENTRY
  52. ValidateRGBBitFields(
  53. PBFINFO pBFInfo
  54. )
  55. /*++
  56. Routine Description:
  57. This function determined the RGB primary order from the RGB bit fields
  58. Arguments:
  59. pBFInfo - Pointer to the BFINFO data structure, following field must
  60. set before the call
  61. BitsRGB[0] = Red Bits
  62. BitsRGB[1] = Green Bits
  63. BitsRGB[2] = Blue Bits
  64. BitmapFormat = BMF_16BPP/BMF_24BPP/BMF_32BPP
  65. RGB1stBit = Specifed PRIMARY_ORDER_xxx ONLY for BMF_1BPP,
  66. BMF_4BPP, BMF_8BPP, BMF_24BPP
  67. requested order.
  68. Return Value:
  69. FALSE if BitsRGB[] or BitmapFormat passed are not valid
  70. else TRUE and following fields are returned
  71. BitsRGB[] - corrected mask bits
  72. BitmapFormat - BMF_16BPP/BMF_24BPP/BMF_32BPP
  73. Flags - BFIF_xxxx
  74. SizeLUT - Size of LUT table
  75. BitStart[] - Starting bits for each of RGB
  76. BitCount[] - Bits Count for each of RGB
  77. RGBOrder - Current RGB order, for BMF_1BPP, BMF_4BPP, BMF_8BPP
  78. and BMF_24BPP the RGBOrder.Index must specified a
  79. PRIMARY_ORDER_xxx, for BMF_16BPP, BMF_32BPP the
  80. RGBOrder.Index will be set by this function
  81. RGB1stBit - The bit start for first on bit in BitsRGB[]
  82. GrayShr[] - The right shift count so that most significant bit
  83. of each RGB color is aligned to bit 7 if the total
  84. bit count of RGB is greater than 8 otherwise this
  85. value is 0, it is used when construct the monochrome
  86. Y value.
  87. Author:
  88. 03-Mar-1993 Wed 12:33:22 created -by- Daniel Chou (danielc)
  89. Revision History:
  90. 06-Apr-1993 Tue 12:15:58 updated -by- Daniel Chou (danielc)
  91. Add 24bpp support for any other order than BGR
  92. --*/
  93. {
  94. BFINFO BFInfo = *pBFInfo;
  95. DWORD AllBits;
  96. DWORD PrimBits;
  97. INT Index;
  98. BYTE BitCount;
  99. BYTE BitStart;
  100. switch (BFInfo.BitmapFormat) {
  101. case BMF_1BPP:
  102. case BMF_4BPP:
  103. case BMF_8BPP:
  104. BFInfo.RGBOrder = SrcOrderTable[BFInfo.RGBOrder.Index];
  105. BFInfo.BitCount[0] =
  106. BFInfo.BitCount[1] =
  107. BFInfo.BitCount[2] = 8;
  108. PrimBits = (DWORD)0x000000ff;
  109. BitStart = 0;
  110. for (Index = 0; Index < 3; Index++) {
  111. BitCount = BFInfo.RGBOrder.Order[Index];
  112. BFInfo.BitsRGB[BitCount] = PrimBits;
  113. BFInfo.BitStart[BitCount] = BitStart;
  114. PrimBits <<= 8;
  115. BitStart += 8;
  116. }
  117. break;
  118. case BMF_16BPP:
  119. case BMF_16BPP_555:
  120. case BMF_16BPP_565:
  121. BFInfo.BitsRGB[0] &= 0xffff;
  122. BFInfo.BitsRGB[1] &= 0xffff;
  123. BFInfo.BitsRGB[2] &= 0xffff;
  124. //
  125. // FALL THROUGH to compute
  126. //
  127. case BMF_24BPP:
  128. case BMF_32BPP:
  129. //
  130. // The bit fields cannot be overlaid
  131. //
  132. if (!(AllBits = (BFInfo.BitsRGB[0] |
  133. BFInfo.BitsRGB[1] |
  134. BFInfo.BitsRGB[2]))) {
  135. DBGP_IF(DBGP_BFINFO, DBGP("ERROR: BitsRGB[] all zeros"));
  136. return(FALSE);
  137. }
  138. if ((BFInfo.BitsRGB[0] & BFInfo.BitsRGB[1]) ||
  139. (BFInfo.BitsRGB[0] & BFInfo.BitsRGB[2]) ||
  140. (BFInfo.BitsRGB[1] & BFInfo.BitsRGB[2])) {
  141. DBGP_IF(DBGP_BFINFO,
  142. DBGP("ERROR: BitsRGB[] Overlay: %08lx:%08lx:%08lx"
  143. ARGDW(BFInfo.BitsRGB[0])
  144. ARGDW(BFInfo.BitsRGB[1])
  145. ARGDW(BFInfo.BitsRGB[2])));
  146. return(FALSE);
  147. }
  148. //
  149. // Now Check the bit count, we will allowed bit count to be 0
  150. //
  151. for (Index = 0; Index < 3; Index++) {
  152. BitStart =
  153. BitCount = 0;
  154. if (PrimBits = BFInfo.BitsRGB[Index]) {
  155. while (!(PrimBits & 0x01)) {
  156. PrimBits >>= 1; // get to the first bit
  157. ++BitStart;
  158. }
  159. do {
  160. ++BitCount;
  161. } while ((PrimBits >>= 1) & 0x01);
  162. if (PrimBits) {
  163. //
  164. // The bit fields is not contiguous
  165. //
  166. DBGP_IF(DBGP_BFINFO,
  167. DBGP("ERROR: BitsRGB[%u]=%08lx is not contiguous"
  168. ARGU(Index)
  169. ARGDW(BFInfo.BitsRGB[Index])));
  170. return(FALSE);
  171. }
  172. }
  173. BFInfo.BitStart[Index] = BitStart;
  174. BFInfo.BitCount[Index] = BitCount;
  175. if (!BitCount) {
  176. DBGP_IF(DBGP_BFINFO,
  177. DBGP("WARNING: BitsRGB[%u] is ZERO"
  178. ARGU(Index)));
  179. }
  180. }
  181. if ((AllBits == 0x00FFFFFF) &&
  182. (BFInfo.BitCount[0] == 8) &&
  183. (BFInfo.BitCount[1] == 8) &&
  184. (BFInfo.BitCount[2] == 8)) {
  185. BFInfo.Flags |= BFIF_RGB_888;
  186. }
  187. //
  188. // Check what primary order is this, remember the Primary Order we
  189. // are checking is source, the source order defines is
  190. //
  191. // PRIMARY_ORDER_ABC
  192. // |||
  193. // ||+---- Highest memory location
  194. // |+----- middle memory location
  195. // +------ lowest memory location
  196. //
  197. if ((BFINFO_BITS_A < BFINFO_BITS_B) &&
  198. (BFINFO_BITS_A < BFINFO_BITS_C)) {
  199. //
  200. // A is the smallest, so ABC or ACB
  201. //
  202. Index = (INT)((BFINFO_BITS_B < BFINFO_BITS_C) ? PRIMARY_ORDER_ABC :
  203. PRIMARY_ORDER_ACB);
  204. } else if ((BFINFO_BITS_B < BFINFO_BITS_A) &&
  205. (BFINFO_BITS_B < BFINFO_BITS_C)) {
  206. //
  207. // B is the smallest, so BAC or BCA
  208. //
  209. Index = (INT)((BFINFO_BITS_A < BFINFO_BITS_C) ? PRIMARY_ORDER_BAC :
  210. PRIMARY_ORDER_BCA);
  211. } else {
  212. //
  213. // C is the smallest, so CAB or CBA
  214. //
  215. Index = (INT)((BFINFO_BITS_A < BFINFO_BITS_B) ? PRIMARY_ORDER_CAB :
  216. PRIMARY_ORDER_CBA);
  217. }
  218. BFInfo.RGBOrder = SrcOrderTable[Index];
  219. break;
  220. default:
  221. DBGP("ERROR: Invalid BFInfo.BitmapFormat=%u"
  222. ARGDW(pBFInfo->BitmapFormat));
  223. return(FALSE);
  224. }
  225. //
  226. // Put it back to return to the caller
  227. //
  228. *pBFInfo = BFInfo;
  229. //
  230. // Output some helpful information
  231. //
  232. DBGP_IF(DBGP_BFINFO,
  233. DBGP("============ BFINFO: BMP Format=%ld ==========="
  234. ARGDW(pBFInfo->BitmapFormat));
  235. DBGP(" BitsRGB[] = 0x%08lx:0x%08lx:0x%08lx"
  236. ARGDW(pBFInfo->BitsRGB[0])
  237. ARGDW(pBFInfo->BitsRGB[1])
  238. ARGDW(pBFInfo->BitsRGB[2]));
  239. DBGP(" Flags = 0x%02x %s"
  240. ARGU(pBFInfo->Flags)
  241. ARGPTR((pBFInfo->Flags & BFIF_RGB_888) ?
  242. "BFIF_RGB_888" : ""));
  243. DBGP(" RGBOrder[] = %2u - %2u:%2u:%2u [PRIMARY_ORDER_%hs]"
  244. ARGU(pBFInfo->RGBOrder.Index)
  245. ARGU(pBFInfo->RGBOrder.Order[0])
  246. ARGU(pBFInfo->RGBOrder.Order[1])
  247. ARGU(pBFInfo->RGBOrder.Order[2])
  248. ARGPTR(pOrderName[pBFInfo->RGBOrder.Index]));
  249. DBGP(" BitStart[] = %2u:%2u:%2u"
  250. ARGU(pBFInfo->BitStart[0])
  251. ARGU(pBFInfo->BitStart[1])
  252. ARGU(pBFInfo->BitStart[2]));
  253. DBGP(" BitCount[] = %2u:%2u:%2u"
  254. ARGU(pBFInfo->BitCount[0])
  255. ARGU(pBFInfo->BitCount[1])
  256. ARGU(pBFInfo->BitCount[2])));
  257. return(TRUE);
  258. }
  259. LONG
  260. HTENTRY
  261. ValidateHTSI(
  262. PHALFTONERENDER pHR,
  263. UINT ValidateMode
  264. )
  265. /*++
  266. Routine Description:
  267. This function read the HTSurfaceInfo and set it to the pHTCBParams
  268. Arguments:
  269. pHR - ponter to HALFTONERENDER data structure
  270. ValiateMode - VALIDATE_HTSC_SRC/VALIDATE_HTSI_DEST/VALIDATE_HTSI_MASK
  271. Return Value:
  272. >= 0 - Sucessful
  273. < 0 - HTERR_xxxx error codes
  274. Author:
  275. 28-Jan-1991 Mon 09:55:53 created -by- Daniel Chou (danielc)
  276. Revision History:
  277. --*/
  278. {
  279. LPDWORD pBitsRGB;
  280. PHTSURFACEINFO pHTSI;
  281. COLORTRIAD ColorTriad;
  282. RGBORDER RGBOrder;
  283. DWORD MaxColors;
  284. BYTE MaxBytesPerEntry;
  285. switch (ValidateMode) {
  286. case VALIDATE_HTSI_MASK:
  287. if (pHTSI = pHR->pSrcMaskSI) {
  288. if (pHTSI->SurfaceFormat != BMF_1BPP) {
  289. return(HTERR_INVALID_SRC_MASK_FORMAT);
  290. }
  291. }
  292. break;
  293. case VALIDATE_HTSI_DEST:
  294. if (!(pHTSI = pHR->pDestSI)) {
  295. return(HTERR_NO_DEST_HTSURFACEINFO);
  296. }
  297. pHR->pXlate8BPP = NULL;
  298. switch(pHTSI->SurfaceFormat) {
  299. case BMF_1BPP:
  300. break;
  301. case BMF_8BPP_VGA256:
  302. //
  303. // Check if we have xlate table for the 8bpp device
  304. //
  305. if (pHTSI->pColorTriad) {
  306. ColorTriad = *(pHTSI->pColorTriad);
  307. if ((ColorTriad.pColorTable) &&
  308. (ColorTriad.ColorTableEntries == 256) &&
  309. (ColorTriad.PrimaryValueMax == 255) &&
  310. (ColorTriad.BytesPerEntry == 1) &&
  311. (ColorTriad.Type == COLOR_TYPE_RGB)) {
  312. pHR->pXlate8BPP = (LPBYTE)ColorTriad.pColorTable;
  313. }
  314. }
  315. break;
  316. case BMF_4BPP:
  317. case BMF_4BPP_VGA16:
  318. case BMF_16BPP_555:
  319. case BMF_16BPP_565:
  320. case BMF_24BPP:
  321. case BMF_32BPP:
  322. break;
  323. default:
  324. return(HTERR_INVALID_DEST_FORMAT);
  325. }
  326. break;
  327. case VALIDATE_HTSI_SRC:
  328. if (!(pHTSI = pHR->pSrcSI)) {
  329. return(HTERR_NO_SRC_HTSURFACEINFO);
  330. }
  331. if (!(pHTSI->pColorTriad)) {
  332. return(HTERR_NO_SRC_COLORTRIAD);
  333. }
  334. ColorTriad = *(pHTSI->pColorTriad);
  335. //
  336. // We will accept other color type (ie. YIQ/XYZ/LAB/LUV) when graphic
  337. // system has type defined for the api, currently halftone can handle
  338. // all these types for 16bpp/24bpp/32bpp sources.
  339. //
  340. if (ColorTriad.Type > COLOR_TYPE_MAX) {
  341. return(HTERR_INVALID_COLOR_TYPE);
  342. }
  343. MaxColors = 0;
  344. MaxBytesPerEntry = 4;
  345. pHR->BFInfo.RGBOrder.Index = (BYTE)ColorTriad.PrimaryOrder;
  346. switch(pHR->BFInfo.BitmapFormat = (BYTE)pHTSI->SurfaceFormat) {
  347. case BMF_1BPP:
  348. MaxColors = 2;
  349. break;
  350. case BMF_4BPP:
  351. MaxColors = 16;
  352. break;
  353. case BMF_8BPP:
  354. MaxColors = 256;
  355. break;
  356. case BMF_16BPP:
  357. MaxBytesPerEntry = 2; // and fall through
  358. case BMF_32BPP:
  359. //
  360. // 16BPP/32BPP bit fields type of input the parameter of
  361. // COLORTRIAD must
  362. //
  363. // Type = COLOR_TYPE_RGB
  364. // BytesPerPrimary = 0
  365. // BytesPerEntry = (16BPP=2, 32BPP=4)
  366. // PrimaryOrder = *Ignored*
  367. // PrimaryValueMax = *Ignored*
  368. // ColorTableEntries = 3
  369. // pColorTable = Point to 3 DWORD RGB bit masks
  370. //
  371. if ((ColorTriad.Type != COLOR_TYPE_RGB) ||
  372. (ColorTriad.BytesPerEntry != MaxBytesPerEntry) ||
  373. (ColorTriad.ColorTableEntries != 3) ||
  374. ((pBitsRGB = (LPDWORD)ColorTriad.pColorTable) == NULL)) {
  375. return(HTERR_INVALID_COLOR_TABLE);
  376. }
  377. PHR_BFINFO_BITS_A = *(pBitsRGB + 0);
  378. PHR_BFINFO_BITS_B = *(pBitsRGB + 1);
  379. PHR_BFINFO_BITS_C = *(pBitsRGB + 2);
  380. break;
  381. case BMF_24BPP:
  382. //
  383. // 24BPP must has COLORTRIAD as
  384. //
  385. // Type = COLOR_TYPE_xxxx
  386. // BytesPerPrimary = 1
  387. // BytesPerEntry = 3;
  388. // PrimaryOrder = PRIMARY_ORDER_xxxx
  389. // PrimaryValueMax = 255
  390. // ColorTableEntries = *Ignorde*
  391. // pColorTable = *Ignored*
  392. //
  393. if ((ColorTriad.Type != COLOR_TYPE_RGB) ||
  394. (ColorTriad.BytesPerPrimary != 1) ||
  395. (ColorTriad.BytesPerEntry != 3) ||
  396. (ColorTriad.PrimaryOrder > PRIMARY_ORDER_MAX) ||
  397. (ColorTriad.PrimaryValueMax != 255)) {
  398. return(HTERR_INVALID_COLOR_ENTRY_SIZE);
  399. }
  400. RGBOrder = SrcOrderTable[ColorTriad.PrimaryOrder];
  401. PHR_BFINFO_BITS_A = (DWORD)0xFF << (RGBOrder.Order[0] << 3);
  402. PHR_BFINFO_BITS_B = (DWORD)0xFF << (RGBOrder.Order[1] << 3);
  403. PHR_BFINFO_BITS_C = (DWORD)0xFF << (RGBOrder.Order[2] << 3);
  404. DBGP_IF(DBGP_BFINFO,
  405. DBGP("24BPP Order=%ld [%ld:%ld:%ld]"
  406. ARGDW(RGBOrder.Index)
  407. ARGDW(RGBOrder.Order[0])
  408. ARGDW(RGBOrder.Order[1])
  409. ARGDW(RGBOrder.Order[2])));
  410. break;
  411. default:
  412. return(HTERR_INVALID_SRC_FORMAT);
  413. }
  414. //
  415. // This is a source surface, let's check the color table format
  416. //
  417. if (MaxColors) {
  418. if (ColorTriad.BytesPerPrimary != 1) {
  419. return(HTERR_INVALID_COLOR_TABLE_SIZE);
  420. }
  421. if (ColorTriad.BytesPerEntry < 3) {
  422. return(HTERR_INVALID_COLOR_ENTRY_SIZE);
  423. }
  424. if (ColorTriad.PrimaryOrder > PRIMARY_ORDER_MAX) {
  425. return(HTERR_INVALID_PRIMARY_ORDER);
  426. }
  427. if (!ColorTriad.pColorTable) {
  428. return(HTERR_INVALID_COLOR_TABLE);
  429. }
  430. if ((ColorTriad.ColorTableEntries > MaxColors) ||
  431. (!ColorTriad.ColorTableEntries)) {
  432. return(HTERR_INVALID_COLOR_TABLE_SIZE);
  433. }
  434. if ((ColorTriad.BytesPerPrimary != 1) ||
  435. (ColorTriad.PrimaryValueMax != 255)) {
  436. return(HTERR_INVALID_PRIMARY_VALUE_MAX);
  437. }
  438. }
  439. if (!ValidateRGBBitFields(&(pHR->BFInfo))) {
  440. return(HTERR_INVALID_COLOR_TABLE);
  441. }
  442. break;
  443. }
  444. return(1);
  445. }
  446. LONG
  447. HTENTRY
  448. ComputeBytesPerScanLine(
  449. UINT SurfaceFormat,
  450. UINT AlignmentBytes,
  451. DWORD WidthInPel
  452. )
  453. /*++
  454. Routine Description:
  455. This function calculate total bytes needed for a single scan line in the
  456. bitmap according to its format and alignment requirement.
  457. Arguments:
  458. SurfaceFormat - Surface format of the bitmap, this is must one of the
  459. standard format which defined as SURFACE_FORMAT_xxx
  460. AlignmentBytes - This is the alignment bytes requirement for one scan
  461. line, this number can be range from 0 to 65535, some
  462. common ones are:
  463. 0, 1 - Alignment in 8-bit boundary (BYTE)
  464. 2 - Alignment in 16-bit boundary (WORD)
  465. 3 - Alignment in 24-bit boundary
  466. 4 - Alignment in 32-bit boundary (DWORD)
  467. 8 - Alignment in 64-bit boundary (QWROD)
  468. WidthInPel - Total Pels per scan line in the bitmap.
  469. Return Value:
  470. The return value is the total bytes in one scan line if it is greater than
  471. zero, some error conditions may be exists when the return value is less
  472. than or equal to 0.
  473. Return Value == 0 - The WidthInPel is <= 0
  474. Return Value < 0 - Invalid Surface format is passed.
  475. Author:
  476. 14-Feb-1991 Thu 10:03:35 created -by- Daniel Chou (danielc)
  477. Revision History:
  478. --*/
  479. {
  480. DWORD BytesPerScanLine;
  481. DWORD OverhangBytes;
  482. if (WidthInPel <= 0L) {
  483. return(0L);
  484. }
  485. switch (SurfaceFormat) {
  486. case BMF_1BPP:
  487. BytesPerScanLine = (WidthInPel + 7L) >> 3;
  488. break;
  489. case BMF_4BPP_VGA16:
  490. case BMF_4BPP:
  491. BytesPerScanLine = (WidthInPel + 1) >> 1;
  492. break;
  493. case BMF_8BPP:
  494. case BMF_8BPP_VGA256:
  495. case BMF_8BPP_MONO:
  496. case BMF_8BPP_B332:
  497. case BMF_8BPP_L555:
  498. case BMF_8BPP_L666:
  499. case BMF_8BPP_K_B332:
  500. case BMF_8BPP_K_L555:
  501. case BMF_8BPP_K_L666:
  502. BytesPerScanLine = WidthInPel;
  503. break;
  504. case BMF_16BPP:
  505. case BMF_16BPP_555:
  506. case BMF_16BPP_565:
  507. BytesPerScanLine = WidthInPel << 1;
  508. break;
  509. case BMF_24BPP:
  510. BytesPerScanLine = WidthInPel + (WidthInPel << 1);
  511. break;
  512. case BMF_32BPP:
  513. BytesPerScanLine = WidthInPel << 2;
  514. break;
  515. default:
  516. return(0);
  517. }
  518. if ((AlignmentBytes <= 1) ||
  519. (!(OverhangBytes = BytesPerScanLine % (DWORD)AlignmentBytes))) {
  520. return((LONG)BytesPerScanLine);
  521. } else {
  522. return((LONG)BytesPerScanLine +
  523. (LONG)AlignmentBytes - (LONG)OverhangBytes);
  524. }
  525. }
  526. BOOL
  527. HTENTRY
  528. IntersectRECTL(
  529. PRECTL prclA,
  530. PRECTL prclB
  531. )
  532. /*++
  533. Routine Description:
  534. This function intersect prclA and prclB and write the result back to
  535. prclA, it return TRUE if two rect are intersected
  536. Arguments:
  537. Return Value:
  538. Author:
  539. 01-Apr-1998 Wed 20:41:00 created -by- Daniel Chou (danielc)
  540. Revision History:
  541. --*/
  542. {
  543. RECTL rcl;
  544. if ((rcl.left = prclA->left) < prclB->left) {
  545. rcl.left = prclB->left;
  546. }
  547. if ((rcl.top = prclA->top) < prclB->top) {
  548. rcl.top = prclB->top;
  549. }
  550. if ((rcl.right = prclA->right) > prclB->right) {
  551. rcl.right = prclB->right;
  552. }
  553. if ((rcl.bottom = prclA->bottom) > prclB->bottom) {
  554. rcl.bottom = prclB->bottom;
  555. }
  556. *prclA = rcl;
  557. return((rcl.right > rcl.left) && (rcl.bottom > rcl.top));
  558. }
  559. LONG
  560. HTENTRY
  561. ComputeByteOffset(
  562. UINT SurfaceFormat,
  563. LONG xLeft,
  564. LPBYTE pPixelInByteSkip
  565. )
  566. /*++
  567. Routine Description:
  568. Arguments:
  569. Return Value:
  570. Author:
  571. 13-Apr-1998 Mon 22:51:28 created -by- Daniel Chou (danielc)
  572. Revision History:
  573. --*/
  574. {
  575. BYTE BitOff = 0;
  576. switch (SurfaceFormat) {
  577. case BMF_1BPP:
  578. BitOff = (BYTE)(xLeft & 0x07);
  579. xLeft >>= 3;
  580. break;
  581. case BMF_4BPP_VGA16:
  582. case BMF_4BPP:
  583. BitOff = (BYTE)(xLeft & 0x01);
  584. xLeft >>= 1;
  585. break;
  586. case BMF_8BPP:
  587. case BMF_8BPP_VGA256:
  588. case BMF_8BPP_MONO:
  589. case BMF_8BPP_B332:
  590. case BMF_8BPP_L555:
  591. case BMF_8BPP_L666:
  592. case BMF_8BPP_K_B332:
  593. case BMF_8BPP_K_L555:
  594. case BMF_8BPP_K_L666:
  595. break;
  596. case BMF_16BPP:
  597. case BMF_16BPP_555:
  598. case BMF_16BPP_565:
  599. xLeft <<= 1;
  600. break;
  601. case BMF_24BPP:
  602. xLeft += (xLeft << 1);
  603. break;
  604. case BMF_32BPP:
  605. xLeft <<= 2;
  606. break;
  607. default:
  608. return(0);
  609. }
  610. *pPixelInByteSkip = BitOff;
  611. return(xLeft);
  612. }
  613. VOID
  614. GetDstBFInfo(
  615. PAAHEADER pAAHdr,
  616. PABINFO pABInfo,
  617. BYTE DstSurfFormat,
  618. BYTE DstOrder
  619. )
  620. /*++
  621. Routine Description:
  622. Arguments:
  623. Return Value:
  624. Author:
  625. 19-Feb-1999 Fri 13:37:22 created -by- Daniel Chou (danielc)
  626. Revision History:
  627. 08-Aug-2000 Tue 18:34:22 updated -by- Daniel Chou (danielc)
  628. Fixing bug for alpha blending, in gray scale mode, the destination
  629. can only be 1bpp or 8bpp mask mono, so when we read back from the
  630. destination to do alpha blending, it will double color mapping pixels.
  631. In gray scale mode, the input function will map the source RGB value
  632. to gray value with the current device transform, color adjustment and
  633. so on, so if we read back from destination then this transform is not
  634. desired.
  635. --*/
  636. {
  637. LPBYTE pbPal;
  638. BFINFO BFInfo;
  639. DWORD Tmp;
  640. ZeroMemory(&BFInfo, sizeof(BFINFO));
  641. pbPal = NULL;
  642. switch (BFInfo.BitmapFormat = (BYTE)DstSurfFormat) {
  643. case BMF_16BPP_555:
  644. BFINFO_BITS_A = 0x7c00;
  645. BFINFO_BITS_B = 0x03e0;
  646. BFINFO_BITS_C = 0x001F;
  647. break;
  648. case BMF_16BPP_565:
  649. BFINFO_BITS_A = 0xF800;
  650. BFINFO_BITS_B = 0x07e0;
  651. BFINFO_BITS_C = 0x001F;
  652. break;
  653. case BMF_24BPP:
  654. case BMF_32BPP:
  655. BFINFO_BITS_A = 0x00FF0000;
  656. BFINFO_BITS_B = 0x0000FF00;
  657. BFINFO_BITS_C = 0x000000FF;
  658. break;
  659. default:
  660. pbPal = (LPBYTE)pABInfo->pDstPal;
  661. DstOrder = (pABInfo->Flags & ABIF_DSTPAL_IS_RGBQUAD) ?
  662. PRIMARY_ORDER_BGR : PRIMARY_ORDER_RGB;
  663. break;
  664. }
  665. if (!pbPal) {
  666. if (DstOrder & COLOR_SWAP_BC) {
  667. XCHG(BFINFO_BITS_B, BFINFO_BITS_C, Tmp);
  668. }
  669. if (DstOrder & COLOR_SWAP_AB) {
  670. XCHG(BFINFO_BITS_A, BFINFO_BITS_B, Tmp);
  671. } else if (DstOrder & COLOR_SWAP_AC) {
  672. XCHG(BFINFO_BITS_A, BFINFO_BITS_C, Tmp);
  673. }
  674. ValidateRGBBitFields(&BFInfo);
  675. }
  676. ComputeInputColorInfo(pbPal,
  677. 4,
  678. DstOrder,
  679. &BFInfo,
  680. &(pAAHdr->DstSurfInfo));
  681. //
  682. // We only do this if this is a 1bpp, 8bpp devices
  683. //
  684. SetGrayColorTable(NULL, &(pAAHdr->DstSurfInfo));
  685. }
  686. LONG
  687. HTENTRY
  688. AAHalftoneBitmap(
  689. PHALFTONERENDER pHR
  690. )
  691. /*++
  692. Routine Description:
  693. This function read the 1/4/8/24 bits per pel source bitmap and composed it
  694. (compress or expand if necessary) into PRIMCOLOR data structures array for
  695. later halftone rendering.
  696. Arguments:
  697. pHalftoneRender - Pointer to the HALFTONERENDER data structure.
  698. Return Value:
  699. The return value will be < 0 if an error encountered else it will be
  700. 1L.
  701. Author:
  702. 24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
  703. Revision History:
  704. --*/
  705. {
  706. #define bm8i (*(PBM8BPPINFO)&pAAHdr->prgbLUT->ExtBGR[3])
  707. PDEVICECOLORINFO pDCI;
  708. PDEVCLRADJ pDevClrAdj;
  709. AAOUTPUTFUNC AAOutputFunc;
  710. AACYFUNC AACYFunc;
  711. AAOUTPUTINFO AAOutputInfo;
  712. PAAHEADER pAAHdr;
  713. LONG Result;
  714. BOOL IsReleaseSem;
  715. DBG_TIMER_BEG(TIMER_SETUP);
  716. pDCI = pHR->pDeviceColorInfo;
  717. pDevClrAdj = pHR->pDevClrAdj;
  718. pAAHdr = (PAAHEADER)pHR->pAAHdr;
  719. if (((Result = ValidateHTSI(pHR, VALIDATE_HTSI_SRC)) < 0) ||
  720. ((Result = ValidateHTSI(pHR, VALIDATE_HTSI_DEST)) < 0) ||
  721. ((Result = ValidateHTSI(pHR, VALIDATE_HTSI_MASK)) < 0) ||
  722. ((Result = SetupAAHeader(pHR, pDCI, pAAHdr, &AACYFunc)) <= 0)) {
  723. //================================================================
  724. // Release SEMAPHORE NOW and return error
  725. //================================================================
  726. RELEASE_HTMUTEX(pDCI->HTMutex);
  727. return(Result);
  728. }
  729. if (IsReleaseSem =
  730. (BOOL)((Result = CreateDyesColorMappingTable(pHR)) > 0)) {
  731. LPBYTE pOut;
  732. LONG cFirst;
  733. LONG BitOff;
  734. LONG cOut;
  735. RGBORDER DstOrder;
  736. DWORD AAHFlags;
  737. DWORD DCAFlags;
  738. BYTE DstSurfFmt;
  739. BYTE DMIFlags;
  740. DstSurfFmt = pDevClrAdj->DMI.CTSTDInfo.BMFDest;
  741. DMIFlags = pDevClrAdj->DMI.Flags;
  742. AAHFlags = pAAHdr->Flags;
  743. pOut = pAAHdr->DstSurfInfo.pb;
  744. cOut = pAAHdr->pAAInfoCX->cOut;
  745. DstOrder = pAAHdr->AAPI.DstOrder;
  746. DCAFlags = (DWORD)pDevClrAdj->PrimAdj.Flags;
  747. ZeroMemory(&AAOutputInfo, sizeof(AAOUTPUTINFO));
  748. if (DCAFlags & DCA_XLATE_332) {
  749. AAOutputInfo.pXlate8BPP = pDCI->CMY8BPPMask.bXlate;
  750. }
  751. if (AAHFlags & AAHF_USE_DCI_DATA) {
  752. IsReleaseSem = FALSE;
  753. DBGP_IF(DBGP_FUNC, DBGP("AAHF_USE_DCI_DATA"));
  754. if (AAHFlags & AAHF_ALPHA_BLEND) {
  755. ASSERT(pDCI->pAlphaBlendBGR);
  756. pAAHdr->pAlphaBlendBGR = pDCI->pAlphaBlendBGR;
  757. if (AAHFlags & AAHF_CONST_ALPHA) {
  758. pAAHdr->pAlphaBlendBGR += AB_BGR_SIZE;
  759. }
  760. }
  761. } else {
  762. CopyMemory(pAAHdr->prgbLUT, &(pDCI->rgbLUT), sizeof(RGBLUTAA));
  763. if (AAHFlags & AAHF_ALPHA_BLEND) {
  764. if (AAHFlags & AAHF_CONST_ALPHA) {
  765. CopyMemory(pAAHdr->pAlphaBlendBGR,
  766. (LPBYTE)(pDCI->pAlphaBlendBGR + AB_BGR_SIZE),
  767. (AB_BGR_CA_SIZE + AB_CONST_SIZE));
  768. } else {
  769. CopyMemory(pAAHdr->pAlphaBlendBGR,
  770. pDCI->pAlphaBlendBGR,
  771. AB_BGR_SIZE);
  772. }
  773. }
  774. //============================================================
  775. // Release SEMAPHORE NOW for pDCI when we halftone the output
  776. //============================================================
  777. RELEASE_HTMUTEX(pDCI->HTMutex);
  778. }
  779. if (pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY) {
  780. ASSERT((DstSurfFmt == BMF_1BPP) ||
  781. (DstSurfFmt == BMF_8BPP_MONO));
  782. SetGrayColorTable(pAAHdr->pIdxBGR, &(pAAHdr->SrcSurfInfo));
  783. }
  784. if (pAAHdr->FUDI.cbbgr) {
  785. InitializeFUDI(pAAHdr);
  786. }
  787. DBGP_IF(DBGP_FUNC,
  788. DBGP("\ncOut=%ld, pOutputBuf=%p-%p, (%ld), pOut=%p"
  789. ARGDW(cOut) ARGPTR(pAAHdr->pOutputBeg)
  790. ARGPTR(pAAHdr->pOutputEnd)
  791. ARGDW(pAAHdr->pOutputEnd - pAAHdr->pOutputBeg)
  792. ARGPTR(pOut)));
  793. --pAAHdr->pOutputBeg;
  794. switch (DstSurfFmt) {
  795. case BMF_1BPP:
  796. AAOutputInfo.bm.XorMask = (AAHFlags & AAHF_ADDITIVE) ? 0x00 : 0xFF;
  797. if (BitOff = (LONG)pAAHdr->DstSurfInfo.BitOffset) {
  798. cFirst = 8 - BitOff;
  799. if ((cOut -= cFirst) < 0) {
  800. //
  801. // Only One byte
  802. //
  803. cFirst += cOut;
  804. cOut = -cOut;
  805. AAOutputInfo.bm.LSFirst = (BYTE)cOut;
  806. cOut = 0;
  807. }
  808. AAOutputInfo.bm.cFirst = (BYTE)cFirst;
  809. }
  810. if (AAOutputInfo.bm.cLast = (BYTE)(cOut & 0x7)) {
  811. pAAHdr->pOutputEnd -= AAOutputInfo.bm.cLast;
  812. }
  813. DBGP_IF(DBGP_FUNC,
  814. DBGP("1BPP: DstBitOff=%ld, cFirst=%ld, XorMask=0x%02lx, LSFirst=%ld, cLast=%ld [%ld]"
  815. ARGDW(BitOff)
  816. ARGDW(AAOutputInfo.bm.cFirst)
  817. ARGDW(AAOutputInfo.bm.XorMask)
  818. ARGDW(AAOutputInfo.bm.LSFirst)
  819. ARGDW(AAOutputInfo.bm.cLast)
  820. ARGDW(pAAHdr->pOutputEnd - pAAHdr->pOutputBeg)));
  821. ASSERT(pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY);
  822. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo1BPP;
  823. break;
  824. case BMF_4BPP:
  825. case BMF_4BPP_VGA16:
  826. //
  827. // 4BPP do pre-increment
  828. //
  829. AAOutputInfo.bm.XorMask = (AAHFlags & AAHF_ADDITIVE) ? 0x00 : 0x77;
  830. if (pAAHdr->DstSurfInfo.BitOffset) {
  831. AAOutputInfo.bm.cFirst = 1;
  832. --cOut;
  833. }
  834. if (cOut & 0x01) {
  835. AAOutputInfo.bm.cLast = 1;
  836. --pAAHdr->pOutputEnd;
  837. }
  838. AAOutputFunc = (AAOUTPUTFUNC)((DstSurfFmt == BMF_4BPP) ?
  839. OutputAATo4BPP : OutputAAToVGA16);
  840. break;
  841. case BMF_8BPP_MONO:
  842. ASSERT(pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY);
  843. AAOutputInfo.bm.XorMask = bm8i.Data.bXor;
  844. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo8BPP_MONO;
  845. break;
  846. case BMF_8BPP_B332:
  847. AAOutputFunc = (DCAFlags & DCA_XLATE_332) ?
  848. OutputAATo8BPP_B332_XLATE :
  849. OutputAATo8BPP_B332;
  850. break;
  851. case BMF_8BPP_K_B332:
  852. AAOutputFunc = (DCAFlags & DCA_XLATE_332) ?
  853. OutputAATo8BPP_K_B332_XLATE :
  854. OutputAATo8BPP_K_B332;
  855. break;
  856. case BMF_8BPP_L555:
  857. case BMF_8BPP_L666:
  858. case BMF_8BPP_K_L555:
  859. case BMF_8BPP_K_L666:
  860. ASSERT(DCAFlags & DCA_XLATE_555_666);
  861. GET_P8BPPXLATE(AAOutputInfo.pXlate8BPP, bm8i);
  862. AAOutputFunc = (AAOUTPUTFUNC)(((DstSurfFmt == BMF_8BPP_L555) ||
  863. (DstSurfFmt == BMF_8BPP_L666)) ?
  864. OutputAATo8BPP_XLATE : OutputAATo8BPP_K_XLATE);
  865. break;
  866. case BMF_8BPP_VGA256:
  867. AAOutputInfo.pXlate8BPP = BuildVGA256Xlate(pHR->pXlate8BPP,
  868. pAAHdr->pXlate8BPP);
  869. AAOutputFunc = (AAOUTPUTFUNC)OutputAAToVGA256;
  870. break;
  871. case BMF_16BPP_555:
  872. case BMF_16BPP_565:
  873. //
  874. // Find out if we are in DWORD boundary
  875. //
  876. if ((UINT_PTR)pOut & 0x03) {
  877. AAOutputInfo.bm.cFirst = 1;
  878. --cOut;
  879. }
  880. if (cOut & 0x01) {
  881. AAOutputInfo.bm.cLast = 1;
  882. --pAAHdr->pOutputEnd;
  883. }
  884. switch (DstOrder.Index) {
  885. case PRIMARY_ORDER_RGB:
  886. AAOutputFunc = (DstSurfFmt == BMF_16BPP_555) ?
  887. (AAOUTPUTFUNC)OutputAATo16BPP_555_RGB :
  888. (AAOUTPUTFUNC)OutputAATo16BPP_565_RGB;
  889. break;
  890. case PRIMARY_ORDER_BGR:
  891. AAOutputFunc = (DstSurfFmt == BMF_16BPP_555) ?
  892. (AAOUTPUTFUNC)OutputAATo16BPP_555_BGR :
  893. (AAOUTPUTFUNC)OutputAATo16BPP_565_BGR;
  894. break;
  895. default:
  896. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo16BPP_ExtBGR;
  897. break;
  898. }
  899. break;
  900. case BMF_24BPP:
  901. AAOutputInfo.bgri.iR = DstOrder.Order[0];
  902. AAOutputInfo.bgri.iG = DstOrder.Order[1];
  903. AAOutputInfo.bgri.iB = DstOrder.Order[2];
  904. switch (AAOutputInfo.bgri.Order = DstOrder.Index) {
  905. case PRIMARY_ORDER_RGB:
  906. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo24BPP_RGB;
  907. break;
  908. case PRIMARY_ORDER_BGR:
  909. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo24BPP_BGR;
  910. break;
  911. default:
  912. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo24BPP_ORDER;
  913. break;
  914. }
  915. DBGP_IF(DBGP_FUNC,
  916. DBGP("24BPP: Order=%ld, iR=%ld, iG=%ld, iB=%ld"
  917. ARGDW(DstOrder.Index)
  918. ARGDW(AAOutputInfo.bgri.iR)
  919. ARGDW(AAOutputInfo.bgri.iG)
  920. ARGDW(AAOutputInfo.bgri.iB)));
  921. break;
  922. case BMF_32BPP:
  923. AAOutputInfo.bgri.iR = DstOrder.Order[0];
  924. AAOutputInfo.bgri.iG = DstOrder.Order[1];
  925. AAOutputInfo.bgri.iB = DstOrder.Order[2];
  926. switch (AAOutputInfo.bgri.Order = DstOrder.Index) {
  927. case PRIMARY_ORDER_RGB:
  928. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo32BPP_RGB;
  929. break;
  930. case PRIMARY_ORDER_BGR:
  931. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo32BPP_BGR;
  932. break;
  933. default:
  934. AAOutputFunc = (AAOUTPUTFUNC)OutputAATo32BPP_ORDER;
  935. break;
  936. }
  937. DBGP_IF(DBGP_FUNC,
  938. DBGP("32BPP: Order=%ld, iR=%ld, iG=%ld, iB=%ld"
  939. ARGDW(DstOrder.Index)
  940. ARGDW(AAOutputInfo.bgri.iR)
  941. ARGDW(AAOutputInfo.bgri.iG)
  942. ARGDW(AAOutputInfo.bgri.iB)));
  943. break;
  944. default:
  945. ASSERTMSG("Invalid Bitmap format", TRUE);
  946. AAOutputFunc = (AAOUTPUTFUNC)NULL;
  947. Result = HTERR_INVALID_DEST_FORMAT;
  948. break;
  949. }
  950. if (pAAHdr->AAOutputFunc = AAOutputFunc) {
  951. pAAHdr->AAOutputInfo = AAOutputInfo;
  952. if (pAAHdr->Flags & AAHF_ALPHA_BLEND) {
  953. GetDstBFInfo(pAAHdr,
  954. pHR->pBitbltParams->pABInfo,
  955. DstSurfFmt,
  956. DstOrder.Index);
  957. }
  958. DBGP_IF(DBGP_FUNC,
  959. DBGP("*%s (%p), cOut=%ld, pOut=%p-%p, (%ld), c1st=%ld, XM=%02lx, Bit1st=%02lx, cLast=%02lx, pXlate=%p"
  960. ARGPTR(GetAAOutputFuncName(AAOutputFunc))
  961. ARGPTR(AAOutputFunc)
  962. ARGDW(pAAHdr->pAAInfoCX->cOut)
  963. ARGPTR(pAAHdr->pOutputBeg)
  964. ARGPTR(pAAHdr->pOutputEnd)
  965. ARGDW(pAAHdr->pOutputEnd - pAAHdr->pOutputBeg)
  966. ARGDW(AAOutputInfo.bm.cFirst)
  967. ARGDW(AAOutputInfo.bm.XorMask)
  968. ARGDW(AAOutputInfo.bm.LSFirst)
  969. ARGDW(AAOutputInfo.bm.cLast)
  970. ARGPTR(pAAHdr->AAOutputInfo.pXlate8BPP)));
  971. DBG_TIMER_END(TIMER_SETUP);
  972. Result = AACYFunc(pAAHdr);
  973. DBG_TIMER_BEG(TIMER_SETUP);
  974. }
  975. if ((AAHFlags & AAHF_DO_CLR_MAPPING) && (pAAHdr->pBGRMapTable)) {
  976. DEREF_BGRMAPCACHE(pAAHdr->pBGRMapTable);
  977. }
  978. DBGP_IF(DBGP_AAHT_MEM,
  979. DBGP("AAHT: pHR=%ld, pDevClrAdj=%ld, pAAInfoX/Y=%ld:%ld, pAAHdr=%ld, Total=%ld"
  980. ARGDW(sizeof(HALFTONERENDER))
  981. ARGDW(sizeof(DEVCLRADJ)) ARGDW(pAAHdr->pAAInfoCX->cbAlloc)
  982. ARGDW(pAAHdr->pAAInfoCY->cbAlloc) ARGDW(pAAHdr->cbAlloc)
  983. ARGDW(sizeof(HALFTONERENDER) +
  984. sizeof(DEVCLRADJ) + pAAHdr->pAAInfoCX->cbAlloc +
  985. pAAHdr->pAAInfoCY->cbAlloc + pAAHdr->cbAlloc)));
  986. }
  987. if (!IsReleaseSem) {
  988. //============================================================
  989. // Release SEMAPHORE NOW since we did not release it yet
  990. //============================================================
  991. RELEASE_HTMUTEX(pDCI->HTMutex);
  992. }
  993. HTFreeMem(pAAHdr->pAAInfoCX);
  994. HTFreeMem(pAAHdr->pAAInfoCY);
  995. DBG_TIMER_END(TIMER_SETUP);
  996. return(Result);
  997. #undef bm8i
  998. }