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.

4777 lines
143 KiB

  1. /*++
  2. Copyright (c) 1990-1991 Microsoft Corporation
  3. Module Name:
  4. htmapclr.c
  5. Abstract:
  6. This module contains low levels functions which map the input color to
  7. the dyes' densities.
  8. Author:
  9. 29-Jan-1991 Tue 10:28:20 created -by- Daniel Chou (danielc)
  10. [Environment:]
  11. GDI Device Driver - Halftone.
  12. [Notes:]
  13. 1. In the near future we will also allowed the XYZ/LAB to be specified in
  14. the color table
  15. Revision History:
  16. --*/
  17. #define DBGP_VARNAME dbgpHTMapClr
  18. #include "htp.h"
  19. #include "htmapclr.h"
  20. #include "htrender.h"
  21. #include "htmath.h"
  22. #include "htapi.h"
  23. #include "htpat.h"
  24. #include "htalias.h"
  25. #define DBGP_SHOWXFORM_RGB 0x00000001
  26. #define DBGP_SHOWXFORM_ALL 0x00000002
  27. #define DBGP_CIEMATRIX 0x00000004
  28. #define DBGP_CSXFORM 0x00000008
  29. #define DBGP_CCT 0x00000010
  30. #define DBGP_DYE_CORRECT 0x00000020
  31. #define DBGP_HCA 0x00000040
  32. #define DBGP_PRIMARY_ORDER 0x00000080
  33. #define DBGP_CACHED_GAMMA 0x00000100
  34. #define DBGP_RGBLUTAA 0x00000200
  35. #define DBGP_SCALE_RGB 0x00000400
  36. #define DBGP_MONO_PRIM 0x00000800
  37. #define DBGP_PRIMADJFLAGS 0x00001000
  38. #define DBGP_CELLGAMMA 0x00002000
  39. #define DBGP_CONST_ALPHA 0x00004000
  40. #define DBGP_BGRMAPTABLE 0x00008000
  41. DEF_DBGPVAR(BIT_IF(DBGP_SHOWXFORM_RGB, 0) |
  42. BIT_IF(DBGP_SHOWXFORM_ALL, 0) |
  43. BIT_IF(DBGP_CIEMATRIX, 0) |
  44. BIT_IF(DBGP_CSXFORM, 0) |
  45. BIT_IF(DBGP_CCT, 0) |
  46. BIT_IF(DBGP_DYE_CORRECT, 0) |
  47. BIT_IF(DBGP_HCA, 0) |
  48. BIT_IF(DBGP_PRIMARY_ORDER, 0) |
  49. BIT_IF(DBGP_CACHED_GAMMA, 0) |
  50. BIT_IF(DBGP_RGBLUTAA, 0) |
  51. BIT_IF(DBGP_SCALE_RGB, 0) |
  52. BIT_IF(DBGP_MONO_PRIM, 0) |
  53. BIT_IF(DBGP_PRIMADJFLAGS, 0) |
  54. BIT_IF(DBGP_CELLGAMMA, 0) |
  55. BIT_IF(DBGP_CONST_ALPHA, 0) |
  56. BIT_IF(DBGP_BGRMAPTABLE, 0))
  57. extern HTCOLORADJUSTMENT DefaultCA;
  58. extern CONST LPBYTE p8BPPXlate[];
  59. extern HTGLOBAL HTGlobal;
  60. #define FD6_p25 (FD6_5 / 2)
  61. #define FD6_p75 (FD6_p25 * 3)
  62. #define JND_ADJ(j,x) RaisePower((j), (FD6)(x), RPF_INTEXP)
  63. #define FD6_p1125 (FD6)112500
  64. #define FD6_p225 (FD6)225000
  65. #define FD6_p325 (FD6)325000
  66. #define FD6_p55 (FD6)550000
  67. #define FD6_p775 (FD6)775000
  68. const FD6 SinNumber[] = {
  69. 0, 17452, 34899, 52336, 69756, // 0
  70. 87156, 104528, 121869, 139173, 156434, // 5.0
  71. 173648, 190809, 207912, 224951, 241922, // 10
  72. 258819, 275637, 292372, 309017, 325568, // 15.0
  73. 342020, 358368, 374607, 390731, 406737, // 20
  74. 422618, 438371, 453990, 469472, 484810, // 25.0
  75. 500000, 515038, 529919, 544639, 559193, // 30
  76. 573576, 587785, 601815, 615661, 629320, // 35.0
  77. 642788, 656059, 669131, 681998, 694658, // 40
  78. 707107, 719340, 731354, 743145, 754710, // 45.0
  79. 766044, 777146, 788011, 798636, 809017, // 50
  80. 819152, 829038, 838671, 848048, 857167, // 55.0
  81. 866025, 874620, 882948, 891007, 898794, // 60
  82. 906308, 913545, 920505, 927184, 933580, // 65.0
  83. 939693, 945519, 951057, 956305, 961262, // 70
  84. 965926, 970296, 974370, 978148, 981627, // 75.0
  85. 984808, 987688, 990268, 992546, 994522, // 80
  86. 996195, 997564, 998630, 999391, 999848, // 85.0
  87. 1000000
  88. };
  89. #define CLAMP_0(x) if ((x) < FD6_0) { (x) = FD6_0; }
  90. #define CLAMP_1(x) if ((x) > FD6_1) { (x) = FD6_1; }
  91. #define CLAMP_01(x) CLAMP_0(x) else CLAMP_1(x)
  92. #define CLAMP_PRIMS_0(a,b,c) CLAMP_0(a); CLAMP_0(b); CLAMP_0(c)
  93. #define CLAMP_PRIMS_1(a,b,c) CLAMP_1(a); CLAMP_1(b); CLAMP_1(c)
  94. #define CLAMP_PRIMS_01(a,b,c) CLAMP_01(a); CLAMP_01(b); CLAMP_01(c)
  95. FD6 LogFilterMax = 0;
  96. #if 0
  97. #define LOG_FILTER_RATIO 4
  98. #else
  99. #define LOG_FILTER_RATIO 7
  100. #endif
  101. #define LOG_FILTER_POWER (FD6)1200000
  102. #define PRIM_LOG_RATIO(p) Log(FD6xL((p), LOG_FILTER_RATIO) + FD6_1)
  103. #define PRIM_CONTRAST(p,adj) (p)=MulFD6((p), (adj).Contrast)
  104. #define PRIM_BRIGHTNESS(p,adj) (p)+=((adj).Brightness)
  105. #define PRIM_COLORFULNESS(a,b,adj) (a)=MulFD6((a),(adj).Color); \
  106. (b)=MulFD6((b),(adj).Color)
  107. #define PRIM_TINT(a,b,t,adj) (t)=(a); \
  108. (a)=MulFD6((a),(adj).TintCosAngle) - \
  109. MulFD6((b),(adj).TintSinAngle); \
  110. (b)=MulFD6((t),(adj).TintSinAngle) + \
  111. MulFD6((b),(adj).TintCosAngle)
  112. #if 0
  113. #define PRIM_LOG_FILTER(p) \
  114. (p)=FD6_1-Power(FD6_1-DivFD6(PRIM_LOG_RATIO(p),LogFilterMax),LOG_FILTER_POWER)
  115. #else
  116. #define PRIM_LOG_FILTER(p) (p)=DivFD6(PRIM_LOG_RATIO(p),LogFilterMax)
  117. #endif
  118. #define PRIM_BW_ADJ(p,adj) \
  119. { \
  120. if ((p) <= (adj).MinL) { \
  121. \
  122. (p) = MulFD6(p, (adj).MinLMul); \
  123. \
  124. } else if ((p) >= (adj).MaxL) { \
  125. \
  126. (p) = HT_W_REF_BASE + MulFD6((p)-(adj).MaxL, (adj).MaxLMul); \
  127. \
  128. } else { \
  129. \
  130. (p) = HT_K_REF_BASE + MulFD6((p)-(adj).MinL, (adj).RangeLMul); \
  131. } \
  132. }
  133. #define COMP_CA(pca1,pca2) CompareMemory((LPBYTE)(pca1), \
  134. (LPBYTE)(pca2), \
  135. sizeof(HTCOLORADJUSTMENT))
  136. #define ADJ_CA(a,min,max) if (a < min) { a = min; } else \
  137. if (a > max) { a = max; }
  138. #define GET_CHECKSUM(c, f) (c)=ComputeChecksum((LPBYTE)&(f),(c),sizeof(f))
  139. #define PRIM_GAMMA_ADJ(p,g) (p)=Power((p),(g))
  140. #define NO_NEGATIVE_RGB_SCALE 0
  141. #if NO_NEGATIVE_RGB_SCALE
  142. #define SCALE_PRIM_RGB(pPrim,py) ScaleRGB((pPrim))
  143. #else
  144. #define SCALE_PRIM_RGB(pPrim,py) ScaleRGB((pPrim), (py))
  145. #endif
  146. #define SET_CACHED_CMI_CA(ca) \
  147. { \
  148. (ca).caFlags &= ~(CLRADJF_LOG_FILTER | \
  149. CLRADJF_NEGATIVE); \
  150. (ca).caRedGamma = \
  151. (ca).caGreenGamma = \
  152. (ca).caBlueGamma = 0; \
  153. (ca).caReferenceBlack = 0x1234; \
  154. (ca).caReferenceWhite = 0x5678; \
  155. (ca).caContrast = (SHORT)0xABCD; \
  156. (ca).caBrightness = (SHORT)0xFFFF; \
  157. }
  158. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  159. //
  160. // The following macros used in Color space transform functions, these macros
  161. // are used to compute CIELAB X/Xw, Y/Yw, Z/Zw when its values is less
  162. // than 0.008856
  163. //
  164. // 1/3
  165. // fX = (X/RefXw) - (16/116) (X/RefXw) > 0.008856
  166. // fX = 7.787 x (X/RefXw) (X/RefXw) <= 0.008856
  167. //
  168. // 1/3
  169. // fY = (Y/RefYw) - (16/116) (Y/RefYw) > 0.008856
  170. // fY = 7.787 x (Y/RefYw) (Y/RefYw) <= 0.008856
  171. //
  172. // 1/3
  173. // fZ = (Z/RefZw) - (16/116) (Z/RefZw) > 0.008856
  174. // fZ = 7.787 x (Z/RefZw) (Z/RefZw) <= 0.008856
  175. //
  176. //
  177. // 1/3
  178. // Thresholds at 0.008856 - (16/116) = 0.068962
  179. // 7.787 x 0.008856 = 0.068962
  180. //
  181. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  182. #define NORM_XYZ(xyz, w) (FD6)(((w)==FD6_1) ? (xyz) : DivFD6((xyz), (w)))
  183. #define fXYZFromXYZ(f,n,w) (f) = ((((f)=NORM_XYZ((n),(w))) >= FD6_p008856) ? \
  184. (CubeRoot((f))) : \
  185. (MulFD6((f), FD6_7p787) + FD6_16Div116))
  186. #define XYZFromfXYZ(n,f,w) (n)=((f)>(FD6)206893) ? \
  187. (Cube((f))) : \
  188. (DivFD6((f) - FD6_16Div116, FD6_7p787)); \
  189. if ((w)!=FD6_1) { (n)=MulFD6((n),(w)); }
  190. //
  191. // Following #defines are used in ComputeColorSpaceXForm, XFormRGB_XYZ_UCS()
  192. // and XFormUCS_XYZ_RGB() functions for easy referenced.
  193. //
  194. #define CSX_AUw(XForm) XForm.AUw
  195. #define CSX_BVw(XForm) XForm.BVw
  196. #define CSX_RefXw(XForm) XForm.WhiteXYZ.X
  197. #define CSX_RefYw(XForm) FD6_1
  198. #define CSX_RefZw(XForm) XForm.WhiteXYZ.Z
  199. #define iAw CSX_AUw(pDevClrAdj->PrimAdj.rgbCSXForm)
  200. #define iBw CSX_BVw(pDevClrAdj->PrimAdj.rgbCSXForm)
  201. #define iUw CSX_AUw(pDevClrAdj->PrimAdj.rgbCSXForm)
  202. #define iVw CSX_BVw(pDevClrAdj->PrimAdj.rgbCSXForm)
  203. #define iRefXw CSX_RefXw(pDevClrAdj->PrimAdj.rgbCSXForm)
  204. #define iRefYw CSX_RefYw(pDevClrAdj->PrimAdj.rgbCSXForm)
  205. #define iRefZw CSX_RefZw(pDevClrAdj->PrimAdj.rgbCSXForm)
  206. #define oAw CSX_AUw(pDevClrAdj->PrimAdj.DevCSXForm)
  207. #define oBw CSX_BVw(pDevClrAdj->PrimAdj.DevCSXForm)
  208. #define oUw CSX_AUw(pDevClrAdj->PrimAdj.DevCSXForm)
  209. #define oVw CSX_BVw(pDevClrAdj->PrimAdj.DevCSXForm)
  210. #define oRefXw CSX_RefXw(pDevClrAdj->PrimAdj.DevCSXForm)
  211. #define oRefYw CSX_RefYw(pDevClrAdj->PrimAdj.DevCSXForm)
  212. #define oRefZw CSX_RefZw(pDevClrAdj->PrimAdj.DevCSXForm)
  213. CONST CIExy2 StdIlluminant[ILLUMINANT_MAX_INDEX] = {
  214. { (UDECI4)4476, (UDECI4)4074 }, // A Tungsten
  215. { (UDECI4)3489, (UDECI4)3520 }, // B Noon Sun
  216. { (UDECI4)3101, (UDECI4)3162 }, // C NTSC
  217. { (UDECI4)3457, (UDECI4)3585 }, // D50 Plain Paper
  218. { (UDECI4)3324, (UDECI4)3474 }, // D55 White Bond Paper
  219. { (UDECI4)3127, (UDECI4)3290 }, // D65 Standard Sun
  220. { (UDECI4)2990, (UDECI4)3149 }, // D75 Northern Sun
  221. { (UDECI4)3721, (UDECI4)3751 } // F2 Cool White
  222. };
  223. CONST REGDATA RegData[] = {
  224. { 9,251,35000,950000,100840336,68627450,31372549,100745314,40309045 },
  225. { 8,249,45000,930000, 69716775,66386554,33613445,101097041,42542759 },
  226. { 7,247,55000,910000, 49910873,65141612,34858387,101555706,44600305 },
  227. { 6,245,65000,890000, 36199095,64349376,35650623,102121877,46557500 },
  228. { 5,243,75000,870000, 26143790,63800904,36199095,102799050,48461978 },
  229. { 4,241,85000,850000, 18454440,63398692,36601307,103595587,50361904 },
  230. { 3,239,95000,830000, 12383900,63091118,36908881,104537807,52367907 }
  231. };
  232. //
  233. //
  234. // REG_L_MIN = 0.075
  235. // REG_L_MAX = 0.8500
  236. // REG_D255MIN = 7
  237. // REG_D255MAX = 248 (255 - 7)
  238. //
  239. // iP 7
  240. // REG_DMIN_MUL = ------- * -----
  241. // 0.075 255
  242. //
  243. // = iP * 0.366013
  244. // = (iP * 36.601307) / 100
  245. //
  246. //
  247. // 248 iP - 0.8500 7
  248. // REG_DMAX_MUL = ----- + ( ------------- * ----- )
  249. // 255 0.1500 255
  250. //
  251. // = 0.972549 + (0.183007 * iP) - 0.155556
  252. // = 0.816993 + (0.183007 * iP)
  253. // ~~~~~~~~ ~~~~~~~~
  254. // = (81.699346 + (18.300654 * iP)) / 100;
  255. //
  256. //
  257. //
  258. // 7 X - RegLogSub 241
  259. // REG_DEN_MUL = ----- + ((--------------- ) * ----- )
  260. // 255 RegLogRange 255
  261. //
  262. // 7 X - RegLogSub 241
  263. // = ----- + ((--------------- ) * ----- )
  264. // 255 RegLogRange 255
  265. //
  266. // 7 X - -2.080771 241
  267. // = ----- + ((--------------- ) * ----- )
  268. // 255 1.900361 255
  269. //
  270. // 7 X + 2.080771 241
  271. // = ----- + ((-------------- ) * ----- )
  272. // 255 1.900361 255
  273. //
  274. // 7 X + 2.080771 241
  275. // = ----- + ((-------------- ) * ----- )
  276. // 255 1.900361 255
  277. //
  278. // = 0.027451 + (( X + 2.080771) * 0.49736)
  279. // = 0.027451 + ( 0.49736X + 1.034820)
  280. // = 0.027451 + 0.49736X + 1.034820
  281. // = 0.497326X + 1.062271
  282. // = (49.732555 X + 106.227145) / 100
  283. //
  284. //
  285. // X = Log(CIE_L2I(iP)),
  286. // RegLogMin = Log(CIE_L2I(REG_L_MIN)) = Log(CIE_L2I(0.075)) = -2.080771
  287. // RegLogMax = Log(CIE_L2I(REG_L_MAX)) = Log(CIE_L2I(0.85)) = -0.180410
  288. // RegLogSub = -2.080771
  289. // RegLogRange = -0.180410 - -2.080771 = 1.900361
  290. //
  291. //
  292. // Standard Illuminant Coordinates and its tristimulus values
  293. //
  294. // Illuminant x y X Y Z
  295. //------------ ---------- ---------- --------- --------- ---------
  296. // EQU 0.333333 0.333333 100.000 100.000 100.000
  297. // A 0.447573 0.407440 109.850 100.000 35.585
  298. // B 0.348904 0.352001 99.120 100.000 84.970
  299. // C 0.310061 0.316150 98.074 100.000 118.232
  300. // D50 0.345669 0.358496 96.422 100.000 82.521
  301. // D55 0.332424 0.347426 95.682 100.000 92.149
  302. // D65 0.312727 0.329023 95.047 100.000 108.883
  303. // D75 0.299021 0.314852 94.972 100.000 122.638
  304. // F2 0.372069 0.375119 99.187 100.000 67.395
  305. // F7 0.312852 0.329165 95.044 100.000 108.755
  306. // F11 0.380521 0.376881 100.966 100.000 64.370
  307. //-----------------------------------------------------------------
  308. //
  309. //
  310. // This is the Source RGB order in Halftone's order, ORDER_ABC, where A is
  311. // lowest memory location and C is the highest memory location
  312. //
  313. const RGBORDER SrcOrderTable[PRIMARY_ORDER_MAX + 1] = {
  314. { PRIMARY_ORDER_RGB, { 0, 1, 2 } },
  315. { PRIMARY_ORDER_RBG, { 0, 2, 1 } },
  316. { PRIMARY_ORDER_GRB, { 1, 0, 2 } },
  317. { PRIMARY_ORDER_GBR, { 2, 0, 1 } },
  318. { PRIMARY_ORDER_BGR, { 2, 1, 0 } },
  319. { PRIMARY_ORDER_BRG, { 1, 2, 0 } }
  320. };
  321. //
  322. // This is the destination RGB order in Halftone's order, ORDER_ABC, where C is
  323. // lowest memory location and A is the highest memory location
  324. //
  325. const RGBORDER DstOrderTable[PRIMARY_ORDER_MAX + 1] = {
  326. { PRIMARY_ORDER_RGB, { 2, 1, 0 } },
  327. { PRIMARY_ORDER_RBG, { 2, 0, 1 } },
  328. { PRIMARY_ORDER_GRB, { 1, 2, 0 } },
  329. { PRIMARY_ORDER_GBR, { 0, 2, 1 } },
  330. { PRIMARY_ORDER_BGR, { 0, 1, 2 } },
  331. { PRIMARY_ORDER_BRG, { 1, 0, 2 } }
  332. };
  333. #define SRC_BF_HT_RGB 0
  334. #define SRC_TABLE_BYTE 1
  335. #define SRC_TABLE_WORD 2
  336. #define SRC_TABLE_DWORD 3
  337. #if DBG
  338. const LPBYTE pCBFLUTName[] = { "CBFLI_16_MONO",
  339. "CBFLI_24_MONO",
  340. "CBFLI_32_MONO",
  341. "CBFLI_16_COLOR",
  342. "CBFLI_24_COLOR",
  343. "CBFLI_32_COLOR" };
  344. const LPBYTE pSrcPrimTypeName[] = { "SRC_BF_HT_RGB",
  345. "SRC_TABLE_BYTE",
  346. "SRC_TABLE_WORD",
  347. "SRC_TABLE_DWORD" };
  348. const LPBYTE pDbgCSName[] = { "LUV", "LAB" };
  349. const LPBYTE pDbgCMIName[] = { "TABLE:MONO", "TABLE:COLOR",
  350. "HT555:MONO", "HT555:COLOR" };
  351. #endif
  352. DWORD dwABPreMul[256] = { 0xFFFFFFFF };
  353. VOID
  354. GenCMYMaskXlate(
  355. LPBYTE pbXlate,
  356. BOOL CMYInverted,
  357. LONG cC,
  358. LONG cM,
  359. LONG cY
  360. )
  361. /*++
  362. Routine Description:
  363. This function generate xlate table for 332 format which CMYMask Mode 3-255
  364. Arguments:
  365. Return Value:
  366. Author:
  367. 08-Sep-2000 Fri 17:57:02 created -by- Daniel Chou (danielc)
  368. Revision History:
  369. --*/
  370. {
  371. LONG iC;
  372. LONG iM;
  373. LONG iY;
  374. LONG IdxDup;
  375. LONG Clr;
  376. LONG MaxC;
  377. LONG MaxM;
  378. LONG MaxIdx;
  379. LONG IdxC;
  380. LONG IdxM;
  381. LONG IdxY;
  382. MaxC = (cM + 1) * (cY + 1);
  383. MaxM = (cY + 1);
  384. MaxIdx = (cC + 1) * (cM + 1) * (cY + 1);
  385. if ((MaxIdx >= 1) && (MaxIdx <= 256) && (CMYInverted)) {
  386. if (MaxIdx & 0x01) {
  387. IdxDup = MaxIdx / 2;
  388. ++MaxIdx;
  389. } else {
  390. IdxDup = 0x200;
  391. }
  392. MaxIdx += ((256 - MaxIdx) / 2) - 1;
  393. for (iC = 0, IdxC = -MaxC; iC <= 7; iC++) {
  394. if (iC <= cC) {
  395. IdxC += MaxC;
  396. }
  397. for (iM = 0, IdxM = -MaxM; iM <= 7; iM++) {
  398. if (iM <= cM) {
  399. IdxM += MaxM;
  400. }
  401. for (iY = 0, IdxY = -1; iY <= 3; iY++) {
  402. if (iY <= cY) {
  403. ++IdxY;
  404. }
  405. if ((Clr = IdxC + IdxM + IdxY) > IdxDup) {
  406. ++Clr;
  407. }
  408. *pbXlate++ = (BYTE)(MaxIdx - Clr);
  409. }
  410. }
  411. }
  412. } else {
  413. for (iC = 0; iC < 256; iC++) {
  414. *pbXlate++ = (BYTE)iC;
  415. }
  416. }
  417. }
  418. VOID
  419. HTENTRY
  420. TintAngle(
  421. LONG TintAdjust,
  422. LONG AngleStep,
  423. PFD6 pSin,
  424. PFD6 pCos
  425. )
  426. /*++
  427. Routine Description:
  428. This function return a sin/cos number for the tint adjust, these returned
  429. numbers are used to rotate the color space.
  430. Arguments:
  431. TintAdjust - Range from -100 to 100
  432. AngleStep - Range from 1 to 10
  433. pSin - Pointer to a FD6 number to store the SIN result
  434. pCos - Pointer to a FD6 number to store the COS result
  435. Return Value:
  436. no return value, but the result is stored in pSin/pCos
  437. Author:
  438. 13-Mar-1992 Fri 15:58:30 created -by- Daniel Chou (danielc)
  439. Revision History:
  440. --*/
  441. {
  442. LONG Major;
  443. LONG Minor;
  444. BOOL PosSin;
  445. BOOL PosCos = TRUE;
  446. FD6 Sin;
  447. FD6 Cos;
  448. if (PosSin = (BOOL)(TintAdjust <= 0)) {
  449. if (!(TintAdjust = (LONG)-TintAdjust)) {
  450. *pSin = *pCos = (FD6)0;
  451. return;
  452. }
  453. }
  454. if (TintAdjust > 100) {
  455. TintAdjust = 100;
  456. }
  457. if ((AngleStep < 1) || (AngleStep > 10)) {
  458. AngleStep = 10;
  459. }
  460. if ((TintAdjust *= AngleStep) >= 900) {
  461. TintAdjust = 1800L - TintAdjust;
  462. PosCos = FALSE;
  463. }
  464. //
  465. // Compute the Sin portion
  466. //
  467. Major = TintAdjust / 10L;
  468. Minor = TintAdjust % 10L;
  469. Sin = SinNumber[Major];
  470. if (Minor) {
  471. Sin += (FD6)((((LONG)(SinNumber[Major+1] - Sin) * Minor) + 5L) / 10L);
  472. }
  473. *pSin = (PosSin) ? Sin : -Sin;
  474. //
  475. // Compute the cosine portion
  476. //
  477. if (Minor) {
  478. Minor = 10 - Minor;
  479. ++Major;
  480. }
  481. Major = 90 - Major;
  482. Cos = SinNumber[Major];
  483. if (Minor) {
  484. Cos += (FD6)((((LONG)(SinNumber[Major+1] - Cos) * Minor) + 5L) / 10L);
  485. }
  486. *pCos = (PosCos) ? Cos : -Cos;
  487. }
  488. #define DO_DEST_GAMMA 1
  489. #define DO_SS_GAMMA 0
  490. BOOL
  491. HTENTRY
  492. AdjustSrcDevGamma(
  493. PDEVICECOLORINFO pDCI,
  494. PPRIMADJ pPrimAdj,
  495. PHTCOLORADJUSTMENT pca,
  496. BYTE DestSurfFormat,
  497. WORD AdjForceFlags
  498. )
  499. /*++
  500. Routine Description:
  501. Arguments:
  502. Return Value:
  503. Author:
  504. 29-Jan-1997 Wed 12:34:13 created -by- Daniel Chou (danielc)
  505. Revision History:
  506. --*/
  507. {
  508. FD6 SrcGamma[3];
  509. FD6 DevGamma[3];
  510. FD6 PelGamma;
  511. DWORD Flags;
  512. BOOL Changed;
  513. Changed = FALSE;
  514. Flags = 0;
  515. SrcGamma[0] = DivFD6((FD6)pca->caRedGamma, (FD6)HT_DEF_RGB_GAMMA);
  516. SrcGamma[1] = DivFD6((FD6)pca->caGreenGamma, (FD6)HT_DEF_RGB_GAMMA);
  517. SrcGamma[2] = DivFD6((FD6)pca->caBlueGamma, (FD6)HT_DEF_RGB_GAMMA);
  518. PelGamma = FD6_1;
  519. pPrimAdj->Flags &= ~DCA_DO_DEVCLR_XFORM;
  520. if (AdjForceFlags & ADJ_FORCE_ICM) {
  521. Flags |= DCA_HAS_ICM;
  522. DevGamma[0] =
  523. DevGamma[1] =
  524. DevGamma[2] = FD6_1;
  525. //
  526. // ??? LATER - We may have to turn off ALL gamma correction here
  527. //
  528. DBGP_IF(DBGP_CELLGAMMA, DBGP("--- DCA_HAS_ICM ---"));
  529. } else {
  530. FD6 GammaMul = FD6_1;
  531. if (pDCI->Flags & DCIF_ADDITIVE_PRIMS) {
  532. //
  533. // Screen Devices
  534. //
  535. switch (DestSurfFormat) {
  536. case BMF_1BPP:
  537. case BMF_4BPP:
  538. case BMF_4BPP_VGA16:
  539. //
  540. // Since we only have two levels (on/off) we will simulate the
  541. // 16bpp's darker output
  542. //
  543. DevGamma[0] =
  544. DevGamma[1] =
  545. DevGamma[2] = 1325000;
  546. pca->caReferenceBlack += 550;
  547. pca->caReferenceWhite -= 300;
  548. break;
  549. case BMF_8BPP_VGA256:
  550. DevGamma[0] =
  551. DevGamma[1] =
  552. DevGamma[2] = (FD6)1025000;
  553. break;
  554. case BMF_16BPP_555:
  555. case BMF_16BPP_565:
  556. case BMF_24BPP:
  557. case BMF_32BPP:
  558. DevGamma[0] =
  559. DevGamma[1] =
  560. DevGamma[2] = (FD6)1000000;
  561. break;
  562. break;
  563. default:
  564. return(FALSE);
  565. }
  566. } else {
  567. FD6 CellSubGamma = GET_REG_GAMMA(pDCI->ClrXFormBlock.RegDataIdx);
  568. #if DO_DEST_GAMMA
  569. CopyMemory(DevGamma, pDCI->ClrXFormBlock.DevGamma, sizeof(DevGamma));
  570. #else
  571. SrcGamma[0] = MulFD6(SrcGamma[0], pDCI->ClrXFormBlock.DevGamma[0]);
  572. SrcGamma[1] = MulFD6(SrcGamma[1], pDCI->ClrXFormBlock.DevGamma[1]);
  573. SrcGamma[2] = MulFD6(SrcGamma[2], pDCI->ClrXFormBlock.DevGamma[2]);
  574. DevGamma[0] =
  575. DevGamma[1] =
  576. DevGamma[2] = FD6_1;
  577. #endif
  578. //
  579. // Printer Devices
  580. //
  581. pPrimAdj->Flags |= DCA_DO_DEVCLR_XFORM;
  582. if (pDCI->HTCell.HTPatIdx <= HTPAT_SIZE_16x16_M) {
  583. GammaMul = FD6_1 +
  584. FD6xL(((pDCI->HTCell.HTPatIdx >> 1) + 1), 25000);
  585. if (DestSurfFormat == BMF_1BPP) {
  586. DBGP_IF(DBGP_CELLGAMMA,
  587. DBGP("1BPP: HTPatIdx=%ld, GammaMul=%s --> %s"
  588. ARGDW(pDCI->HTCell.HTPatIdx)
  589. ARGFD6(GammaMul, 1, 6)
  590. ARGFD6(MulFD6(GammaMul, 1125000), 1, 6)));
  591. GammaMul = MulFD6(GammaMul, 1125000);
  592. }
  593. }
  594. if (pDCI->DevPelRatio > FD6_1) {
  595. PelGamma = DivFD6(-477121,
  596. Log(DivFD6(333333, pDCI->DevPelRatio)));
  597. } else if (pDCI->DevPelRatio < FD6_1) {
  598. PelGamma = DivFD6(Log(pDCI->DevPelRatio / 3), -477121);
  599. }
  600. switch (DestSurfFormat) {
  601. case BMF_1BPP:
  602. case BMF_4BPP:
  603. case BMF_4BPP_VGA16:
  604. break;
  605. case BMF_8BPP_VGA256:
  606. if ((pDCI->Flags & (DCIF_USE_8BPP_BITMASK |
  607. DCIF_MONO_8BPP_BITMASK)) ==
  608. DCIF_USE_8BPP_BITMASK) {
  609. DBGP_IF(DBGP_CELLGAMMA,
  610. DBGP("Mask 8BPP, Reset PelGamma=FD6_1, CellSubGamma=%s --> %s"
  611. ARGFD6(CellSubGamma, 1, 6)
  612. ARGFD6(DivFD6(CellSubGamma, MASK8BPP_GAMMA_DIV), 1, 6)));
  613. CellSubGamma = DivFD6(CellSubGamma, MASK8BPP_GAMMA_DIV);
  614. PelGamma = FD6_1;
  615. }
  616. break;
  617. case BMF_16BPP_555:
  618. case BMF_16BPP_565:
  619. case BMF_24BPP:
  620. case BMF_32BPP:
  621. if (!(pDCI->Flags & DCIF_DO_DEVCLR_XFORM)) {
  622. pPrimAdj->Flags &= ~DCA_DO_DEVCLR_XFORM;
  623. CellSubGamma = FD6_1;
  624. break;
  625. }
  626. break;
  627. default:
  628. return(FALSE);
  629. }
  630. DBGP_IF(DBGP_CELLGAMMA,
  631. DBGP("Res=%ldx%ld, , PelRatio=%s, PelGamma=%s"
  632. ARGDW(pDCI->DeviceResXDPI) ARGDW(pDCI->DeviceResYDPI)
  633. ARGFD6(pDCI->DevPelRatio, 1, 6) ARGFD6(PelGamma, 1, 6)));
  634. DBGP_IF(DBGP_CELLGAMMA,
  635. DBGP("HTPatIdx=%ld, CellSubGamma=%s, SUB GammaMul=%s"
  636. ARGDW(pDCI->HTCell.HTPatIdx)
  637. ARGFD6(CellSubGamma, 1, 6)
  638. ARGFD6(GammaMul, 1, 6)));
  639. GammaMul = MulFD6(GammaMul, CellSubGamma);
  640. #if DO_SS_GAMMA
  641. if (pDCI->Flags & (DCIF_SUPERCELL | DCIF_SUPERCELL_M)) {
  642. DBGP_IF(DBGP_CELLGAMMA,
  643. DBGP("SM: Gamma: %s:%s:%s --> %s:%s:%s"
  644. ARGFD6(SrcGamma[0], 1, 6)
  645. ARGFD6(SrcGamma[1], 1, 6)
  646. ARGFD6(SrcGamma[2], 1, 6)
  647. ARGFD6(MulFD6(SrcGamma[0], SCM_R_GAMMA_MUL), 1, 6)
  648. ARGFD6(MulFD6(SrcGamma[1], SCM_G_GAMMA_MUL), 1, 6)
  649. ARGFD6(MulFD6(SrcGamma[2], SCM_B_GAMMA_MUL), 1, 6)));
  650. SrcGamma[0] = MulFD6(SrcGamma[0], SCM_R_GAMMA_MUL);
  651. SrcGamma[1] = MulFD6(SrcGamma[1], SCM_G_GAMMA_MUL);
  652. SrcGamma[2] = MulFD6(SrcGamma[2], SCM_B_GAMMA_MUL);
  653. }
  654. #endif
  655. }
  656. SrcGamma[0] = MulFD6(SrcGamma[0], GammaMul);
  657. SrcGamma[1] = MulFD6(SrcGamma[1], GammaMul);
  658. SrcGamma[2] = MulFD6(SrcGamma[2], GammaMul);
  659. DBGP_IF(DBGP_CELLGAMMA,
  660. DBGP("Gamma: Src=%s:%s:%s, Dev=%s:%s:%s, Pel=%s, Mul=%s"
  661. ARGFD6(SrcGamma[0], 1, 6)
  662. ARGFD6(SrcGamma[1], 1, 6)
  663. ARGFD6(SrcGamma[2], 1, 6)
  664. ARGFD6(DevGamma[0], 1, 6)
  665. ARGFD6(DevGamma[1], 1, 6)
  666. ARGFD6(DevGamma[2], 1, 6)
  667. ARGFD6(PelGamma, 1, 6)
  668. ARGFD6(GammaMul, 1, 6)));
  669. DBGP_IF(DBGP_CELLGAMMA,
  670. DBGP("Source Gamma=%s:%s:%s, PelGamma=%s"
  671. ARGFD6(SrcGamma[0], 1, 6) ARGFD6(SrcGamma[1], 1, 6)
  672. ARGFD6(SrcGamma[2], 1, 6) ARGFD6(PelGamma, 1, 6)));
  673. if (PelGamma != FD6_1) {
  674. DevGamma[0] = MulFD6(DevGamma[0], PelGamma);
  675. DevGamma[1] = MulFD6(DevGamma[1], PelGamma);
  676. DevGamma[2] = MulFD6(DevGamma[2], PelGamma);
  677. DBGP_IF(DBGP_CELLGAMMA,
  678. DBGP("DevGamma=%s:%s:%s, PelGamma=%s"
  679. ARGFD6(DevGamma[0], 1, 6) ARGFD6(DevGamma[1], 1, 6)
  680. ARGFD6(DevGamma[2], 1, 6) ARGFD6(PelGamma, 1, 6)));
  681. }
  682. }
  683. if ((SrcGamma[0] != FD6_1) ||
  684. (SrcGamma[1] != FD6_1) ||
  685. (SrcGamma[2] != FD6_1)) {
  686. Flags |= DCA_HAS_SRC_GAMMA;
  687. DBGP_IF(DBGP_CELLGAMMA,
  688. DBGP("--- DCA_HAS_SRC_GAMMA --- %s:%s:%s [%s]"
  689. ARGFD6(SrcGamma[0], 1, 6)
  690. ARGFD6(SrcGamma[1], 1, 6)
  691. ARGFD6(SrcGamma[2], 1, 6)
  692. ARGFD6(MulFD6(SrcGamma[0], (FD6)2200000), 1, 6)));
  693. }
  694. if ((SrcGamma[0] != pPrimAdj->SrcGamma[0]) ||
  695. (SrcGamma[1] != pPrimAdj->SrcGamma[1]) ||
  696. (SrcGamma[2] != pPrimAdj->SrcGamma[2])) {
  697. CopyMemory(pPrimAdj->SrcGamma, SrcGamma, sizeof(SrcGamma));
  698. Changed = TRUE;
  699. }
  700. if ((DevGamma[0] != FD6_1) ||
  701. (DevGamma[1] != FD6_1) ||
  702. (DevGamma[2] != FD6_1)) {
  703. Flags |= DCA_HAS_DEST_GAMMA;
  704. DBGP_IF(DBGP_CELLGAMMA,
  705. DBGP("--- DCA_HAS_DEST_GAMMA --- %s:%s:%s"
  706. ARGFD6(DevGamma[0], 1, 6)
  707. ARGFD6(DevGamma[1], 1, 6)
  708. ARGFD6(DevGamma[2], 1, 6)));
  709. }
  710. if ((DevGamma[0] != pPrimAdj->DevGamma[0]) ||
  711. (DevGamma[1] != pPrimAdj->DevGamma[1]) ||
  712. (DevGamma[2] != pPrimAdj->DevGamma[2])) {
  713. CopyMemory(pPrimAdj->DevGamma, DevGamma, sizeof(DevGamma));
  714. Changed = TRUE;
  715. }
  716. if ((pPrimAdj->Flags & (DCA_HAS_ICM |
  717. DCA_HAS_SRC_GAMMA |
  718. DCA_HAS_DEST_GAMMA)) != Flags) {
  719. Changed = TRUE;
  720. }
  721. if (Changed) {
  722. pPrimAdj->Flags = (pPrimAdj->Flags & ~(DCA_HAS_ICM |
  723. DCA_HAS_SRC_GAMMA |
  724. DCA_HAS_DEST_GAMMA)) | Flags;
  725. }
  726. return(Changed);
  727. }
  728. PDEVICECOLORINFO
  729. HTENTRY
  730. pDCIAdjClr(
  731. PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
  732. PHTCOLORADJUSTMENT pHTColorAdjustment,
  733. PDEVCLRADJ *ppDevClrAdj,
  734. DWORD cbAlloc,
  735. WORD ForceFlags,
  736. CTSTDINFO CTSTDInfo,
  737. PLONG pError
  738. )
  739. /*++
  740. Routine Description:
  741. This function allowed the caller to changed the overall color adjustment
  742. for all the pictures rendered
  743. Arguments:
  744. pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
  745. which returned from the HT_CreateDeviceHalftoneInfo.
  746. pHTColorAdjustment - Pointer to the HTCOLORADJUSTMENT data structure, if
  747. this pointer is NULL then a default is applied.
  748. ppDevClrAdj - Pointer to pointer to the DEVCLRADJ data structure
  749. where the computed results will be stored, if this
  750. pointer isNULL then no color adjustment is done.
  751. if pSrcSI and ppDevClrAdj are not NULL then
  752. *ppDevClrAdj->Flags must contains the BBPFlags;
  753. ForceFlags - Force flags to make color changed.
  754. Return Value:
  755. PDEVICECOLORINFO, if return is NULL then a invalid pDeviceHalftoneInfo
  756. pointer is passed.
  757. Author:
  758. 29-May-1991 Wed 09:11:31 created -by- Daniel Chou (danielc)
  759. Revision History:
  760. --*/
  761. {
  762. PDEVICECOLORINFO pDCI;
  763. if ((!pDeviceHalftoneInfo) ||
  764. (PHT_DHI_DCI_OF(HalftoneDLLID) != HALFTONE_DLL_ID)) {
  765. *pError = HTERR_INVALID_DHI_POINTER;
  766. return(NULL);
  767. }
  768. pDCI = PDHI_TO_PDCI(pDeviceHalftoneInfo);
  769. //
  770. // Lock For this DCI
  771. //
  772. ACQUIRE_HTMUTEX(pDCI->HTMutex);
  773. //
  774. // Only if caller required color adjustments computations, then we will
  775. // compute for it.
  776. //
  777. if (ppDevClrAdj) {
  778. PDEVCLRADJ pDevClrAdj;
  779. PCIEPRIMS pDevPrims;
  780. PRGBLUTAA prgbLUT;
  781. HTCOLORADJUSTMENT ca;
  782. HTCOLORADJUSTMENT caCached;
  783. DEVMAPINFO DMI;
  784. DWORD LUTAAHdr[LUTAA_HDR_COUNT];
  785. PRIMADJ PrimAdj;
  786. DWORD DCIFlags;
  787. if ((ForceFlags & ADJ_FORCE_AB_PREMUL_SRC) &&
  788. (dwABPreMul[0])) {
  789. DWORD i;
  790. //
  791. // Generate a ABPreMul[] so that we can multiply it and get the
  792. // original pre-mul source value
  793. //
  794. dwABPreMul[0] = 0;
  795. for (i = 1; i < 256; i++) {
  796. dwABPreMul[i] = (DWORD)((0xFF000000 + (i - 1)) / i);
  797. }
  798. }
  799. if (!(*ppDevClrAdj = pDevClrAdj =
  800. (PDEVCLRADJ)HTAllocMem((LPVOID)pDCI,
  801. HTMEM_DevClrAdj,
  802. LPTR,
  803. cbAlloc + sizeof(DEVCLRADJ)))) {
  804. *pError = HTERR_INSUFFICIENT_MEMORY;
  805. //================================================================
  806. // Release SEMAPHORE NOW, since we are failing the memory request
  807. //================================================================
  808. RELEASE_HTMUTEX(pDCI->HTMutex);
  809. return(NULL);
  810. }
  811. //
  812. // Force the ICM on
  813. //
  814. if ((DCIFlags = pDCI->Flags) & DCIF_FORCE_ICM) {
  815. ForceFlags |= ADJ_FORCE_ICM;
  816. }
  817. //
  818. // Force gray scale
  819. //
  820. DMI.CTSTDInfo = CTSTDInfo;
  821. if ((DMI.CTSTDInfo.BMFDest == BMF_1BPP) ||
  822. ((DMI.CTSTDInfo.BMFDest == BMF_8BPP_VGA256) &&
  823. ((DCIFlags & (DCIF_USE_8BPP_BITMASK | DCIF_MONO_8BPP_BITMASK)) ==
  824. (DCIF_USE_8BPP_BITMASK | DCIF_MONO_8BPP_BITMASK)))) {
  825. ForceFlags |= (ADJ_FORCE_MONO | ADJ_FORCE_IDXBGR_MONO);
  826. }
  827. prgbLUT = (ForceFlags & ADJ_FORCE_BRUSH) ? &pDCI->rgbLUTPat :
  828. &pDCI->rgbLUT;
  829. if (ForceFlags & ADJ_FORCE_ICM) {
  830. //
  831. // These two does not mix
  832. //
  833. ForceFlags &= ~ADJ_FORCE_BRUSH;
  834. }
  835. //=====================================================================
  836. // We must make sure only one thread using this info.
  837. //=====================================================================
  838. ca = (pHTColorAdjustment) ? *pHTColorAdjustment :
  839. pDeviceHalftoneInfo->HTColorAdjustment;
  840. if ((ca.caSize != sizeof(HTCOLORADJUSTMENT)) ||
  841. (ca.caFlags & ~(CLRADJF_FLAGS_MASK))) {
  842. ca = DefaultCA;
  843. }
  844. caCached = pDCI->ca;
  845. PrimAdj = pDCI->PrimAdj;
  846. //
  847. // Now validate all color adjustments
  848. //
  849. ca.caFlags &= CLRADJF_FLAGS_MASK;
  850. if (ca.caIlluminantIndex > ILLUMINANT_MAX_INDEX) {
  851. ca.caIlluminantIndex = DefaultCA.caIlluminantIndex;
  852. }
  853. ADJ_CA(ca.caRedGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
  854. ADJ_CA(ca.caGreenGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
  855. ADJ_CA(ca.caBlueGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
  856. ADJ_CA(ca.caReferenceBlack, 0, REFERENCE_BLACK_MAX);
  857. ADJ_CA(ca.caReferenceWhite, REFERENCE_WHITE_MIN, 10000);
  858. ADJ_CA(ca.caContrast, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
  859. ADJ_CA(ca.caBrightness, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
  860. ADJ_CA(ca.caColorfulness, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
  861. ADJ_CA(ca.caRedGreenTint, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
  862. if ((ForceFlags & ADJ_FORCE_MONO) ||
  863. (ca.caColorfulness == MIN_COLOR_ADJ)) {
  864. ca.caColorfulness = MIN_COLOR_ADJ;
  865. ca.caRedGreenTint = 0;
  866. }
  867. if (ForceFlags & ADJ_FORCE_NEGATIVE) {
  868. ca.caFlags |= CLRADJF_NEGATIVE;
  869. }
  870. ca.caSize = (WORD)(ForceFlags & (ADJ_FORCE_DEVXFORM |
  871. ADJ_FORCE_BRUSH |
  872. ADJ_FORCE_MONO |
  873. ADJ_FORCE_IDXBGR_MONO |
  874. ADJ_FORCE_ICM));
  875. if ((AdjustSrcDevGamma(pDCI,
  876. &PrimAdj,
  877. &ca,
  878. DMI.CTSTDInfo.BMFDest,
  879. ForceFlags)) ||
  880. (!COMP_CA(&ca, &caCached))){
  881. DBGP_IF(DBGP_HCA,
  882. DBGP("---- New Color Adjustments --%08lx---" ARGDW(ca.caSize));
  883. DBGP("Flags = %08x" ARGDW(ca.caFlags));
  884. DBGP("Illum = %d" ARGW(ca.caIlluminantIndex));
  885. DBGP("R_Power = %u" ARGI(ca.caRedGamma));
  886. DBGP("G_Power = %u" ARGI(ca.caGreenGamma));
  887. DBGP("B_Power = %u" ARGI(ca.caBlueGamma));
  888. DBGP("BlackRef = %u" ARGW(ca.caReferenceBlack));
  889. DBGP("WhiteRef = %u" ARGW(ca.caReferenceWhite));
  890. DBGP("Contrast = %d" ARGI(ca.caContrast));
  891. DBGP("Bright = %d" ARGI(ca.caBrightness));
  892. DBGP("Colorful = %d" ARGI(ca.caColorfulness));
  893. DBGP("RG_Tint = %d" ARGI(ca.caRedGreenTint));
  894. DBGP("ForceAdj = %04lx" ARGDW(ForceFlags)));
  895. PrimAdj.Flags &= (DCA_HAS_ICM |
  896. DCA_DO_DEVCLR_XFORM |
  897. DCA_HAS_SRC_GAMMA |
  898. DCA_HAS_DEST_GAMMA);
  899. if (ForceFlags & ADJ_FORCE_IDXBGR_MONO) {
  900. PrimAdj.Flags |= DCA_MONO_ONLY;
  901. DBGP_IF(DBGP_HCA, DBGP("---DCA_MONO_ONLY---"));
  902. }
  903. if (ca.caFlags & CLRADJF_LOG_FILTER) {
  904. if (!LogFilterMax) {
  905. LogFilterMax = PRIM_LOG_RATIO(FD6_1);
  906. }
  907. PrimAdj.Flags |= DCA_LOG_FILTER;
  908. DBGP_IF(DBGP_HCA, DBGP("---DCA_LOG_FILTER---"));
  909. }
  910. if (ca.caFlags & CLRADJF_NEGATIVE) {
  911. PrimAdj.Flags |= DCA_NEGATIVE;
  912. DBGP_IF(DBGP_HCA, DBGP("---DCA_NEGATIVE---"));
  913. }
  914. pDevPrims = (PrimAdj.Flags & DCA_HAS_ICM) ?
  915. &(pDCI->ClrXFormBlock.rgbCIEPrims) :
  916. &(pDCI->ClrXFormBlock.DevCIEPrims);
  917. if ((ca.caSize & (ADJ_FORCE_ICM | ADJ_FORCE_DEVXFORM)) !=
  918. (caCached.caSize & (ADJ_FORCE_ICM | ADJ_FORCE_DEVXFORM))) {
  919. //
  920. // Re-Compute Device RGB xfrom matrix
  921. //
  922. DBGP_IF(DBGP_CCT,
  923. DBGP("\n*** ComputeColorSpaceForm(%hs_XFORM) ***\n"
  924. ARGPTR((PrimAdj.Flags & DCA_HAS_ICM) ?
  925. "ICM" : "DEVICE")));
  926. ComputeColorSpaceXForm(pDCI,
  927. pDevPrims,
  928. &(PrimAdj.DevCSXForm),
  929. -1);
  930. }
  931. if (ca.caIlluminantIndex != caCached.caIlluminantIndex) {
  932. DBGP_IF(DBGP_CCT,
  933. DBGP("*** ComputeColorSpaceForm(RGB_XFORM Illuminant=%u) ***"
  934. ARGU(ca.caIlluminantIndex)));
  935. ComputeColorSpaceXForm(pDCI,
  936. &(pDCI->ClrXFormBlock.rgbCIEPrims),
  937. &(PrimAdj.rgbCSXForm),
  938. (INT)ca.caIlluminantIndex);
  939. }
  940. if ((PrimAdj.Flags & DCA_MONO_ONLY) ||
  941. (CompareMemory((LPBYTE)pDevPrims,
  942. (LPBYTE)&(pDCI->ClrXFormBlock.rgbCIEPrims),
  943. sizeof(CIEPRIMS)))) {
  944. PrimAdj.Flags &= ~DCA_HAS_CLRSPACE_ADJ;
  945. } else {
  946. PrimAdj.Flags |= DCA_HAS_CLRSPACE_ADJ;
  947. }
  948. PrimAdj.MinL = UDECI4ToFD6(ca.caReferenceBlack) + HT_K_REF_ADD;
  949. PrimAdj.MaxL = UDECI4ToFD6(ca.caReferenceWhite) - HT_W_REF_SUB;
  950. if ((PrimAdj.MinL != HT_K_REF_BASE) ||
  951. (PrimAdj.MaxL != HT_W_REF_BASE)) {
  952. PrimAdj.Flags |= DCA_HAS_BW_REF_ADJ;
  953. PrimAdj.MinLMul = DivFD6(HT_K_REF_CLIP, PrimAdj.MinL);
  954. PrimAdj.MaxLMul = DivFD6(HT_W_REF_CLIP,
  955. FD6_1 - PrimAdj.MaxL);
  956. PrimAdj.RangeLMul = DivFD6(HT_KW_REF_RANGE,
  957. PrimAdj.MaxL - PrimAdj.MinL);
  958. DBGP_IF(DBGP_HCA,
  959. DBGP("--- DCA_HAS_BW_REF_ADJ %s to %s, xK=%s, xW=%s, xRange=%s ---"
  960. ARGFD6(PrimAdj.MinL, 1, 6)
  961. ARGFD6(PrimAdj.MaxL, 1, 6)
  962. ARGFD6(PrimAdj.MinLMul, 1, 6)
  963. ARGFD6(PrimAdj.MaxLMul, 1, 6)
  964. ARGFD6(PrimAdj.RangeLMul, 1, 6)));
  965. } else {
  966. PrimAdj.Flags &= ~DCA_HAS_BW_REF_ADJ;
  967. PrimAdj.MinL = FD6_0;
  968. PrimAdj.MaxL = FD6_1;
  969. PrimAdj.MinLMul =
  970. PrimAdj.MaxLMul =
  971. PrimAdj.RangeLMul = FD6_0;
  972. }
  973. if (ca.caContrast) {
  974. PrimAdj.Contrast = JND_ADJ((FD6)1015000, ca.caContrast);
  975. PrimAdj.Flags |= DCA_HAS_CONTRAST_ADJ;
  976. DBGP_IF(DBGP_HCA,
  977. DBGP("--- DCA_HAS_CONTRAST_ADJ = %s ---"
  978. ARGFD6(PrimAdj.Contrast, 1, 6)));
  979. }
  980. if (ca.caBrightness) {
  981. PrimAdj.Brightness = FD6xL((FD6)3750, ca.caBrightness);
  982. PrimAdj.Flags |= DCA_HAS_BRIGHTNESS_ADJ;
  983. DBGP_IF(DBGP_HCA,
  984. DBGP("--- DCA_HAS_BRIGHTNESS_ADJ = %s ---"
  985. ARGFD6(PrimAdj.Brightness, 1, 6)));
  986. }
  987. //
  988. // Colorfulness, RedGreenTint, and DYE_CORRECTIONS only valid and
  989. // necessary if it a color device output
  990. //
  991. if (!(PrimAdj.Flags & DCA_MONO_ONLY)) {
  992. PrimAdj.Color = (FD6)(ca.caColorfulness + MAX_COLOR_ADJ);
  993. // if (ca.caSize & ADJ_FORCE_BRUSH) {
  994. //
  995. // PrimAdj.Color += HT_BRUSH_COLORFULNESS;
  996. // }
  997. if ((PrimAdj.Color *= 10000) != FD6_1) {
  998. PrimAdj.Flags |= DCA_HAS_COLOR_ADJ;
  999. DBGP_IF(DBGP_HCA,
  1000. DBGP("--- DCA_HAS_COLOR_ADJ = %s ---"
  1001. ARGFD6(PrimAdj.Color, 1, 6)));
  1002. }
  1003. if (ca.caRedGreenTint) {
  1004. TintAngle((LONG)ca.caRedGreenTint,
  1005. (LONG)6,
  1006. (PFD6)&(PrimAdj.TintSinAngle),
  1007. (PFD6)&(PrimAdj.TintCosAngle));
  1008. PrimAdj.Flags |= DCA_HAS_TINT_ADJ;
  1009. DBGP_IF(DBGP_HCA,
  1010. DBGP("--- DCA_HAS_TINT_ADJ Sin=%s, Cos=%s ---"
  1011. ARGFD6(PrimAdj.TintSinAngle, 1, 6)
  1012. ARGFD6(PrimAdj.TintCosAngle, 1, 6)));
  1013. }
  1014. if ((DCIFlags & DCIF_NEED_DYES_CORRECTION) &&
  1015. ((PrimAdj.Flags & (DCA_HAS_ICM | DCA_DO_DEVCLR_XFORM)) ==
  1016. DCA_DO_DEVCLR_XFORM)) {
  1017. PrimAdj.Flags |= DCA_NEED_DYES_CORRECTION;
  1018. DBGP_IF(DBGP_HCA, DBGP("---DCA_NEED_DYES_CORRECTION---"));
  1019. if (DCIFlags & DCIF_HAS_BLACK_DYE) {
  1020. PrimAdj.Flags |= DCA_HAS_BLACK_DYE;
  1021. DBGP_IF(DBGP_HCA, DBGP("---DCA_HAS_BLACK_DYE---"));
  1022. }
  1023. }
  1024. }
  1025. DBGP_IF(DBGP_CCT,
  1026. DBGP("** Save PrimAdj back to pDCI, Flags=%08lx **"
  1027. ARGDW(PrimAdj.Flags)));
  1028. pDCI->ca = ca;
  1029. pDCI->PrimAdj = PrimAdj;
  1030. } else {
  1031. DBGP_IF(DBGP_CCT, DBGP("* Use cached HTCOLORADJUSTMENT *"));
  1032. }
  1033. //
  1034. // These flags are always computed per call, so turn it off first
  1035. //
  1036. PrimAdj.Flags &= ~(DCA_NO_ANY_ADJ |
  1037. DCA_NO_MAPPING_TABLE |
  1038. DCA_MASK8BPP |
  1039. DCA_BBPF_AA_OFF |
  1040. DCA_USE_ADDITIVE_PRIMS |
  1041. DCA_XLATE_555_666 |
  1042. DCA_XLATE_332 |
  1043. DCA_REPLACE_BLACK);
  1044. if (!(PrimAdj.Flags & (DCA_NEED_DYES_CORRECTION |
  1045. DCA_HAS_CLRSPACE_ADJ |
  1046. DCA_HAS_SRC_GAMMA |
  1047. DCA_HAS_BW_REF_ADJ |
  1048. DCA_HAS_CONTRAST_ADJ |
  1049. DCA_HAS_BRIGHTNESS_ADJ |
  1050. DCA_HAS_COLOR_ADJ |
  1051. DCA_HAS_TINT_ADJ |
  1052. DCA_LOG_FILTER |
  1053. DCA_NEGATIVE |
  1054. DCA_DO_DEVCLR_XFORM |
  1055. DCA_HAS_DEST_GAMMA))) {
  1056. PrimAdj.Flags |= DCA_NO_ANY_ADJ;
  1057. DBGP_IF(DBGP_HCA, DBGP("---DCA_NO_ANY_ADJ---"));
  1058. }
  1059. if ((PrimAdj.Flags & DCA_MONO_ONLY) ||
  1060. (!(PrimAdj.Flags & (DCA_NEED_DYES_CORRECTION |
  1061. DCA_HAS_CLRSPACE_ADJ |
  1062. DCA_HAS_COLOR_ADJ |
  1063. DCA_HAS_TINT_ADJ)))) {
  1064. PrimAdj.Flags |= DCA_NO_MAPPING_TABLE;
  1065. DBGP_IF(DBGP_HCA, DBGP("---DCA_NO_MAPPING_TABLE---"));
  1066. }
  1067. if ((DCIFlags & DCIF_PRINT_DRAFT_MODE) ||
  1068. (ForceFlags & ADJ_FORCE_NO_EXP_AA)) {
  1069. PrimAdj.Flags |= DCA_BBPF_AA_OFF;
  1070. DBGP_IF(DBGP_HCA, DBGP("---DCA_BBPF_AA_OFF---"));
  1071. }
  1072. if (ForceFlags & ADJ_FORCE_ALPHA_BLEND) {
  1073. PrimAdj.Flags |= DCA_ALPHA_BLEND;
  1074. DBGP_IF(DBGP_HCA, DBGP("---DCA_ALPHA_BLEND---"));
  1075. if (ForceFlags & ADJ_FORCE_CONST_ALPHA) {
  1076. PrimAdj.Flags |= DCA_CONST_ALPHA;
  1077. DBGP_IF(DBGP_HCA, DBGP("---DCA_CONST_ALPHA---"));
  1078. } else {
  1079. if (ForceFlags & ADJ_FORCE_AB_PREMUL_SRC) {
  1080. DBGP_IF(DBGP_HCA, DBGP("---DCA_AB_PREMUL_SRC---"));
  1081. PrimAdj.Flags |= DCA_AB_PREMUL_SRC;
  1082. }
  1083. if (ForceFlags & ADJ_FORCE_AB_DEST) {
  1084. DBGP_IF(DBGP_HCA, DBGP("---DCA_AB_DEST---"));
  1085. PrimAdj.Flags |= DCA_AB_DEST;
  1086. }
  1087. }
  1088. }
  1089. //
  1090. // Since we do substractive prims at output time, we need to re-set
  1091. // this flag evertime the pDCIAdjClr called.
  1092. //
  1093. if (ForceFlags & ADJ_FORCE_ADDITIVE_PRIMS) {
  1094. PrimAdj.Flags |= DCA_USE_ADDITIVE_PRIMS;
  1095. DBGP_IF(DBGP_HCA, DBGP("---DCA_USE_ADDITIVE_PRIMS---"));
  1096. }
  1097. //
  1098. // All following is first set in RGB order wehre B is lowest memory
  1099. // location (0) and R is in highest memory location (2), see
  1100. // DstOrderTable[], so the index 0=B, 1=G. 2=R
  1101. //
  1102. // LUTAAHdr[]: DWORD Masking for the destination in BGR order
  1103. // Mul[]: Multiply factor when makeing RGBLUTAA table
  1104. // MulAdd: Addition amount after Mul
  1105. // LSft: Left shift amount after Mul/MulAdd
  1106. //
  1107. ZeroMemory(LUTAAHdr, sizeof(LUTAAHdr));
  1108. DMI.BlackChk = FD6_1;
  1109. DMI.Flags = 0;
  1110. DMI.LSft[0] =
  1111. DMI.LSft[1] =
  1112. DMI.LSft[2] = 4;
  1113. DMI.CTSTDInfo.cbPrim = sizeof(BGR8);
  1114. if (PrimAdj.Flags & DCA_MONO_ONLY) {
  1115. PrimAdj.Flags |= DCA_RGBLUTAA_MONO;
  1116. DMI.Flags |= DMIF_GRAY;
  1117. DMI.Mul[0] =
  1118. DMI.Mul[1] =
  1119. DMI.Mul[2] = GRAY_MAX_IDX;
  1120. DMI.MulAdd = 0;
  1121. } else {
  1122. DMI.MulAdd = 0x1000;
  1123. DMI.Mul[0] =
  1124. DMI.Mul[1] =
  1125. DMI.Mul[2] = DMI.MulAdd - 1;
  1126. }
  1127. switch (DMI.CTSTDInfo.BMFDest) {
  1128. case BMF_1BPP:
  1129. //
  1130. // PRIMARY_ORDER_RGB (Always)
  1131. //
  1132. // NOT APPLICABLE
  1133. //
  1134. ASSERT(DMI.Flags & DMIF_GRAY);
  1135. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
  1136. break;
  1137. case BMF_4BPP_VGA16:
  1138. //
  1139. // PRIMARY_ORDER_BGR
  1140. // |||
  1141. // ||+-- bit 0/4
  1142. // ||
  1143. // |+--- bit 1/5
  1144. // |
  1145. // +---- bit 2/7
  1146. //
  1147. //
  1148. PrimAdj.Flags |= DCA_USE_ADDITIVE_PRIMS;
  1149. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_BGR;
  1150. //
  1151. // Fall through for same as BMF_4BPP
  1152. //
  1153. case BMF_4BPP:
  1154. //
  1155. // PRIMARY_ORDER_abc
  1156. // |||
  1157. // ||+-- bit 0/4
  1158. // ||
  1159. // |+--- bit 1/5
  1160. // |
  1161. // +---- bit 2/7
  1162. //
  1163. //
  1164. LUTAAHdr[0] = 0x100000;
  1165. LUTAAHdr[1] = 0x200000;
  1166. LUTAAHdr[2] = 0x400000;
  1167. LUTAAHdr[3] = 0x010000;
  1168. LUTAAHdr[4] = 0x020000;
  1169. LUTAAHdr[5] = 0x040000;
  1170. DMI.LSft[0] = 4;
  1171. DMI.LSft[1] = 5;
  1172. DMI.LSft[2] = 6;
  1173. DMI.MulAdd = 0x0;
  1174. break;
  1175. case BMF_8BPP_VGA256:
  1176. //
  1177. // 8BPP_MASK_CLR (COLOR)
  1178. //
  1179. // PRIMARY_ORDER_CMY (system standard 3:3:2 CMY format)
  1180. // |||
  1181. // ||+-- bit 0-1 (Max. 2 bits of yellow)
  1182. // ||
  1183. // |+--- bit 2-4 (Max. 3 bits of magenta)
  1184. // |
  1185. // +---- bit 5-7 (Max. 3 bits of cyan)
  1186. //
  1187. //
  1188. // 8BPP_MASK_MONO (MONO)
  1189. //
  1190. // NOT APPLICABLE
  1191. //
  1192. //
  1193. //
  1194. // VGA_256 System Halftone Standard (BGR Always)
  1195. //
  1196. // PRIMARY_ORDER_BGR
  1197. // | |
  1198. // | +-- Lowest Primary Index
  1199. // |
  1200. // |
  1201. // |
  1202. // +---- Highest Primary Index
  1203. //
  1204. //
  1205. if (DCIFlags & DCIF_USE_8BPP_BITMASK) {
  1206. BM8BPPINFO bm8i;
  1207. PrimAdj.Flags |= DCA_MASK8BPP;
  1208. bm8i.dw = 0;
  1209. if (pDCI->CMY8BPPMask.GenerateXlate) {
  1210. GenCMYMaskXlate(pDCI->CMY8BPPMask.bXlate,
  1211. (BOOL)(DCIFlags &
  1212. DCIF_INVERT_8BPP_BITMASK_IDX),
  1213. (LONG)pDCI->CMY8BPPMask.cC,
  1214. (LONG)pDCI->CMY8BPPMask.cM,
  1215. (LONG)pDCI->CMY8BPPMask.cY);
  1216. pDCI->CMY8BPPMask.GenerateXlate = 0;
  1217. }
  1218. if (DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) {
  1219. bm8i.Data.pXlateIdx |= XLATE_RGB_IDX_OR;
  1220. bm8i.Data.bXor = 0xFF;
  1221. } else {
  1222. bm8i.Data.bXor = 0;
  1223. }
  1224. bm8i.Data.bBlack = pDCI->CMY8BPPMask.Mask ^ bm8i.Data.bXor;
  1225. bm8i.Data.bWhite = bm8i.Data.bXor;
  1226. if (DCIFlags & DCIF_MONO_8BPP_BITMASK) {
  1227. ASSERT(DMI.Flags & DMIF_GRAY);
  1228. LUTAAHdr[0] =
  1229. LUTAAHdr[1] =
  1230. LUTAAHdr[2] = 0xFF0000;
  1231. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
  1232. DMI.CTSTDInfo.BMFDest = BMF_8BPP_MONO;
  1233. DBGP_IF(DBGP_HCA, DBGP("---DCA_MASK8BPP_MONO---"));
  1234. } else {
  1235. LPBYTE pXlate;
  1236. DWORD KIdx;
  1237. DMI.Mul[0] = ((DWORD)pDCI->CMY8BPPMask.cY << 12) - 1;
  1238. DMI.Mul[1] = ((DWORD)pDCI->CMY8BPPMask.cM << 12) - 1;
  1239. DMI.Mul[2] = ((DWORD)pDCI->CMY8BPPMask.cC << 12) - 1;
  1240. LUTAAHdr[0] = (DWORD)pDCI->CMY8BPPMask.PatSubY;
  1241. LUTAAHdr[1] = (DWORD)pDCI->CMY8BPPMask.PatSubM;
  1242. LUTAAHdr[2] = (DWORD)pDCI->CMY8BPPMask.PatSubC;
  1243. DMI.LSft[0] = 4;
  1244. DMI.LSft[1] = 7;
  1245. DMI.LSft[2] = 10;
  1246. switch (pDCI->CMY8BPPMask.SameLevel) {
  1247. case 4:
  1248. case 5:
  1249. if (pDCI->CMY8BPPMask.SameLevel == 4) {
  1250. DMI.CTSTDInfo.BMFDest = BMF_8BPP_L555;
  1251. KIdx = SIZE_XLATE_555 - 1;
  1252. } else {
  1253. DMI.CTSTDInfo.BMFDest = BMF_8BPP_L666;
  1254. bm8i.Data.pXlateIdx |= XLATE_666_IDX_OR;
  1255. KIdx = SIZE_XLATE_666 - 1;
  1256. }
  1257. PrimAdj.Flags |= DCA_XLATE_555_666;
  1258. bm8i.Data.pXlateIdx &= XLATE_IDX_MASK;
  1259. pXlate = p8BPPXlate[bm8i.Data.pXlateIdx];
  1260. bm8i.Data.bBlack = pXlate[KIdx];
  1261. bm8i.Data.bWhite = pXlate[0];
  1262. break;
  1263. default:
  1264. DMI.LSft[1] = 6;
  1265. DMI.LSft[2] = 9;
  1266. DMI.CTSTDInfo.BMFDest = BMF_8BPP_B332;
  1267. if (DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) {
  1268. PrimAdj.Flags |= DCA_XLATE_332;
  1269. bm8i.Data.bBlack = pDCI->CMY8BPPMask.bXlate[255];
  1270. bm8i.Data.bWhite = pDCI->CMY8BPPMask.bXlate[0];
  1271. }
  1272. break;
  1273. }
  1274. if (pDCI->CMY8BPPMask.KCheck) {
  1275. PrimAdj.Flags |= DCA_REPLACE_BLACK;
  1276. DMI.BlackChk = pDCI->CMY8BPPMask.KCheck;
  1277. DMI.LSft[0] -= 4;
  1278. DMI.LSft[1] -= 4;
  1279. DMI.LSft[2] -= 4;
  1280. switch (DMI.CTSTDInfo.BMFDest) {
  1281. case BMF_8BPP_B332:
  1282. DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_B332;
  1283. break;
  1284. case BMF_8BPP_L555:
  1285. DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_L555;
  1286. break;
  1287. case BMF_8BPP_L666:
  1288. DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_L666;
  1289. break;
  1290. }
  1291. }
  1292. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_CMY;
  1293. DBGP_IF(DBGP_HCA,
  1294. DBGP("---%hsFlag=%04lx, KCheck=%s, KPower=%s ---"
  1295. ARGPTR((PrimAdj.Flags & DCA_REPLACE_BLACK) ?
  1296. "DCA_REPLACE_BLACK, " : " ")
  1297. ARGDW(DMI.Flags)
  1298. ARGFD6(DMI.BlackChk, 1, 6)
  1299. ARGFD6(K_REP_POWER, 1, 6)));
  1300. }
  1301. DBGP_IF(DBGP_HCA,
  1302. DBGP("---DCA_MASK8BPP (%hs), Idx=%02lx, Xor=%02lx, K=%02lx (%ld), W=(%02lx/%ld) ---"
  1303. ARGPTR((DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) ?
  1304. "RGB" : "CMY")
  1305. ARGDW(bm8i.Data.pXlateIdx)
  1306. ARGDW(bm8i.Data.bXor)
  1307. ARGDW(bm8i.Data.bBlack) ARGDW(bm8i.Data.bBlack)
  1308. ARGDW(bm8i.Data.bWhite) ARGDW(bm8i.Data.bWhite)));
  1309. LUTAAHdr[3] =
  1310. LUTAAHdr[4] =
  1311. LUTAAHdr[5] = bm8i.dw;
  1312. } else {
  1313. //
  1314. // PRIMARY_ORDER_BGR (Always BGR system halftone palette)
  1315. // |||
  1316. // ||+-- bit 0-2 (3 bits)
  1317. // ||
  1318. // |+--- bit 3-5 (3 bits)
  1319. // |
  1320. // +---- bit 6-8 (3 bits)
  1321. //
  1322. //
  1323. DMI.Mul[0] =
  1324. DMI.Mul[1] =
  1325. DMI.Mul[2] = 0x4FFF;
  1326. LUTAAHdr[0] = 0x0070000;
  1327. LUTAAHdr[1] = 0x0380000;
  1328. LUTAAHdr[2] = 0x1c00000;
  1329. DMI.LSft[0] = 4;
  1330. DMI.LSft[1] = 7;
  1331. DMI.LSft[2] = 10;
  1332. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_BGR;
  1333. PrimAdj.Flags &= ~DCA_MASK8BPP;
  1334. }
  1335. break;
  1336. case BMF_16BPP_555:
  1337. //
  1338. // PRIMARY_ORDER_abc
  1339. // |||
  1340. // ||+-- bit 0-4 (5 bits)
  1341. // ||
  1342. // |+--- bit 5-9 (5 bits)
  1343. // |
  1344. // +---- bit 10-14 (5 bits)
  1345. //
  1346. //
  1347. DMI.Mul[0] =
  1348. DMI.Mul[1] =
  1349. DMI.Mul[2] = 0x1EFFF;
  1350. LUTAAHdr[0] = 0x001F0000;
  1351. LUTAAHdr[1] = 0x03e00000;
  1352. LUTAAHdr[2] = 0x7c000000;
  1353. LUTAAHdr[3] =
  1354. LUTAAHdr[4] =
  1355. LUTAAHdr[5] = 0x7FFF7FFF;
  1356. DMI.LSft[0] = 4;
  1357. DMI.LSft[1] = 9;
  1358. DMI.LSft[2] = 14;
  1359. break;
  1360. case BMF_16BPP_565:
  1361. //
  1362. // PRIMARY_ORDER_RGB (or BGR)
  1363. // |||
  1364. // ||+-- bit 0-4 (5 bits)
  1365. // ||
  1366. // |+--- bit 5-10 (6 bits)
  1367. // |
  1368. // +---- bit 11-15 (5 bits)
  1369. //
  1370. //
  1371. switch (DMI.CTSTDInfo.DestOrder) {
  1372. case PRIMARY_ORDER_RGB:
  1373. case PRIMARY_ORDER_BGR:
  1374. break;
  1375. default:
  1376. DBGP("Invalid 16BPP 565 Order=%ld, Allowed=(%ld,%ld) --> %ld"
  1377. ARGDW(DMI.CTSTDInfo.DestOrder)
  1378. ARGDW(PRIMARY_ORDER_RGB) ARGDW(PRIMARY_ORDER_BGR)
  1379. ARGDW(PRIMARY_ORDER_RGB));
  1380. DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
  1381. }
  1382. DMI.Mul[0] =
  1383. DMI.Mul[2] = 0x1EFFF;
  1384. DMI.Mul[1] = 0x3EFFF;
  1385. LUTAAHdr[0] = 0x001F0000;
  1386. LUTAAHdr[1] = 0x07e00000;
  1387. LUTAAHdr[2] = 0xF8000000;
  1388. LUTAAHdr[3] =
  1389. LUTAAHdr[4] =
  1390. LUTAAHdr[5] = 0xFFFFFFFF;
  1391. DMI.LSft[0] = 4;
  1392. DMI.LSft[1] = 9;
  1393. DMI.LSft[2] = 15;
  1394. break;
  1395. case BMF_24BPP:
  1396. //
  1397. // PRIMARY_ORDER_BGR (system standard always BGR)
  1398. // |||
  1399. // ||+-- bit 0-7 (8 bits)
  1400. // ||
  1401. // |+--- bit 8-15 (8 bits)
  1402. // |
  1403. // +---- bit 16-23 (8 bits)
  1404. //
  1405. //
  1406. DBGP_IF(DBGP_HCA,
  1407. DBGP("24BPP DstOrder=%ld" ARGDW(DMI.CTSTDInfo.DestOrder)));
  1408. //
  1409. // Fall through
  1410. //
  1411. case BMF_32BPP:
  1412. //
  1413. // PRIMARY_ORDER_abc
  1414. // |||
  1415. // ||+-- bit 0-7 (8 bits)
  1416. // ||
  1417. // |+--- bit 8-15 (8 bits)
  1418. // |
  1419. // +---- bit 16-23 (8 bits)
  1420. //
  1421. //
  1422. DMI.Mul[0] =
  1423. DMI.MulAdd = 0;
  1424. DMI.LSft[0] =
  1425. DMI.LSft[1] =
  1426. DMI.LSft[2] = 0;
  1427. DMI.Mul[0] =
  1428. DMI.Mul[1] =
  1429. DMI.Mul[2] = 0xFF;
  1430. LUTAAHdr[0] = 0;
  1431. LUTAAHdr[1] = 1;
  1432. LUTAAHdr[2] = 2;
  1433. break;
  1434. }
  1435. //
  1436. // Watch out!!!, the ExtBGR must in BGR order
  1437. //
  1438. DMI.DstOrder = DstOrderTable[DMI.CTSTDInfo.DestOrder];
  1439. pDevClrAdj->DMI = DMI;
  1440. pDevClrAdj->ca = ca;
  1441. prgbLUT->ExtBGR[2] = LUTAAHdr[DMI.DstOrder.Order[0]];
  1442. prgbLUT->ExtBGR[1] = LUTAAHdr[DMI.DstOrder.Order[1]];
  1443. prgbLUT->ExtBGR[0] = LUTAAHdr[DMI.DstOrder.Order[2]];
  1444. prgbLUT->ExtBGR[5] = LUTAAHdr[DMI.DstOrder.Order[0] + 3];
  1445. prgbLUT->ExtBGR[4] = LUTAAHdr[DMI.DstOrder.Order[1] + 3];
  1446. prgbLUT->ExtBGR[3] = LUTAAHdr[DMI.DstOrder.Order[2] + 3];
  1447. pDevClrAdj->PrimAdj = PrimAdj;
  1448. pDevClrAdj->pClrXFormBlock = &(pDCI->ClrXFormBlock);
  1449. pDevClrAdj->pCRTXLevel255 = &(pDCI->CRTX[CRTX_LEVEL_255]);
  1450. pDevClrAdj->pCRTXLevelRGB = &(pDCI->CRTX[CRTX_LEVEL_RGB]);
  1451. DBGP_IF(DBGP_HCA,
  1452. DBGP("DestFmt=%3ld, Order=%ld [%ld:%ld:%ld], DMI.Flags=%02lx"
  1453. ARGDW(DMI.CTSTDInfo.BMFDest) ARGDW(DMI.DstOrder.Index)
  1454. ARGDW(DMI.DstOrder.Order[0]) ARGDW(DMI.DstOrder.Order[1])
  1455. ARGDW(DMI.DstOrder.Order[2]) ARGDW(DMI.Flags)));
  1456. DBGP_IF(DBGP_HCA,
  1457. DBGP("ExtBGR=%08lx:%08lx:%08lx:%08lx:%08lx:%08lx, LSft=%ld:%ld:%ld"
  1458. ARGDW(prgbLUT->ExtBGR[0]) ARGDW(prgbLUT->ExtBGR[1])
  1459. ARGDW(prgbLUT->ExtBGR[2]) ARGDW(prgbLUT->ExtBGR[3])
  1460. ARGDW(prgbLUT->ExtBGR[4]) ARGDW(prgbLUT->ExtBGR[5])
  1461. ARGDW(pDevClrAdj->DMI.LSft[0])
  1462. ARGDW(pDevClrAdj->DMI.LSft[1])
  1463. ARGDW(pDevClrAdj->DMI.LSft[2])));
  1464. DBGP_IF(DBGP_HCA,
  1465. DBGP("Mul=%08lx:%08lx:%08lx, MulAdd=%08lx"
  1466. ARGDW(pDevClrAdj->DMI.Mul[0]) ARGDW(pDevClrAdj->DMI.Mul[1])
  1467. ARGDW(pDevClrAdj->DMI.Mul[2]) ARGDW(pDevClrAdj->DMI.MulAdd)));
  1468. DBGP_IF(DBGP_PRIMADJFLAGS,
  1469. DBGP("pDCIAdjClr: PrimAdj.Flags=%08lx" ARGDW(PrimAdj.Flags)));
  1470. }
  1471. return(pDCI);
  1472. }
  1473. VOID
  1474. HTENTRY
  1475. ComputeColorSpaceXForm(
  1476. PDEVICECOLORINFO pDCI,
  1477. PCIEPRIMS pCIEPrims,
  1478. PCOLORSPACEXFORM pCSXForm,
  1479. INT IlluminantIndex
  1480. )
  1481. /*++
  1482. Routine Description:
  1483. This function take device's R/G/B/W CIE coordinate (x,y) and compute
  1484. 3 x 3 transform matrix, it assume the primaries are additively.
  1485. Calcualte the 3x3 CIE matrix and its inversion (matrix) based on the
  1486. C.I.E. CHROMATICITY x, y coordinates or RGB and WHITE alignment.
  1487. this function produces the CIE XYZ matrix and/or its inversion for trnaform
  1488. between RGB primary colors and CIE color spaces, the transforms are
  1489. -1
  1490. [ X ] = [ Xr Xg Xb ] [ R ] [ R ] = [ Xr Xg Xb ] [ X ]
  1491. [ Y ] = [ Yr Yg Yb ] [ G ] and [ G ] [ Yr Yg Yb ] [ Y ]
  1492. [ Z ] = [ Zr Zg Zb ] [ B ] [ B ] [ Zr Zg Zb ] [ Z ]
  1493. Arguments:
  1494. pDCI - The current device color info
  1495. pCIEPrims - Pointer to CIEPRIMS data structure, the CIEPRIMS data
  1496. must already validated.
  1497. pCSXForm - Pointer to the location to stored the transfrom
  1498. ColorSpace - CIELUV or CIELAB
  1499. IlluminantIndex - Standard illuminant index if < 0 then pCIEPrims->w is
  1500. used
  1501. Return Value:
  1502. VOID
  1503. Author:
  1504. 11-Oct-1991 Fri 14:19:59 created -by- Daniel Chou (danielc)
  1505. Revision History:
  1506. 20-Apr-1993 Tue 03:08:15 updated -by- Daniel Chou (danielc)
  1507. re-write so that xform will be correct when device default is used.
  1508. 22-Jan-1998 Thu 03:01:02 updated -by- Daniel Chou (danielc)
  1509. use IlluminantIndex to indicate if device reverse transform is needed
  1510. --*/
  1511. {
  1512. MATRIX3x3 Matrix3x3;
  1513. FD6XYZ WhiteXYZ;
  1514. MULDIVPAIR MDPairs[5];
  1515. FD6 DiffRGB;
  1516. FD6 RedXYZScale;
  1517. FD6 GreenXYZScale;
  1518. FD6 BlueXYZScale;
  1519. FD6 AUw;
  1520. FD6 BVw;
  1521. FD6 xr;
  1522. FD6 yr;
  1523. FD6 xg;
  1524. FD6 yg;
  1525. FD6 xb;
  1526. FD6 yb;
  1527. FD6 xw;
  1528. FD6 yw;
  1529. FD6 Yw;
  1530. xr = pCIEPrims->r.x;
  1531. yr = pCIEPrims->r.y;
  1532. xg = pCIEPrims->g.x;
  1533. yg = pCIEPrims->g.y;
  1534. xb = pCIEPrims->b.x;
  1535. yb = pCIEPrims->b.y;
  1536. Yw = pCIEPrims->Yw;
  1537. if (IlluminantIndex < 0) {
  1538. xw = pCIEPrims->w.x;
  1539. yw = pCIEPrims->w.y;
  1540. } else {
  1541. if (--IlluminantIndex < 0) {
  1542. IlluminantIndex = ILLUMINANT_D65 - 1;
  1543. }
  1544. pCIEPrims->w.x =
  1545. xw = UDECI4ToFD6(StdIlluminant[IlluminantIndex].x);
  1546. pCIEPrims->w.y =
  1547. yw = UDECI4ToFD6(StdIlluminant[IlluminantIndex].y);
  1548. }
  1549. DBGP_IF(DBGP_CIEMATRIX,
  1550. DBGP("** CIEINFO: [xw, yw, Yw] = [%s, %s, %s], Illuminant=%d"
  1551. ARGFD6l(xw) ARGFD6l(yw) ARGFD6l(Yw) ARGI(IlluminantIndex)));
  1552. DBGP_IF(DBGP_CIEMATRIX,
  1553. DBGP("[xR yR] = [%s %s]" ARGFD6l(xr) ARGFD6l(yr));
  1554. DBGP("[xG yG] = [%s %s]" ARGFD6l(xg) ARGFD6l(yg));
  1555. DBGP("[xB yB] = [%s %s]" ARGFD6l(xb) ARGFD6l(yb));
  1556. DBGP("***********************************************"));
  1557. //
  1558. // Normalized to have C.I.E. Y equal to 1.0
  1559. //
  1560. MAKE_MULDIV_INFO(MDPairs, 3, MULDIV_HAS_DIVISOR);
  1561. MAKE_MULDIV_DVSR(MDPairs, Yw);
  1562. MAKE_MULDIV_PAIR(MDPairs, 1, xr, yg - yb);
  1563. MAKE_MULDIV_PAIR(MDPairs, 2, xg, yb - yr);
  1564. MAKE_MULDIV_PAIR(MDPairs, 3, xb, yr - yg);
  1565. DiffRGB = MulFD6(yw, MulDivFD6Pairs(MDPairs));
  1566. //
  1567. // Compute Scaling factors for each color
  1568. //
  1569. MAKE_MULDIV_INFO(MDPairs, 4, MULDIV_HAS_DIVISOR);
  1570. MAKE_MULDIV_DVSR(MDPairs, DiffRGB);
  1571. MAKE_MULDIV_PAIR(MDPairs, 1, xw, yg - yb);
  1572. MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xg - xb);
  1573. MAKE_MULDIV_PAIR(MDPairs, 3, xg, yb );
  1574. MAKE_MULDIV_PAIR(MDPairs, 4, -xb, yg );
  1575. RedXYZScale = MulDivFD6Pairs(MDPairs);
  1576. MAKE_MULDIV_PAIR(MDPairs, 1, xw, yb - yr);
  1577. MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xb - xr);
  1578. MAKE_MULDIV_PAIR(MDPairs, 3, -xr, yb );
  1579. MAKE_MULDIV_PAIR(MDPairs, 4, xb, yr );
  1580. GreenXYZScale = MulDivFD6Pairs(MDPairs);
  1581. MAKE_MULDIV_PAIR(MDPairs, 1, xw, yr - yg);
  1582. MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xr - xg);
  1583. MAKE_MULDIV_PAIR(MDPairs, 3, xr, yg );
  1584. MAKE_MULDIV_PAIR(MDPairs, 4, -xg, yr );
  1585. BlueXYZScale = MulDivFD6Pairs(MDPairs);
  1586. //
  1587. // Now scale the RGB coordinate by it ratio, notice that C.I.E z value.
  1588. // equal to (1.0 - x - y)
  1589. //
  1590. // Make sure Yr + Yg + Yb = 1.0, this may happened when ruound off
  1591. // durning the computation, we will add the difference (at most it will
  1592. // be 0.000002) to the Yg since this is brightnest color
  1593. //
  1594. CIE_Xr(Matrix3x3) = MulFD6(xr, RedXYZScale);
  1595. CIE_Xg(Matrix3x3) = MulFD6(xg, GreenXYZScale);
  1596. CIE_Xb(Matrix3x3) = MulFD6(xb, BlueXYZScale);
  1597. pCSXForm->Yrgb.R =
  1598. CIE_Yr(Matrix3x3) = MulFD6(yr, RedXYZScale);
  1599. pCSXForm->Yrgb.G =
  1600. CIE_Yg(Matrix3x3) = MulFD6(yg, GreenXYZScale);
  1601. pCSXForm->Yrgb.B =
  1602. CIE_Yb(Matrix3x3) = MulFD6(yb, BlueXYZScale);
  1603. CIE_Zr(Matrix3x3) = MulFD6(FD6_1 - xr - yr, RedXYZScale);
  1604. CIE_Zg(Matrix3x3) = MulFD6(FD6_1 - xg - yg, GreenXYZScale);
  1605. CIE_Zb(Matrix3x3) = MulFD6(FD6_1 - xb - yb, BlueXYZScale);
  1606. WhiteXYZ.X = CIE_Xr(Matrix3x3) + CIE_Xg(Matrix3x3) + CIE_Xb(Matrix3x3);
  1607. WhiteXYZ.Y = CIE_Yr(Matrix3x3) + CIE_Yg(Matrix3x3) + CIE_Yb(Matrix3x3);
  1608. WhiteXYZ.Z = CIE_Zr(Matrix3x3) + CIE_Zg(Matrix3x3) + CIE_Zb(Matrix3x3);
  1609. //
  1610. // If request a 3 x 3 transform matrix then save the result back
  1611. //
  1612. DBGP_IF(DBGP_CIEMATRIX,
  1613. DBGP("== RGB -> XYZ 3x3 Matrix ==== White = (%s, %s) =="
  1614. ARGFD6s(xw) ARGFD6s(yw));
  1615. DBGP("[Xr Xg Xb] = [%s %s %s]" ARGFD6l(CIE_Xr(Matrix3x3))
  1616. ARGFD6l(CIE_Xg(Matrix3x3))
  1617. ARGFD6l(CIE_Xb(Matrix3x3)));
  1618. DBGP("[Yr Yg Yb] = [%s %s %s]" ARGFD6l(CIE_Yr(Matrix3x3))
  1619. ARGFD6l(CIE_Yg(Matrix3x3))
  1620. ARGFD6l(CIE_Yb(Matrix3x3)));
  1621. DBGP("[Zr Zg Zb] = [%s %s %s]" ARGFD6l(CIE_Zr(Matrix3x3))
  1622. ARGFD6l(CIE_Zg(Matrix3x3))
  1623. ARGFD6l(CIE_Zb(Matrix3x3)));
  1624. DBGP("===============================================");
  1625. );
  1626. DBGP_IF(DBGP_CIEMATRIX,
  1627. DBGP("RGB->XYZ: [Xw=%s, Yw=%s, Zw=%s]"
  1628. ARGFD6l(WhiteXYZ.X)
  1629. ARGFD6l(WhiteXYZ.Y)
  1630. ARGFD6l(WhiteXYZ.Z)));
  1631. if (IlluminantIndex < 0) {
  1632. pCSXForm->M3x3 = Matrix3x3;
  1633. ComputeInverseMatrix3x3(&(pCSXForm->M3x3), &Matrix3x3);
  1634. DBGP_IF(DBGP_CIEMATRIX,
  1635. DBGP("======== XYZ -> RGB INVERSE 3x3 Matrix ========");
  1636. DBGP(" -1");
  1637. DBGP("[Xr Xg Xb] = [%s %s %s]" ARGFD6l(CIE_Xr(Matrix3x3))
  1638. ARGFD6l(CIE_Xg(Matrix3x3))
  1639. ARGFD6l(CIE_Xb(Matrix3x3)));
  1640. DBGP("[Yr Yg Yb] = [%s %s %s]"
  1641. ARGFD6l(CIE_Yr(Matrix3x3))
  1642. ARGFD6l(CIE_Yg(Matrix3x3))
  1643. ARGFD6l(CIE_Yb(Matrix3x3)));
  1644. DBGP("[Zr Zg Zb] = [%s %s %s]"
  1645. ARGFD6l(CIE_Zr(Matrix3x3))
  1646. ARGFD6l(CIE_Zg(Matrix3x3))
  1647. ARGFD6l(CIE_Zb(Matrix3x3)));
  1648. DBGP("===============================================");
  1649. );
  1650. }
  1651. if ((pCSXForm->YW = WhiteXYZ.Y) != NORMALIZED_WHITE) {
  1652. if (WhiteXYZ.Y) {
  1653. WhiteXYZ.X = DivFD6(WhiteXYZ.X, WhiteXYZ.Y);
  1654. WhiteXYZ.Z = DivFD6(WhiteXYZ.Z, WhiteXYZ.Y);
  1655. } else {
  1656. WhiteXYZ.X =
  1657. WhiteXYZ.Z = FD6_0;
  1658. }
  1659. WhiteXYZ.Y = NORMALIZED_WHITE;
  1660. }
  1661. switch (pDCI->ClrXFormBlock.ColorSpace) {
  1662. case CIELUV_1976:
  1663. //
  1664. // U' = 4X / (X + 15Y + 3Z)
  1665. // V' = 9Y / (X + 15Y + 3Z)
  1666. //
  1667. // U* = 13 x L x (U' - Uw)
  1668. // V* = 13 x L x (V' - Vw)
  1669. //
  1670. //
  1671. DiffRGB = WhiteXYZ.X + FD6xL(WhiteXYZ.Y, 15) + FD6xL(WhiteXYZ.Z, 3);
  1672. AUw = DivFD6(FD6xL(WhiteXYZ.X, 4), DiffRGB);
  1673. BVw = DivFD6(FD6xL(WhiteXYZ.Y, 9), DiffRGB);
  1674. break;
  1675. case CIELAB_1976:
  1676. default:
  1677. //
  1678. // CIELAB 1976 L*A*B*
  1679. //
  1680. // A* = 500 x (fX - fY)
  1681. // B* = 200 x (fY - fZ)
  1682. //
  1683. // 1/3
  1684. // fX = (X/Xw) (X/Xw) > 0.008856
  1685. // fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
  1686. //
  1687. // 1/3
  1688. // fY = (Y/Yw) (Y/Yw) > 0.008856
  1689. // fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
  1690. //
  1691. // 1/3
  1692. // fZ = (Z/Zw) (Z/Zw) > 0.008856
  1693. // fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
  1694. //
  1695. AUw =
  1696. BVw = FD6_0;
  1697. break;
  1698. }
  1699. pCSXForm->M3x3 = Matrix3x3;
  1700. pCSXForm->WhiteXYZ = WhiteXYZ;
  1701. pCSXForm->AUw = AUw;
  1702. pCSXForm->BVw = BVw;
  1703. pCSXForm->xW = xw;
  1704. pCSXForm->yW = yw;
  1705. DBGP_IF(DBGP_CSXFORM,
  1706. DBGP("------- ComputeColorSpaceXForm: %s ---------"
  1707. ARG(pDbgCSName[pDCI->ClrXFormBlock.ColorSpace]));
  1708. DBGP(" White XYZ = (%s, %s, %s)" ARGFD6(WhiteXYZ.X, 1, 6)
  1709. ARGFD6(WhiteXYZ.Y, 1, 6)
  1710. ARGFD6(WhiteXYZ.Z, 1, 6));
  1711. DBGP(" AUw/BVw = %s / %s" ARGFD6(AUw, 1, 6) ARGFD6s(BVw));
  1712. DBGP(" White xyY = (%s, %s, %s)" ARGFD6(pCSXForm->xW, 1, 6)
  1713. ARGFD6(pCSXForm->yW, 1, 6)
  1714. ARGFD6(pCSXForm->YW, 1, 6));
  1715. DBGP("------------------------------------------------");
  1716. );
  1717. }
  1718. PCACHERGBTOXYZ
  1719. HTENTRY
  1720. CacheRGBToXYZ(
  1721. PCACHERGBTOXYZ pCRTX,
  1722. PFD6XYZ pFD6XYZ,
  1723. LPDWORD pNewChecksum,
  1724. PDEVCLRADJ pDevClrAdj
  1725. )
  1726. /*++
  1727. Routine Description:
  1728. This function cached the RGB color input to XYZ
  1729. Arguments:
  1730. pCRTX - Pointer to the CACHERGBTOXYZ
  1731. pFD6XYZ - Pointer to the local cached RGB->XYZ table (will be updated)
  1732. pNewChecksum- Pointer to the new checksum computed
  1733. pDevClrAdj - Pointer to DEVCLRADJ,
  1734. Return Value:
  1735. if a cahced is copied to the pFD6XYZ then NULL will be returned, otherwise
  1736. the cache table is computed on the pFD6XYZ and pCRTX returned
  1737. TRUE if cached XYZ info is generate, false otherwise, only possible failure
  1738. is that memory allocation failed.
  1739. Author:
  1740. 08-May-1992 Fri 13:21:03 created -by- Daniel Chou (danielc)
  1741. Revision History:
  1742. 09-Mar-1995 Thu 10:50:13 updated -by- Daniel Chou (danielc)
  1743. DO NOT TURN OFF DCA_NEGATIVE in this function
  1744. --*/
  1745. {
  1746. PMATRIX3x3 pRGBToXYZ;
  1747. PPRIMADJ pPrimAdj;
  1748. FD6 rgbX;
  1749. FD6 rgbY;
  1750. FD6 rgbZ;
  1751. FD6 PrimCur;
  1752. UINT PrimMax;
  1753. UINT PrimInc;
  1754. DWORD Checksum;
  1755. UINT RGBIndex;
  1756. //
  1757. // Turn off the one we did not need any checksum for
  1758. //
  1759. pPrimAdj = &(pDevClrAdj->PrimAdj);
  1760. pRGBToXYZ = &(pPrimAdj->rgbCSXForm.M3x3);
  1761. Checksum = ComputeChecksum((LPBYTE)pRGBToXYZ, 'CXYZ', sizeof(MATRIX3x3));
  1762. if ((pCRTX->pFD6XYZ) &&
  1763. (pCRTX->Checksum == Checksum)) {
  1764. CopyMemory(pFD6XYZ, pCRTX->pFD6XYZ, pCRTX->SizeCRTX);
  1765. DBGP_IF(DBGP_CACHED_GAMMA,
  1766. DBGP("*** Use %u bytes CACHED RGB->XYZ Table ***"
  1767. ARGU(pCRTX->SizeCRTX)));
  1768. return(NULL);
  1769. }
  1770. *pNewChecksum = Checksum;
  1771. DBGP_IF(DBGP_CCT, DBGP("** Re-Compute %ld bytes RGB->XYZ xform table **"
  1772. ARGDW(pCRTX->SizeCRTX)));
  1773. PrimMax = (UINT)pCRTX->PrimMax;
  1774. for (RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
  1775. rgbX = pRGBToXYZ->m[X_INDEX][RGBIndex];
  1776. rgbY = pRGBToXYZ->m[Y_INDEX][RGBIndex];
  1777. rgbZ = pRGBToXYZ->m[Z_INDEX][RGBIndex];
  1778. DBGP_IF(DBGP_CACHED_GAMMA,
  1779. DBGP("CachedRGBToXYZ %u:%u, XYZ=%s:%s:%s"
  1780. ARGU(RGBIndex) ARGU(PrimMax)
  1781. ARGFD6(rgbX, 2, 6) ARGFD6(rgbY, 2, 6)
  1782. ARGFD6(rgbZ, 2, 6)));
  1783. for (PrimInc = 0; PrimInc <= PrimMax; PrimInc++, pFD6XYZ++) {
  1784. PrimCur = DivFD6((FD6)PrimInc, (FD6)PrimMax);
  1785. pFD6XYZ->X = MulFD6(rgbX, PrimCur);
  1786. pFD6XYZ->Y = MulFD6(rgbY, PrimCur);
  1787. pFD6XYZ->Z = MulFD6(rgbZ, PrimCur);
  1788. DBGP_IF(DBGP_CACHED_GAMMA,
  1789. DBGP("(%u:%3u): %s, XYZ=%s:%s:%s"
  1790. ARGU(RGBIndex) ARGU(PrimInc)
  1791. ARGFD6(PrimCur, 1, 6)
  1792. ARGFD6(pFD6XYZ->X, 1, 6)
  1793. ARGFD6(pFD6XYZ->Y, 1, 6)
  1794. ARGFD6(pFD6XYZ->Z, 1, 6)));
  1795. }
  1796. }
  1797. return(pCRTX);
  1798. }
  1799. #define RD_MIN_POWER (FD6)1500000
  1800. #define RD_MAX_POWER (FD6)2000000
  1801. #define GET_RD_MIN_PRIM(p, RD) \
  1802. { \
  1803. (p) = FD6_1 - DivFD6(p, RD.LMin); \
  1804. (p) = MulFD6(FD6_1 - Power(p, RD_MIN_POWER), RD.LMin); \
  1805. }
  1806. #define GET_RD_MAX_PRIM(p, RD) \
  1807. { \
  1808. (p) = DivFD6((p) - RD.LMax, FD6_1 - RD.LMax); \
  1809. (p) = RD.LMax + MulFD6(Power(p, RD_MAX_POWER), FD6_1 - RD.LMax); \
  1810. }
  1811. VOID
  1812. HTENTRY
  1813. ComputeRGBLUTAA(
  1814. PDEVICECOLORINFO pDCI,
  1815. PDEVCLRADJ pDevClrAdj,
  1816. PRGBLUTAA prgbLUT
  1817. )
  1818. /*++
  1819. Routine Description:
  1820. This function compute a RGB to Monochrome *L translation table.
  1821. Arguments:
  1822. pDCI - Pointer to the DEVICECOLORINFO
  1823. pDevClrAdj - Pointer to DEVCLRADJ, the DCA_NEGATIVE and DCA_HAS_SRC_GAMMA
  1824. flags in pDevClrAdj->PrimAdj.Flags will always be turn off
  1825. at return.
  1826. prgbLUT - Pointer to the RGBLUTAA buffer for computation
  1827. Return Value:
  1828. VOID
  1829. Author:
  1830. 05-Mar-1993 Fri 17:37:12 created -by- Daniel Chou (danielc)
  1831. Revision History:
  1832. --*/
  1833. {
  1834. LPDWORD pdw;
  1835. LPBYTE pbAB;
  1836. REGDATA RD;
  1837. PRIMADJ PrimAdj;
  1838. DEVMAPINFO DMI;
  1839. HTCOLORADJUSTMENT ca;
  1840. FD6 Prim;
  1841. FD6 PrimOrg;
  1842. FD6 PrimKDiv;
  1843. FD6 Mul;
  1844. FD6 SrcGamma;
  1845. FD6 DevGamma;
  1846. DWORD dwPrim;
  1847. DWORD PrimMask;
  1848. DWORD aMulAdd[3];
  1849. DWORD CurCA;
  1850. DWORD PrevCA;
  1851. FD6 aPrimMaxMul[3];
  1852. FD6 PrimMaxMul;
  1853. PFD6 pDenCMY[3];
  1854. PFD6 pDensity;
  1855. UINT Index;
  1856. UINT LeftShift;
  1857. UINT PrimIdx;
  1858. INT PrimCur;
  1859. PrimAdj = pDevClrAdj->PrimAdj;
  1860. ca = pDevClrAdj->ca;
  1861. DMI = pDevClrAdj->DMI;
  1862. pDevClrAdj->PrimAdj.Flags &= ~(DCA_HAS_SRC_GAMMA |
  1863. DCA_HAS_DEST_GAMMA |
  1864. DCA_HAS_BW_REF_ADJ |
  1865. DCA_HAS_CONTRAST_ADJ |
  1866. DCA_HAS_BRIGHTNESS_ADJ |
  1867. DCA_LOG_FILTER |
  1868. DCA_NEGATIVE |
  1869. DCA_DO_DEVCLR_XFORM);
  1870. ca.caColorfulness =
  1871. ca.caRedGreenTint = (PrimAdj.Flags & DCA_MONO_ONLY) ? 0xff : 0x00;
  1872. SET_CACHED_CMI_CA(pDevClrAdj->ca);
  1873. aPrimMaxMul[0] =
  1874. aPrimMaxMul[1] =
  1875. aPrimMaxMul[2] = FD6_1;
  1876. aMulAdd[0] =
  1877. aMulAdd[1] =
  1878. aMulAdd[2] = DMI.MulAdd;
  1879. pDenCMY[0] =
  1880. pDenCMY[1] =
  1881. pDenCMY[2] = NULL;
  1882. if (PrimAdj.Flags & DCA_RGBLUTAA_MONO) {
  1883. ASSERT(PrimAdj.Flags & DCA_NO_MAPPING_TABLE);
  1884. ASSERT(DMI.Mul[1] == GRAY_MAX_IDX);
  1885. ASSERT(PrimAdj.Flags & DCA_MONO_ONLY);
  1886. ASSERT(DMI.MulAdd == 0);
  1887. ASSERT(DMI.Flags & DMIF_GRAY);
  1888. DMI.Mul[0] = (DWORD)MulFD6(NTSC_R_INT, DMI.Mul[1]);
  1889. DMI.Mul[2] = (DWORD)MulFD6(NTSC_B_INT, DMI.Mul[1]);
  1890. DMI.Mul[1] -= (DMI.Mul[0] + DMI.Mul[2]);
  1891. DMI.DstOrder.Order[0] = 0;
  1892. DMI.DstOrder.Order[1] = 1;
  1893. DMI.DstOrder.Order[2] = 2;
  1894. DMI.LSft[0] =
  1895. DMI.LSft[1] =
  1896. DMI.LSft[2] = 0;
  1897. } else {
  1898. ASSERT(!(DMI.Flags & DMIF_GRAY));
  1899. if (PrimAdj.Flags & DCA_MASK8BPP) {
  1900. ASSERT((pDCI->Flags & (DCIF_USE_8BPP_BITMASK |
  1901. DCIF_MONO_8BPP_BITMASK)) ==
  1902. DCIF_USE_8BPP_BITMASK);
  1903. aPrimMaxMul[0] = pDCI->CMY8BPPMask.MaxMulY;
  1904. aPrimMaxMul[1] = pDCI->CMY8BPPMask.MaxMulM;
  1905. aPrimMaxMul[2] = pDCI->CMY8BPPMask.MaxMulC;
  1906. if (pDCI->Flags & DCIF_HAS_DENSITY) {
  1907. pDenCMY[0] = pDCI->CMY8BPPMask.DenY;
  1908. pDenCMY[1] = pDCI->CMY8BPPMask.DenM;
  1909. pDenCMY[2] = pDCI->CMY8BPPMask.DenC;
  1910. }
  1911. }
  1912. }
  1913. if (!(PrimAdj.Flags & DCA_REPLACE_BLACK)) {
  1914. DMI.BlackChk = FD6_1;
  1915. }
  1916. PrimMask = PrimAdj.Flags & (DCA_REPLACE_BLACK |
  1917. DCA_DO_DEVCLR_XFORM |
  1918. DCA_ALPHA_BLEND |
  1919. DCA_CONST_ALPHA |
  1920. DCA_NO_MAPPING_TABLE);
  1921. GET_CHECKSUM(PrimMask, PrimAdj.SrcGamma);
  1922. GET_CHECKSUM(PrimMask, PrimAdj.DevGamma);
  1923. GET_CHECKSUM(PrimMask, ca);
  1924. GET_CHECKSUM(PrimMask, DMI);
  1925. CurCA = (DWORD)pDCI->CurConstAlpha;
  1926. PrevCA = (DWORD)pDCI->PrevConstAlpha;
  1927. if (prgbLUT->Checksum != PrimMask) {
  1928. prgbLUT->Checksum = PrimMask;
  1929. PrevCA =
  1930. pDCI->PrevConstAlpha = AB_CONST_MAX + 1;
  1931. DBGP_IF(DBGP_RGBLUTAA,
  1932. DBGP("** Re-Compute %ld bytes of pLUT=%p, SG=%s:%s:%s, DG=%s:%s:%s **"
  1933. ARGDW(sizeof(RGBLUTAA))
  1934. ARGPTR(prgbLUT)
  1935. ARGFD6(PrimAdj.SrcGamma[0], 1, 4)
  1936. ARGFD6(PrimAdj.SrcGamma[1], 1, 4)
  1937. ARGFD6(PrimAdj.SrcGamma[2], 1, 4)
  1938. ARGFD6(PrimAdj.DevGamma[0], 1, 4)
  1939. ARGFD6(PrimAdj.DevGamma[1], 1, 4)
  1940. ARGFD6(PrimAdj.DevGamma[2], 1, 4)));
  1941. DBGP_IF(DBGP_RGBLUTAA,
  1942. DBGP("DMI.Mul=%08lx:%08lx:%08lx, %08lx, LSft=%ld:%ld:%ld"
  1943. ARGDW(DMI.Mul[0]) ARGDW(DMI.Mul[1]) ARGDW(DMI.Mul[2])
  1944. ARGDW(DMI.Mul[0] + DMI.Mul[1] + DMI.Mul[2])
  1945. ARGDW(DMI.LSft[0]) ARGDW(DMI.LSft[1]) ARGDW(DMI.LSft[2])));
  1946. if (PrimAdj.Flags & DCA_DO_DEVCLR_XFORM) {
  1947. RD = RegData[pDCI->ClrXFormBlock.RegDataIdx];
  1948. }
  1949. //
  1950. // Compute order BGR
  1951. //
  1952. Index = 3;
  1953. PrimKDiv = FD6_1 - DMI.BlackChk;
  1954. PrimMask = (DWORD)(DMI.MulAdd - 1);
  1955. pdw = (LPDWORD)prgbLUT->IdxBGR;
  1956. if ((PrimAdj.Flags & DCA_ALPHA_BLEND) &&
  1957. (!(DMI.Flags & DMIF_GRAY))) {
  1958. pbAB = (LPBYTE)pDCI->pAlphaBlendBGR;
  1959. } else {
  1960. pbAB = NULL;
  1961. }
  1962. while (Index--) {
  1963. SrcGamma = PrimAdj.SrcGamma[Index];
  1964. DevGamma = PrimAdj.DevGamma[Index];
  1965. PrimIdx = DMI.DstOrder.Order[Index];
  1966. PrimMaxMul = aPrimMaxMul[PrimIdx];
  1967. DMI.MulAdd = aMulAdd[PrimIdx];
  1968. LeftShift = DMI.LSft[PrimIdx];
  1969. Mul = DMI.Mul[PrimIdx];
  1970. pDensity = pDenCMY[PrimIdx];
  1971. PrimCur = -1;
  1972. DBGP_IF(DBGP_RGBLUTAA,
  1973. DBGP("Index=%ld: Mul=%08lx, LSft=%2ld [%08lx], PrimMaxMul=%s, MulAdd=%04lx"
  1974. ARGDW(Index) ARGDW(Mul) ARGDW(LeftShift)
  1975. ARGDW( ((Mul + DMI.MulAdd) & PrimMask) |
  1976. (((Mul + DMI.MulAdd) & ~PrimMask) << LeftShift))
  1977. ARGFD6(PrimMaxMul, 1, 6) ARGDW(DMI.MulAdd)));
  1978. while (++PrimCur < BF_GRAY_TABLE_COUNT) {
  1979. PrimOrg =
  1980. Prim = DivFD6((FD6)PrimCur, (FD6)(BF_GRAY_TABLE_COUNT - 1));
  1981. if (PrimAdj.Flags & DCA_HAS_SRC_GAMMA) {
  1982. Prim = Power(Prim, SrcGamma);
  1983. }
  1984. if (PrimAdj.Flags & DCA_HAS_BW_REF_ADJ) {
  1985. PRIM_BW_ADJ(Prim, PrimAdj);
  1986. }
  1987. if (PrimAdj.Flags & DCA_HAS_CONTRAST_ADJ) {
  1988. PRIM_CONTRAST(Prim, PrimAdj);
  1989. }
  1990. if (PrimAdj.Flags & DCA_HAS_BRIGHTNESS_ADJ) {
  1991. PRIM_BRIGHTNESS(Prim, PrimAdj);
  1992. }
  1993. if (PrimAdj.Flags & DCA_LOG_FILTER) {
  1994. PRIM_LOG_FILTER(Prim);
  1995. }
  1996. CLAMP_01(Prim);
  1997. if (PrimAdj.Flags & DCA_NEGATIVE) {
  1998. Prim = FD6_1 - Prim;
  1999. }
  2000. if (PrimAdj.Flags & DCA_DO_DEVCLR_XFORM) {
  2001. if (Prim <= RD.LMin) {
  2002. GET_RD_MIN_PRIM(Prim, RD);
  2003. Prim = REG_DMIN_ADD + 50 + MulFD6(Prim, RD.DMinMul);
  2004. } else if (Prim >= RD.LMax) {
  2005. GET_RD_MAX_PRIM(Prim, RD);
  2006. Prim = RD.DMaxAdd + 50 + MulFD6(Prim, RD.DMaxMul);
  2007. } else {
  2008. Prim = RD.DenAdd + 50 +
  2009. MulFD6(Log(CIE_L2I(Prim)), RD.DenMul);
  2010. }
  2011. Prim /= 100;
  2012. }
  2013. CLAMP_01(Prim);
  2014. if (PrimAdj.Flags & DCA_HAS_DEST_GAMMA) {
  2015. Prim = Power(Prim, DevGamma);
  2016. }
  2017. if (pbAB) {
  2018. *pbAB++ = (BYTE)MulFD6(Prim, 0xFF);
  2019. Prim = PrimOrg;
  2020. }
  2021. if (!(DMI.Flags & DMIF_GRAY)) {
  2022. Prim = FD6_1 - Prim;
  2023. }
  2024. if (pDensity) {
  2025. FD6 p1;
  2026. FD6 p2;
  2027. DWORD Idx;
  2028. p2 = FD6_0;
  2029. Idx = ~0;
  2030. do {
  2031. p1 = p2;
  2032. p2 = pDensity[++Idx];
  2033. } while (Prim > p2);
  2034. dwPrim = MulFD6(DivFD6(Prim - p1, p2 - p1), MAX_BGR_IDX) +
  2035. (Idx << 12) + DMI.MulAdd;
  2036. } else {
  2037. dwPrim = (DWORD)MulFD6(Prim, Mul) + DMI.MulAdd;
  2038. }
  2039. dwPrim = (DWORD)MulFD6(dwPrim & PrimMask, PrimMaxMul) |
  2040. ((DWORD)(dwPrim & ~PrimMask) << LeftShift);
  2041. if (Prim > DMI.BlackChk) {
  2042. dwPrim |= (DWORD)MulFD6(Power(DivFD6(Prim - DMI.BlackChk,
  2043. PrimKDiv),
  2044. K_REP_POWER),
  2045. MAX_K_IDX) << 21;
  2046. }
  2047. *pdw++ = dwPrim;
  2048. }
  2049. for (PrimCur = 0; PrimCur < BF_GRAY_TABLE_COUNT; PrimCur++) {
  2050. DBGP_IF(DBGP_RGBLUTAA,
  2051. DBGP("COLOR(%04lx:%4ld) %3u = %08lx"
  2052. ARGU(Index) ARGU(Mul) ARGU(PrimCur)
  2053. ARGDW(*(pdw - BF_GRAY_TABLE_COUNT + PrimCur))));
  2054. }
  2055. }
  2056. } else {
  2057. DBGP_IF(DBGP_RGBLUTAA, DBGP("** Used Cached %ld bytes pLUT **"
  2058. ARGDW(sizeof(RGBLUTAA))));
  2059. }
  2060. if ((PrimAdj.Flags & (DCA_ALPHA_BLEND | DCA_CONST_ALPHA)) ==
  2061. (DCA_ALPHA_BLEND | DCA_CONST_ALPHA)) {
  2062. if (PrevCA != CurCA) {
  2063. LPWORD pwBGR;
  2064. LPWORD pCA;
  2065. DBGP_IF(DBGP_CONST_ALPHA,
  2066. DBGP("** %hs ConstAlpha=%3ld: Re-compute"
  2067. ARGPTR((DMI.Flags & DMIF_GRAY) ? "GRAY" : "STD")
  2068. ARGDW(CurCA)));
  2069. pbAB = pDCI->pAlphaBlendBGR;
  2070. pwBGR = (LPWORD)(pbAB + AB_BGR_SIZE);
  2071. pCA = (LPWORD)((LPBYTE)pwBGR + AB_BGR_CA_SIZE);
  2072. pDCI->CurConstAlpha =
  2073. pDCI->PrevConstAlpha = (WORD)CurCA;
  2074. PrevCA = (DMI.Flags & DMIF_GRAY) ? 0xFFFF : 0xFF00;
  2075. CurCA = (((CurCA * PrevCA) + 0x7F) / 0xFF);
  2076. PrevCA -= CurCA;
  2077. for (Index = 0, dwPrim = 0x7F;
  2078. Index < 256;
  2079. Index++, dwPrim += CurCA) {
  2080. pCA[Index] = (WORD)(dwPrim / 255);
  2081. }
  2082. if (DMI.Flags & DMIF_GRAY) {
  2083. CopyMemory(pwBGR, pCA, sizeof(WORD) * 256);
  2084. } else {
  2085. Index = 256 * 3;
  2086. while (Index--) {
  2087. *pwBGR++ = pCA[*pbAB++];
  2088. }
  2089. }
  2090. for (Index = 0, dwPrim = 0x7F;
  2091. Index < 256;
  2092. Index++, dwPrim += PrevCA) {
  2093. pCA[Index] = (WORD)(dwPrim / 255);
  2094. }
  2095. } else {
  2096. DBGP_IF(DBGP_CONST_ALPHA,
  2097. DBGP("** %hs ConstAlpha=%3ld: Use Cache"
  2098. ARGPTR((DMI.Flags & DMIF_GRAY) ? "GRAY" : "STD")
  2099. ARGDW(CurCA)));
  2100. }
  2101. }
  2102. DBGP_IF(DBGP_RGBLUTAA,
  2103. DBGP("ComputeRGBLUTAA: PrimAdj.Flags=%08lx"
  2104. ARGDW(pDevClrAdj->PrimAdj.Flags)));
  2105. }
  2106. #if NO_NEGATIVE_RGB_SCALE
  2107. VOID
  2108. HTENTRY
  2109. ScaleRGB(
  2110. PFD6 pRGB
  2111. )
  2112. /*++
  2113. Routine Description:
  2114. This function scale out of range RGB back into range and taking the
  2115. lumminance of the color into consideration.
  2116. if any of RGB is less then 0.0 then it will first clamp that to 0.0 and
  2117. it only scale if any of RGB is greater then 1.0
  2118. Arguments:
  2119. pRGB - Pointer to RGB (FD6) prims to be adjust
  2120. Return Value:
  2121. VOID
  2122. Author:
  2123. 08-Mar-1995 Wed 19:19:33 created -by- Daniel Chou (danielc)
  2124. Revision History:
  2125. --*/
  2126. {
  2127. PFD6 pRGBTmp;
  2128. FD6 MaxClr;
  2129. INT Idx;
  2130. DEFDBGVAR(FD6, RGBOld[3])
  2131. DEFDBGVAR(BOOL, Negative = FALSE)
  2132. Idx = 3;
  2133. pRGBTmp = pRGB;
  2134. MaxClr = FD6_1;
  2135. while (Idx--) {
  2136. FD6 CurClr;
  2137. //
  2138. // Firstable Clamp the negative component
  2139. //
  2140. if ((CurClr = *pRGBTmp) < FD6_0) {
  2141. *pRGBTmp = FD6_0;
  2142. SETDBGVAR(Negative, TRUE);
  2143. } else if (CurClr > MaxClr) {
  2144. MaxClr = CurClr;
  2145. }
  2146. ++pRGBTmp;
  2147. SETDBGVAR(RGBOld[Idx], CurClr);
  2148. }
  2149. if (MaxClr > FD6_1) {
  2150. //
  2151. // Now Scale it
  2152. //
  2153. *pRGB++ = DivFD6(*pRGB, MaxClr);
  2154. *pRGB++ = DivFD6(*pRGB, MaxClr);
  2155. *pRGB = DivFD6(*pRGB, MaxClr);
  2156. DBGP_IF(DBGP_SCALE_RGB,
  2157. DBGP("ScaleRGB: %s:%s:%s -> %s:%s:%s, Max=%s%s"
  2158. ARGFD6(RGBOld[2], 1, 6)
  2159. ARGFD6(RGBOld[1], 1, 6)
  2160. ARGFD6(RGBOld[0], 1, 6)
  2161. ARGFD6(*(pRGB - 2), 1, 6)
  2162. ARGFD6(*(pRGB - 1), 1, 6)
  2163. ARGFD6(*(pRGB ), 1, 6)
  2164. ARGFD6(MaxClr, 1, 6)
  2165. ARG((Negative) ? "*NEG CLAMP*" : "")));
  2166. } else {
  2167. DBGP_IF(DBGP_SCALE_RGB,
  2168. {
  2169. if (Negative) {
  2170. DBGP("*NEG CLAMP ONLY* ScaleRGB: %s:%s:%s -> %s:%s:%s"
  2171. ARGFD6(RGBOld[2], 1, 6)
  2172. ARGFD6(RGBOld[1], 1, 6)
  2173. ARGFD6(RGBOld[0], 1, 6)
  2174. ARGFD6(*(pRGB ), 1, 6)
  2175. ARGFD6(*(pRGB + 1), 1, 6)
  2176. ARGFD6(*(pRGB + 2), 1, 6));
  2177. }
  2178. }
  2179. )
  2180. }
  2181. }
  2182. #else
  2183. VOID
  2184. HTENTRY
  2185. ScaleRGB(
  2186. PFD6 pRGB,
  2187. PFD6 pYrgb
  2188. )
  2189. /*++
  2190. Routine Description:
  2191. This function scale out of range RGB back into range and taking the
  2192. lumminance of the color into consideration.
  2193. if any of RGB is less then 0.0 then it will first clamp that to 0.0 and
  2194. it only scale if any of RGB is greater then 1.0
  2195. Arguments:
  2196. pRGB - Pointer to RGB (FD6) prims to be adjust
  2197. pYrgb - Pinter to the Luminance (FD6) of the RGB, if NULL then it is not
  2198. used in the computation
  2199. Return Value:
  2200. VOID
  2201. Author:
  2202. 08-Mar-1995 Wed 19:19:33 created -by- Daniel Chou (danielc)
  2203. Revision History:
  2204. --*/
  2205. {
  2206. FD6 MaxClr = FD6_1;
  2207. FD6 MinClr = FD6_10;
  2208. FD6 RGBNew[3];
  2209. FD6 RGBOld[3];
  2210. if ((RGBOld[0] = pRGB[0]) > (RGBOld[1] = pRGB[1])) {
  2211. MaxClr = RGBOld[0];
  2212. MinClr = RGBOld[1];
  2213. } else {
  2214. MaxClr = RGBOld[1];
  2215. MinClr = RGBOld[0];
  2216. }
  2217. if ((RGBOld[2] = pRGB[2]) > MaxClr) {
  2218. MaxClr = RGBOld[2];
  2219. }
  2220. if (RGBOld[2] < MinClr) {
  2221. MinClr = RGBOld[2];
  2222. }
  2223. if ((MaxClr <= FD6_1) && (MinClr >= FD6_0)) {
  2224. return;
  2225. }
  2226. if (MinClr >= FD6_1) {
  2227. DBGP_IF((DBGP_SCALE_RGB | DBGP_SCALE_RGB),
  2228. DBGP("** RGB %s:%s:%s is too LIGHT make it WHITE"
  2229. ARGFD6(RGBOld[0], 1, 6)
  2230. ARGFD6(RGBOld[1], 1, 6)
  2231. ARGFD6(RGBOld[2], 1, 6)));
  2232. pRGB[0] =
  2233. pRGB[1] =
  2234. pRGB[2] = FD6_1;
  2235. return;
  2236. }
  2237. if (MaxClr <= FD6_0) {
  2238. DBGP_IF((DBGP_SCALE_RGB | DBGP_SCALE_RGB),
  2239. DBGP("** RGB %s:%s:%s is too DARK make it BLACK"
  2240. ARGFD6(RGBOld[0], 1, 6)
  2241. ARGFD6(RGBOld[1], 1, 6)
  2242. ARGFD6(RGBOld[2], 1, 6)));
  2243. pRGB[0] =
  2244. pRGB[1] =
  2245. pRGB[2] = FD6_0;
  2246. return;
  2247. }
  2248. if (MaxClr < FD6_1) {
  2249. MaxClr = FD6_1;
  2250. }
  2251. if (MinClr > FD6_0) {
  2252. MinClr = FD6_0;
  2253. }
  2254. MaxClr -= MinClr;
  2255. RGBNew[0] = DivFD6(RGBOld[0] - MinClr, MaxClr);
  2256. RGBNew[1] = DivFD6(RGBOld[1] - MinClr, MaxClr);
  2257. RGBNew[2] = DivFD6(RGBOld[2] - MinClr, MaxClr);
  2258. DBGP_IF(DBGP_SCALE_RGB,
  2259. DBGP("ScaleRGB: %s:%s:%s -> %s:%s:%s, (%s/%s, %s)"
  2260. ARGFD6(RGBOld[0], 1, 6)
  2261. ARGFD6(RGBOld[1], 1, 6)
  2262. ARGFD6(RGBOld[2], 1, 6)
  2263. ARGFD6(RGBNew[0], 1, 6)
  2264. ARGFD6(RGBNew[1], 1, 6)
  2265. ARGFD6(RGBNew[2], 1, 6)
  2266. ARGFD6(MinClr, 1, 6)
  2267. ARGFD6(MaxClr + MinClr, 1, 6)
  2268. ARGFD6(MaxClr, 1, 6)));
  2269. if (pYrgb) {
  2270. FD6 OldY;
  2271. if ((OldY = MulFD6(RGBOld[0], pYrgb[0]) +
  2272. MulFD6(RGBOld[1], pYrgb[1]) +
  2273. MulFD6(RGBOld[2], pYrgb[2])) <= FD6_0) {
  2274. DBGP_IF(DBGP_SHOWXFORM_RGB,
  2275. DBGP("OldY <= 0.0 (%s), Ignore and NO Y Scale"
  2276. ARGFD6(OldY, 2, 6)));
  2277. } else if (OldY >= FD6_1) {
  2278. DBGP_IF(DBGP_SHOWXFORM_RGB,
  2279. DBGP("OldY >= 1.0 (%s), Ignore and NO Y Scale"
  2280. ARGFD6(OldY, 2, 6)));
  2281. } else {
  2282. FD6 NewY;
  2283. FD6 CurRatio;
  2284. FD6 MaxRatio;
  2285. NewY = MulFD6(RGBNew[0], pYrgb[0]) +
  2286. MulFD6(RGBNew[1], pYrgb[1]) +
  2287. MulFD6(RGBNew[2], pYrgb[2]);
  2288. DBGP_IF(DBGP_SHOWXFORM_RGB,
  2289. DBGP("RGBOld=%s:%s:%s [Y=%s] --> New=%s:%s:%s [Y=%s]"
  2290. ARGFD6(pRGB[0], 1, 6)
  2291. ARGFD6(pRGB[1], 1, 6)
  2292. ARGFD6(pRGB[2], 1, 6)
  2293. ARGFD6(OldY, 1, 6)
  2294. ARGFD6(RGBNew[0], 1, 6)
  2295. ARGFD6(RGBNew[1], 1, 6)
  2296. ARGFD6(RGBNew[2], 1, 6)
  2297. ARGFD6(NewY, 1, 6)));
  2298. if (OldY != NewY) {
  2299. MaxClr = (RGBNew[0] > RGBNew[1]) ? RGBNew[0] : RGBNew[1];
  2300. if (RGBNew[2] > MaxClr) {
  2301. MaxClr = RGBNew[2];
  2302. }
  2303. MaxRatio = DivFD6(FD6_1, MaxClr);
  2304. CurRatio = DivFD6(OldY, NewY);
  2305. if (CurRatio > MaxRatio) {
  2306. CurRatio = MaxRatio;
  2307. }
  2308. RGBNew[0] = MulFD6(RGBNew[0], CurRatio);
  2309. RGBNew[1] = MulFD6(RGBNew[1], CurRatio);
  2310. RGBNew[2] = MulFD6(RGBNew[2], CurRatio);
  2311. DBGP_IF(DBGP_SHOWXFORM_RGB,
  2312. DBGP("CurRatio%s, MaxRatio=%s, MaxClr=%s"
  2313. ARGFD6(CurRatio, 1, 6)
  2314. ARGFD6(MaxRatio, 1, 6)
  2315. ARGFD6(MaxClr, 1, 6)));
  2316. }
  2317. }
  2318. }
  2319. //
  2320. // Save back and return
  2321. //
  2322. pRGB[0] = RGBNew[0];
  2323. pRGB[1] = RGBNew[1];
  2324. pRGB[2] = RGBNew[2];
  2325. }
  2326. #endif
  2327. LONG
  2328. HTENTRY
  2329. ComputeBGRMappingTable(
  2330. PDEVICECOLORINFO pDCI,
  2331. PDEVCLRADJ pDevClrAdj,
  2332. PCOLORTRIAD pSrcClrTriad,
  2333. PBGR8 pbgr
  2334. )
  2335. /*++
  2336. Routine Description:
  2337. This functions set up all the DECI4 value in PRIMRGB, PRIMCMY with
  2338. PowerGamma, Brightness, Contrast adjustment and optionally to transform
  2339. to C.I.E. color space and/or do the Colorfulness adjustment.
  2340. Arguments:
  2341. pDCI - Pointer to computed DEVICECOLORINFO
  2342. pDevClrAdj - Pointer to the pre-computed DEVCLRADJ data structure.
  2343. pSrcClrTriad - Pointer to the COLORTRIAD strcutrue for computation
  2344. pbgr - Pointer to the storage for computed BGR table
  2345. Return Value:
  2346. Return value LONG
  2347. Count of table generated, if < 0 then it is an error number
  2348. Author:
  2349. 30-Jan-1991 Wed 13:31:58 created -by- Daniel Chou (danielc)
  2350. Revision History:
  2351. 06-Feb-1992 Thu 21:39:46 updated -by- Daniel Chou (danielc)
  2352. Rewrite!
  2353. 02-Feb-1994 Wed 17:33:55 updated -by- Daniel Chou (danielc)
  2354. Remove unreferenced/unused variable L
  2355. 10-May-1994 Tue 11:24:16 updated -by- Daniel Chou (danielc)
  2356. Bug# 13329, Memory Leak, Free Up pR_XYZ which I fogot to free it after
  2357. allocated it.
  2358. 17-Dec-1998 Thu 16:33:16 updated -by- Daniel Chou (danielc)
  2359. Re-organized so it use pbgr now, and it will only generate for color
  2360. 15-Feb-1999 Mon 15:40:03 updated -by- Daniel Chou (danielc)
  2361. Re-do it only BGR 3 bytes for each entry, and it will generate both
  2362. color or gray scale conversion, all color mapping for coloradjustment
  2363. is done here, this includes internal ICM (when external icm is off)
  2364. --*/
  2365. {
  2366. PFD6 pPrimA;
  2367. PFD6 pPrimB;
  2368. PFD6 pPrimC;
  2369. LPBYTE pSrcPrims;
  2370. PCACHERGBTOXYZ pCRTX;
  2371. PFD6XYZ pR_XYZ = NULL;
  2372. PFD6XYZ pG_XYZ;
  2373. PFD6XYZ pB_XYZ;
  2374. COLORTRIAD SrcClrTriad;
  2375. PMATRIX3x3 pCMYDyeMasks;
  2376. DWORD Loop;
  2377. DWORD CRTXChecksum;
  2378. DWORD PrimAdjFlags;
  2379. FD6 Prim[3];
  2380. FD6 X;
  2381. FD6 Y;
  2382. FD6 Z;
  2383. FD6 AU;
  2384. FD6 BV;
  2385. FD6 U1;
  2386. FD6 V1;
  2387. FD6 p0;
  2388. FD6 p1;
  2389. FD6 p2;
  2390. FD6 C;
  2391. FD6 W;
  2392. FD6 AutoPrims[3];
  2393. MULDIVPAIR MDPairs[4];
  2394. MULDIVPAIR AUMDPairs[3];
  2395. MULDIVPAIR BVMDPairs[3];
  2396. RGBORDER RGBOrder;
  2397. INT TempI;
  2398. INT TempJ;
  2399. BYTE DataSet[8];
  2400. DEFDBGVAR(WORD, ClrNo)
  2401. DEFDBGVAR(BYTE, dbgR)
  2402. DEFDBGVAR(BYTE, dbgG)
  2403. DEFDBGVAR(BYTE, dbgB)
  2404. #define _SrcPrimType DataSet[ 0]
  2405. #define _DevBytesPerPrimary DataSet[ 1]
  2406. #define _DevBytesPerEntry DataSet[ 2]
  2407. #define _ColorSpace DataSet[ 3]
  2408. #define _fX p0
  2409. #define _fY p1
  2410. #define _fZ p2
  2411. #define _X15Y3Z C
  2412. #define _L13 W
  2413. SETDBGVAR(ClrNo, 0);
  2414. if (pSrcClrTriad) {
  2415. SrcClrTriad = *pSrcClrTriad;
  2416. } else {
  2417. SrcClrTriad.Type = COLOR_TYPE_RGB;
  2418. SrcClrTriad.BytesPerPrimary = 0;
  2419. SrcClrTriad.BytesPerEntry = 0;
  2420. SrcClrTriad.PrimaryOrder = PRIMARY_ORDER_RGB;
  2421. SrcClrTriad.PrimaryValueMax = 0xFF;
  2422. SrcClrTriad.ColorTableEntries = HT_RGB_CUBE_COUNT;
  2423. SrcClrTriad.pColorTable = (LPBYTE)&Prim[0];
  2424. }
  2425. if (SrcClrTriad.Type != COLOR_TYPE_RGB) {
  2426. return(HTERR_INVALID_COLOR_TYPE);
  2427. }
  2428. //
  2429. // Two possible cases:
  2430. //
  2431. // A: The transform is used for color adjustment only, this is for
  2432. // HT_AdjustColorTable API call
  2433. //
  2434. // B: The halftone is taking places, the final output will be either
  2435. // Prim1/2 or Prim1/2/3 and each primary must 1 byte long.
  2436. //
  2437. PrimAdjFlags = pDevClrAdj->PrimAdj.Flags;
  2438. ASSERT((PrimAdjFlags & (DCA_HAS_SRC_GAMMA |
  2439. DCA_HAS_DEST_GAMMA |
  2440. DCA_HAS_BW_REF_ADJ |
  2441. DCA_HAS_CONTRAST_ADJ |
  2442. DCA_HAS_BRIGHTNESS_ADJ |
  2443. DCA_LOG_FILTER |
  2444. DCA_NEGATIVE |
  2445. DCA_DO_DEVCLR_XFORM)) == 0);
  2446. //
  2447. // We will not do regression (source to destination mapping) for
  2448. //
  2449. // 1. ICM is ON
  2450. // 2. Subtractive with 24bpp
  2451. // 3. Additive surface.
  2452. //
  2453. if (pbgr) {
  2454. _DevBytesPerEntry = (BYTE)pDevClrAdj->DMI.CTSTDInfo.cbPrim;
  2455. _DevBytesPerPrimary = 1;
  2456. ASSERT(_DevBytesPerEntry == sizeof(BGR8));
  2457. } else {
  2458. return(HTERR_INVALID_COLOR_TYPE);
  2459. }
  2460. if (!(pSrcPrims = (LPBYTE)SrcClrTriad.pColorTable)) {
  2461. return(HTERR_INVALID_COLOR_TABLE);
  2462. }
  2463. //
  2464. // If the total color table entries is less than MIN_CCT_COLORS then
  2465. // we just compute the color directly
  2466. //
  2467. pCRTX = NULL;
  2468. DBGP_IF(DBGP_CCT,
  2469. DBGP("PrimAdjFlags=%08lx" ARGDW(PrimAdjFlags)));
  2470. if (SrcClrTriad.BytesPerPrimary) {
  2471. //
  2472. // Something passed
  2473. //
  2474. RGBOrder = SrcOrderTable[SrcClrTriad.PrimaryOrder];
  2475. pPrimA = &Prim[RGBOrder.Order[0]];
  2476. pPrimB = &Prim[RGBOrder.Order[1]];
  2477. pPrimC = &Prim[RGBOrder.Order[2]];
  2478. DBGP_IF(DBGP_PRIMARY_ORDER,
  2479. DBGP("SOURCE PrimaryOrder: %u [%u] - %u:%u:%u"
  2480. ARGU(SrcClrTriad.PrimaryOrder)
  2481. ARGU(RGBOrder.Index) ARGU(RGBOrder.Order[0])
  2482. ARGU(RGBOrder.Order[1]) ARGU(RGBOrder.Order[2])));
  2483. }
  2484. //
  2485. // Now compute the cache info
  2486. //
  2487. switch (SrcClrTriad.BytesPerPrimary) {
  2488. case 0:
  2489. SrcClrTriad.BytesPerEntry = 0; // stay there!!
  2490. _SrcPrimType = SRC_BF_HT_RGB;
  2491. SrcClrTriad.PrimaryValueMax = HT_RGB_MAX_COUNT - 1;
  2492. pCRTX = pDevClrAdj->pCRTXLevelRGB;
  2493. break;
  2494. case 1:
  2495. _SrcPrimType = SRC_TABLE_BYTE;
  2496. break;
  2497. case 2:
  2498. _SrcPrimType = SRC_TABLE_WORD;
  2499. break;
  2500. case 4:
  2501. _SrcPrimType = SRC_TABLE_DWORD;
  2502. break;
  2503. default:
  2504. return(INTERR_INVALID_SRCRGB_SIZE);
  2505. }
  2506. if (PrimAdjFlags & DCA_NEED_DYES_CORRECTION) {
  2507. pCMYDyeMasks = &(pDevClrAdj->pClrXFormBlock->CMYDyeMasks);
  2508. }
  2509. _ColorSpace = (BYTE)pDevClrAdj->pClrXFormBlock->ColorSpace;
  2510. if (((_ColorSpace == CIELUV_1976) &&
  2511. ((pDevClrAdj->PrimAdj.rgbCSXForm.xW !=
  2512. pDevClrAdj->PrimAdj.DevCSXForm.xW) ||
  2513. (pDevClrAdj->PrimAdj.rgbCSXForm.yW !=
  2514. pDevClrAdj->PrimAdj.DevCSXForm.yW))) ||
  2515. (PrimAdjFlags & (DCA_HAS_CLRSPACE_ADJ |
  2516. DCA_HAS_COLOR_ADJ |
  2517. DCA_HAS_TINT_ADJ))) {
  2518. TempI = 1;
  2519. TempJ = (_ColorSpace == CIELUV_1976) ? MULDIV_HAS_DIVISOR :
  2520. MULDIV_NO_DIVISOR;
  2521. C = FD6_1;
  2522. AU =
  2523. BV = (PrimAdjFlags & DCA_HAS_COLOR_ADJ) ?
  2524. pDevClrAdj->PrimAdj.Color : FD6_1;
  2525. if (PrimAdjFlags & DCA_HAS_TINT_ADJ) {
  2526. if (_ColorSpace == CIELAB_1976) {
  2527. AU = FD6xL(AU, 500);
  2528. BV = FD6xL(BV, 200);
  2529. }
  2530. TempI = 2;
  2531. TempJ = MULDIV_HAS_DIVISOR;
  2532. C = pDevClrAdj->PrimAdj.TintSinAngle;
  2533. AUMDPairs[2].Pair1.Mul = MulFD6(BV, -C);
  2534. BVMDPairs[2].Pair1.Mul = MulFD6(AU, C);
  2535. C = pDevClrAdj->PrimAdj.TintCosAngle;
  2536. MAKE_MULDIV_DVSR(AUMDPairs, (FD6)500000000);
  2537. MAKE_MULDIV_DVSR(BVMDPairs, (FD6)200000000);
  2538. }
  2539. AUMDPairs[1].Pair1.Mul = MulFD6(AU, C);
  2540. BVMDPairs[1].Pair1.Mul = MulFD6(BV, C);
  2541. MAKE_MULDIV_INFO(AUMDPairs, TempI, TempJ);
  2542. MAKE_MULDIV_INFO(BVMDPairs, TempI, TempJ);
  2543. }
  2544. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2545. DBGP("iUVw = %s,%s, iRefXYZ = %s, %s, %s"
  2546. ARGFD6(iUw, 1, 6)
  2547. ARGFD6(iVw, 1, 6)
  2548. ARGFD6(iRefXw, 1, 6)
  2549. ARGFD6(iRefYw, 1, 6)
  2550. ARGFD6(iRefZw, 1, 6)));
  2551. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2552. DBGP("oUVw = %s,%s, oRefXYZ = %s, %s, %s"
  2553. ARGFD6(oUw, 1, 6)
  2554. ARGFD6(oVw, 1, 6)
  2555. ARGFD6(oRefXw, 1, 6)
  2556. ARGFD6(oRefYw, 1, 6)
  2557. ARGFD6(oRefZw, 1, 6)));
  2558. if (pCRTX) {
  2559. DBGP_IF(DBGP_CCT,
  2560. DBGP("*** Allocate %u bytes RGB->XYZ xform table ***"
  2561. ARGU(pCRTX->SizeCRTX)));
  2562. if (pR_XYZ = (PFD6XYZ)HTAllocMem((LPVOID)pDCI,
  2563. HTMEM_RGBToXYZ,
  2564. NONZEROLPTR,
  2565. pCRTX->SizeCRTX)) {
  2566. Loop = (DWORD)(pCRTX->PrimMax + 1);
  2567. //
  2568. // Save current flags back before calling, since CachedRGBToXYZ
  2569. // may change this flags for DCA_xxx
  2570. //
  2571. pCRTX = CacheRGBToXYZ(pCRTX,
  2572. pR_XYZ,
  2573. &CRTXChecksum,
  2574. pDevClrAdj);
  2575. pG_XYZ = pR_XYZ + Loop;
  2576. pB_XYZ = pG_XYZ + Loop;
  2577. SrcClrTriad.PrimaryValueMax = 0;
  2578. DBGP_IF(DBGP_CCT, DBGP("*** Has RGB->XYZ xform table ***"));
  2579. } else {
  2580. DBGP_IF(DBGP_CCT, DBGP("Allocate RGB->XYZ xform table failed !!"));
  2581. }
  2582. }
  2583. if (SrcClrTriad.PrimaryValueMax == (LONG)FD6_1) {
  2584. SrcClrTriad.PrimaryValueMax = 0;
  2585. }
  2586. //
  2587. // Starting the big Loop, reset AutoCur = AutoMax so it recycle back to
  2588. // 0:0:0
  2589. //
  2590. MAKE_MULDIV_SIZE(MDPairs, 3);
  2591. MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
  2592. AutoPrims[0] =
  2593. AutoPrims[1] =
  2594. AutoPrims[2] = FD6_0;
  2595. Loop = SrcClrTriad.ColorTableEntries;
  2596. DBGP_IF(DBGP_CCT,
  2597. DBGP("Compute %ld COLOR of %s type [%p]"
  2598. ARGDW(Loop)
  2599. ARG(pSrcPrimTypeName[_SrcPrimType])
  2600. ARGPTR(pSrcPrims)));
  2601. //
  2602. // 0. Get The source prim into the Prim[]
  2603. //
  2604. while (Loop--) {
  2605. switch (_SrcPrimType) {
  2606. case SRC_BF_HT_RGB:
  2607. //
  2608. // This format always in BGR order
  2609. //
  2610. Prim[0] = AutoPrims[0]; // R
  2611. Prim[1] = AutoPrims[1]; // G
  2612. Prim[2] = AutoPrims[2]; // B
  2613. if (++AutoPrims[0] >= (FD6)HT_RGB_MAX_COUNT) {
  2614. AutoPrims[0] = FD6_0;
  2615. if (++AutoPrims[1] >= (FD6)HT_RGB_MAX_COUNT) {
  2616. AutoPrims[1] = FD6_0;
  2617. if (++AutoPrims[2] >= (FD6)HT_RGB_MAX_COUNT) {
  2618. AutoPrims[2] = FD6_0;
  2619. }
  2620. }
  2621. }
  2622. DBGP_IF(DBGP_SHOWXFORM_ALL, DBGP("HT555: Prim[3]= %2ld:%2ld:%2ld, %s:%s:%s, (%ld / %ld)"
  2623. ARGDW(Prim[0])
  2624. ARGDW(Prim[1])
  2625. ARGDW(Prim[2])
  2626. ARGFD6(DivFD6(Prim[0], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
  2627. ARGFD6(DivFD6(Prim[1], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
  2628. ARGFD6(DivFD6(Prim[2], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
  2629. ARGDW(HT_RGB_MAX_COUNT)
  2630. ARGDW(SrcClrTriad.PrimaryValueMax)));
  2631. break;
  2632. case SRC_TABLE_BYTE:
  2633. *pPrimA = (FD6)(*(LPBYTE)(pSrcPrims ));
  2634. *pPrimB = (FD6)(*(LPBYTE)(pSrcPrims + (sizeof(BYTE) * 1)));
  2635. *pPrimC = (FD6)(*(LPBYTE)(pSrcPrims + (sizeof(BYTE) * 2)));
  2636. break;
  2637. case SRC_TABLE_WORD:
  2638. *pPrimA = (FD6)(*(LPSHORT)(pSrcPrims ));
  2639. *pPrimB = (FD6)(*(LPSHORT)(pSrcPrims + (sizeof(SHORT) * 1)));
  2640. *pPrimC = (FD6)(*(LPSHORT)(pSrcPrims + (sizeof(SHORT) * 2)));
  2641. break;
  2642. case SRC_TABLE_DWORD:
  2643. *pPrimA = (FD6)(*(PFD6)(pSrcPrims ));
  2644. *pPrimB = (FD6)(*(PFD6)(pSrcPrims + (sizeof(FD6) * 1)));
  2645. *pPrimC = (FD6)(*(PFD6)(pSrcPrims + (sizeof(FD6) * 2)));
  2646. break;
  2647. }
  2648. SETDBGVAR(dbgR, (BYTE)Prim[0]);
  2649. SETDBGVAR(dbgG, (BYTE)Prim[1]);
  2650. SETDBGVAR(dbgB, (BYTE)Prim[2]);
  2651. pSrcPrims += SrcClrTriad.BytesPerEntry;
  2652. //
  2653. // 1. First convert the Input value to FD6
  2654. //
  2655. if (SrcClrTriad.PrimaryValueMax) {
  2656. Prim[0] = DivFD6(Prim[0], SrcClrTriad.PrimaryValueMax);
  2657. Prim[1] = DivFD6(Prim[1], SrcClrTriad.PrimaryValueMax);
  2658. Prim[2] = DivFD6(Prim[2], SrcClrTriad.PrimaryValueMax);
  2659. }
  2660. //
  2661. // 2: Transform from RGB (gamma correction) -> XYZ -> L*A*B* or L*U*V*
  2662. // This only done if any of DCA_HAS_COLOR_ADJ or DCA_HAS_TINT_ADJ
  2663. //
  2664. if (PrimAdjFlags & (DCA_HAS_CLRSPACE_ADJ |
  2665. DCA_HAS_COLOR_ADJ |
  2666. DCA_HAS_TINT_ADJ)) {
  2667. // If we only doing monochrome, then we only need Y/L pair only,
  2668. // else convert it to the XYZ/LAB/LUV
  2669. //
  2670. if (pR_XYZ) {
  2671. X = pR_XYZ[Prim[0]].X +
  2672. pG_XYZ[Prim[1]].X +
  2673. pB_XYZ[Prim[2]].X;
  2674. Y = pR_XYZ[Prim[0]].Y +
  2675. pG_XYZ[Prim[1]].Y +
  2676. pB_XYZ[Prim[2]].Y;
  2677. Z = pR_XYZ[Prim[0]].Z +
  2678. pG_XYZ[Prim[1]].Z +
  2679. pB_XYZ[Prim[2]].Z;
  2680. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2681. DBGP("Yrgb: %s:%s:%s"
  2682. ARGFD6(pR_XYZ[Prim[0]].Y, 1, 6)
  2683. ARGFD6(pG_XYZ[Prim[1]].Y, 1, 6)
  2684. ARGFD6(pB_XYZ[Prim[2]].Y, 1, 6)));
  2685. } else {
  2686. MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
  2687. MAKE_MULDIV_PAIR(
  2688. MDPairs, 1,
  2689. CIE_Xr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2690. Prim[0]);
  2691. MAKE_MULDIV_PAIR(
  2692. MDPairs, 2,
  2693. CIE_Xg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2694. Prim[1]);
  2695. MAKE_MULDIV_PAIR(
  2696. MDPairs, 3,
  2697. CIE_Xb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2698. Prim[2]);
  2699. X = MulDivFD6Pairs(MDPairs);
  2700. //
  2701. // Compute CIE L from CIE Y tristimulus value
  2702. //
  2703. // L* = (1.16 x f(Y/Yw)) - 0.16
  2704. //
  2705. // 1/3
  2706. // f(Y/Yw) = (Y/Yw) (Y/Yw) > 0.008856
  2707. // f(Y/Yw) = 9.033 x (Y/Yw) (Y/Yw) <= 0.008856
  2708. //
  2709. //
  2710. // Our L* is range from 0.0 to 1.0, not 0.0 to 100.0
  2711. //
  2712. MAKE_MULDIV_PAIR(
  2713. MDPairs, 1,
  2714. CIE_Yr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2715. Prim[0]);
  2716. MAKE_MULDIV_PAIR(
  2717. MDPairs, 2,
  2718. CIE_Yg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2719. Prim[1]);
  2720. MAKE_MULDIV_PAIR(
  2721. MDPairs, 3,
  2722. CIE_Yb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2723. Prim[2]);
  2724. Y = MulDivFD6Pairs(MDPairs);
  2725. MAKE_MULDIV_PAIR(
  2726. MDPairs, 1,
  2727. CIE_Zr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2728. Prim[0]);
  2729. MAKE_MULDIV_PAIR(
  2730. MDPairs, 2,
  2731. CIE_Zg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2732. Prim[1]);
  2733. MAKE_MULDIV_PAIR(
  2734. MDPairs, 3,
  2735. CIE_Zb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
  2736. Prim[2]);
  2737. Z = MulDivFD6Pairs(MDPairs);
  2738. }
  2739. switch (_ColorSpace) {
  2740. case CIELUV_1976:
  2741. //
  2742. // U' = 4X / (X + 15Y + 3Z)
  2743. // V' = 9Y / (X + 15Y + 3Z)
  2744. //
  2745. // U* = 13 x L x (U' - Uw)
  2746. // V* = 13 x L x (V' - Vw)
  2747. //
  2748. _X15Y3Z = X + FD6xL(Y, 15) + FD6xL(Z, 3);
  2749. U1 = DivFD6(FD6xL(X, 4), _X15Y3Z) - iUw;
  2750. V1 = DivFD6(FD6xL(Y, 9), _X15Y3Z) - iVw;
  2751. _L13 = FD6xL(CIE_I2L(Y), 13);
  2752. AU = MulFD6(_L13, U1);
  2753. BV = MulFD6(_L13, V1);
  2754. MAKE_MULDIV_DVSR(AUMDPairs, _L13);
  2755. MAKE_MULDIV_DVSR(BVMDPairs, _L13);
  2756. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2757. DBGP(" << UV1: %s:%s [%s:%s], X15Y3Z=%s"
  2758. ARGFD6(U1, 2, 6)
  2759. ARGFD6(V1, 2, 6)
  2760. ARGFD6(U1 + iUw, 2, 6)
  2761. ARGFD6(V1 + iVw, 2, 6)
  2762. ARGFD6(_X15Y3Z, 2, 6)));
  2763. break;
  2764. case CIELAB_1976:
  2765. default:
  2766. //
  2767. // CIELAB 1976 L*A*B*
  2768. //
  2769. // A* = 500 x (fX - fY)
  2770. // B* = 200 x (fY - fZ)
  2771. //
  2772. // 1/3
  2773. // fX = (X/Xw) (X/Xw) > 0.008856
  2774. // fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
  2775. //
  2776. // 1/3
  2777. // fY = (Y/Yw) (Y/Yw) > 0.008856
  2778. // fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
  2779. //
  2780. // 1/3
  2781. // fZ = (Z/Zw) (Z/Zw) > 0.008856
  2782. // fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
  2783. //
  2784. fXYZFromXYZ(_fX, X, iRefXw);
  2785. fXYZFromXYZ(_fY, Y, FD6_1);
  2786. fXYZFromXYZ(_fZ, Z, iRefZw);
  2787. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2788. DBGP(" >> fXYZ: %s:%s:%s"
  2789. ARGFD6(_fX, 2, 6)
  2790. ARGFD6(_fY, 2, 6)
  2791. ARGFD6(_fZ, 2, 6)));
  2792. AU = _fX - _fY;
  2793. BV = _fY - _fZ;
  2794. //
  2795. // DO NOT Translate it now
  2796. //
  2797. if ((AU >= (FD6)-20) && (AU <= (FD6)20) &&
  2798. (BV >= (FD6)-20) && (BV <= (FD6)20)) {
  2799. DBGP_IF(DBGP_MONO_PRIM,
  2800. DBGP("*** MONO PRIMS: %s:%s:%s --> Y=%s"
  2801. ARGFD6(DivFD6(dbgR, 255), 1, 6)
  2802. ARGFD6(DivFD6(dbgG, 255), 1, 6)
  2803. ARGFD6(DivFD6(dbgB, 255), 1, 6)
  2804. ARGFD6(Y, 1, 6)));
  2805. }
  2806. break;
  2807. }
  2808. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2809. DBGP(" XYZ->%s: %s:%s:%s >> L:%s:%s"
  2810. ARG(pDbgCSName[_ColorSpace])
  2811. ARGFD6(X, 2, 6)
  2812. ARGFD6(Y, 1, 6)
  2813. ARGFD6(Z, 2, 6)
  2814. ARGFD6(AU, 4, 6)
  2815. ARGFD6(BV, 4, 6)));
  2816. //
  2817. // 5: Do any Color Adjustments (in LAB/LUV)
  2818. //
  2819. AUMDPairs[1].Pair2 =
  2820. BVMDPairs[2].Pair2 = AU;
  2821. AUMDPairs[2].Pair2 =
  2822. BVMDPairs[1].Pair2 = BV;
  2823. AU = MulDivFD6Pairs(AUMDPairs);
  2824. BV = MulDivFD6Pairs(BVMDPairs);
  2825. //
  2826. // 6: Transform From LAB/LUV->XYZ->RGB with possible gamma
  2827. // correction
  2828. //
  2829. // L* = (1.16 x f(Y/Yw)) - 0.16
  2830. //
  2831. // 1/3
  2832. // f(Y/Yw) = (Y/Yw) (Y/Yw) > 0.008856
  2833. // f(Y/Yw) = 9.033 x (Y/Yw) (Y/Yw) <= 0.008856
  2834. //
  2835. switch (_ColorSpace) {
  2836. case CIELUV_1976:
  2837. //
  2838. // U' = 4X / (X + 15Y + 3Z)
  2839. // V' = 9Y / (X + 15Y + 3Z)
  2840. //
  2841. // U* = 13 x L x (U' - Uw)
  2842. // V* = 13 x L x (V' - Vw)
  2843. //
  2844. if (((V1 = BV + oVw) < FD6_0) ||
  2845. ((_X15Y3Z = DivFD6(FD6xL(Y, 9), V1)) < FD6_0)) {
  2846. _X15Y3Z = (FD6)2147000000;
  2847. }
  2848. if ((U1 = AU + oUw) < FD6_0) {
  2849. X =
  2850. U1 = FD6_0;
  2851. } else {
  2852. X = FD6DivL(MulFD6(_X15Y3Z, U1), 4);
  2853. }
  2854. Z = FD6DivL(_X15Y3Z - X - FD6xL(Y, 15), 3);
  2855. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2856. DBGP(" >> UV1: %s:%s [%s:%s], X15Y3Z=%s"
  2857. ARGFD6(U1 - oUw, 2, 6)
  2858. ARGFD6(V1 - oVw, 2, 6)
  2859. ARGFD6(U1, 2, 6)
  2860. ARGFD6(V1, 2, 6)
  2861. ARGFD6(_X15Y3Z, 2, 6)));
  2862. break;
  2863. case CIELAB_1976:
  2864. default:
  2865. //
  2866. // CIELAB 1976 L*A*B*
  2867. //
  2868. // A* = 500 x (fX - fY)
  2869. // B* = 200 x (fY - fZ)
  2870. //
  2871. // 1/3
  2872. // fX = (X/Xw) (X/Xw) > 0.008856
  2873. // fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
  2874. //
  2875. // 1/3
  2876. // fY = (Y/Yw) (Y/Yw) > 0.008856
  2877. // fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
  2878. //
  2879. // 1/3
  2880. // fZ = (Z/Zw) (Z/Zw) > 0.008856
  2881. // fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
  2882. //
  2883. // _fX = FD6DivL(AU, 500) + _fY;
  2884. // _fZ = _fY - FD6DivL(BV, 200);
  2885. _fX = AU + _fY;
  2886. _fZ = _fY - BV;
  2887. XYZFromfXYZ(X, _fX, oRefXw);
  2888. XYZFromfXYZ(Z, _fZ, oRefZw);
  2889. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2890. DBGP(" << fXYZ: %s:%s:%s"
  2891. ARGFD6(_fX, 2, 6)
  2892. ARGFD6(_fY, 2, 6)
  2893. ARGFD6(_fZ, 2, 6)));
  2894. break;
  2895. }
  2896. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2897. DBGP(" %s->XYZ: %s:%s:%s << L:%s:%s"
  2898. ARG(pDbgCSName[_ColorSpace])
  2899. ARGFD6(X, 2, 6)
  2900. ARGFD6(Y, 1, 6)
  2901. ARGFD6(Z, 2, 6)
  2902. ARGFD6(AU, 4, 6)
  2903. ARGFD6(BV, 4, 6)));
  2904. MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
  2905. MAKE_MULDIV_PAIR(MDPairs, 1,
  2906. CIE_Xr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
  2907. MAKE_MULDIV_PAIR(MDPairs, 2,
  2908. CIE_Xg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
  2909. MAKE_MULDIV_PAIR(MDPairs, 3,
  2910. CIE_Xb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
  2911. Prim[0] = MulDivFD6Pairs(MDPairs);
  2912. MAKE_MULDIV_PAIR(MDPairs, 1,
  2913. CIE_Yr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
  2914. MAKE_MULDIV_PAIR(MDPairs, 2,
  2915. CIE_Yg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
  2916. MAKE_MULDIV_PAIR(MDPairs, 3,
  2917. CIE_Yb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
  2918. Prim[1] = MulDivFD6Pairs(MDPairs);
  2919. MAKE_MULDIV_PAIR(MDPairs, 1,
  2920. CIE_Zr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
  2921. MAKE_MULDIV_PAIR(MDPairs, 2,
  2922. CIE_Zg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
  2923. MAKE_MULDIV_PAIR(MDPairs, 3,
  2924. CIE_Zb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
  2925. Prim[2] = MulDivFD6Pairs(MDPairs);
  2926. //
  2927. // Make sure everthing is in the range
  2928. //
  2929. SCALE_PRIM_RGB(Prim, NULL);
  2930. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2931. DBGP(" XYZ->RGB: %s:%s:%s >> %s:%s:%s"
  2932. ARGFD6(X, 2, 6) ARGFD6(Y, 1, 6)
  2933. ARGFD6(Z, 2, 6) ARGFD6(Prim[0], 1, 6)
  2934. ARGFD6(Prim[1], 1, 6) ARGFD6(Prim[2], 1, 6)));
  2935. }
  2936. //
  2937. // 3: Dye correction if necessary
  2938. //
  2939. if (PrimAdjFlags & DCA_NEED_DYES_CORRECTION) {
  2940. if (PrimAdjFlags & DCA_HAS_BLACK_DYE) {
  2941. MAX_OF_3(W, Prim[0], Prim[1], Prim[2]);
  2942. } else {
  2943. W = FD6_1;
  2944. }
  2945. p0 = W - Prim[0];
  2946. p1 = W - Prim[1];
  2947. p2 = W - Prim[2];
  2948. DBGP_IF(DBGP_DYE_CORRECT,
  2949. DBGP(" DYE_CORRECT: %s:%s:%s, W=%s --> %s:%s:%s"
  2950. ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
  2951. ARGFD6(Prim[2], 2, 6) ARGFD6(W, 1, 6)
  2952. ARGFD6(p0, 2, 6) ARGFD6(p1, 2, 6)
  2953. ARGFD6(p2, 2, 6)));
  2954. MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
  2955. MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Xr((*pCMYDyeMasks)), p0);
  2956. MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Xg((*pCMYDyeMasks)), p1);
  2957. MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Xb((*pCMYDyeMasks)), p2);
  2958. Prim[0] = W - MulDivFD6Pairs(MDPairs);
  2959. MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Yr((*pCMYDyeMasks)), p0);
  2960. MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Yg((*pCMYDyeMasks)), p1);
  2961. MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Yb((*pCMYDyeMasks)), p2);
  2962. Prim[1] = W - MulDivFD6Pairs(MDPairs);
  2963. MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Zr((*pCMYDyeMasks)), p0);
  2964. MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Zg((*pCMYDyeMasks)), p1);
  2965. MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Zb((*pCMYDyeMasks)), p2);
  2966. Prim[2] = W - MulDivFD6Pairs(MDPairs);
  2967. DBGP_IF(DBGP_DYE_CORRECT,
  2968. DBGP(" DYE_CORRECT: %s:%s:%s << %s:%s:%s"
  2969. ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
  2970. ARGFD6(Prim[2], 2, 6) ARGFD6(p0, 2, 6)
  2971. ARGFD6(p1, 2, 6) ARGFD6(p2, 2, 6)));
  2972. CLAMP_01(Prim[0]);
  2973. CLAMP_01(Prim[1]);
  2974. CLAMP_01(Prim[2]);
  2975. }
  2976. //*******************************************************************
  2977. //
  2978. // 4: Compute Final Device DYE through device color mapping and
  2979. // Primary/Halftone Cell number computation, The Primaries (ie.
  2980. // Prim[]) are in ADDITIVE FORMAT
  2981. //
  2982. //*******************************************************************
  2983. //
  2984. // Store in BGRF in this order
  2985. //
  2986. (pbgr )->r = (BYTE)MulFD6(Prim[0], 0xFF);
  2987. (pbgr )->g = (BYTE)MulFD6(Prim[1], 0xFF);
  2988. (pbgr++)->b = (BYTE)MulFD6(Prim[2], 0xFF);
  2989. DBGP_IF(DBGP_SHOWXFORM_ALL,
  2990. DBGP(" MAPPING(%3ld:%3ld:%3ld): %s:%s:%s ---> %3ld:%3ld:%3ld"
  2991. ARGDW(dbgR) ARGDW(dbgG) ARGDW(dbgB)
  2992. ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
  2993. ARGFD6(Prim[2], 2, 6) ARGDW((pbgr - 1)->r)
  2994. ARGDW((pbgr - 1)->g) ARGDW((pbgr - 1)->b)));
  2995. }
  2996. if ((pR_XYZ) && (pCRTX)) {
  2997. if (!pCRTX->pFD6XYZ) {
  2998. DBGP_IF(DBGP_CCT,
  2999. DBGP("CCT: Allocate %ld bytes RGB->XYZ xform cached table"
  3000. ARGDW(pCRTX->SizeCRTX)));
  3001. if (!(pCRTX->pFD6XYZ =
  3002. (PFD6XYZ)HTAllocMem((LPVOID)pDCI,
  3003. HTMEM_CacheCRTX,
  3004. NONZEROLPTR,
  3005. pCRTX->SizeCRTX))) {
  3006. DBGP_IF(DBGP_CCT,
  3007. DBGP("Allocate %ld bytes of RGB->XYZ cached table failed"
  3008. ARGDW(pCRTX->SizeCRTX)));
  3009. }
  3010. }
  3011. if (pCRTX->pFD6XYZ) {
  3012. DBGP_IF(DBGP_CCT,
  3013. DBGP("CCT: *** Save computed RGB->XYZ xform to CACHE ***"));
  3014. pCRTX->Checksum = CRTXChecksum;
  3015. CopyMemory(pCRTX->pFD6XYZ, pR_XYZ, pCRTX->SizeCRTX);
  3016. }
  3017. }
  3018. if (pR_XYZ) {
  3019. DBGP_IF(DBGP_CCT,
  3020. DBGP("ColorTriadSrcToDev: Free Up pR_XYZ local cached table"));
  3021. HTFreeMem(pR_XYZ);
  3022. }
  3023. return((LONG)SrcClrTriad.ColorTableEntries);
  3024. #undef _SrcPrimType
  3025. #undef _DevBytesPerPrimary
  3026. #undef _DevBytesPerEntry
  3027. #undef _ColorSpace
  3028. #undef _fX
  3029. #undef _fY
  3030. #undef _fZ
  3031. #undef _X15Y3Z
  3032. #undef _L13
  3033. }
  3034. #if DBG
  3035. VOID
  3036. ShowBGRMC(
  3037. )
  3038. /*++
  3039. Routine Description:
  3040. Arguments:
  3041. Return Value:
  3042. Author:
  3043. 06-Oct-2000 Fri 17:01:25 created -by- Daniel Chou (danielc)
  3044. Revision History:
  3045. --*/
  3046. {
  3047. LONG i;
  3048. ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3049. i = HTGlobal.cBGRMC;
  3050. DBGP_IF(DBGP_BGRMAPTABLE, DBGP("\n================"));
  3051. while (i-- > 0) {
  3052. DBGP_IF(DBGP_BGRMAPTABLE,
  3053. DBGP(" --- %3ld: pMap=%p, Checksum=%08lx, cRef=%4ld"
  3054. ARGDW(i)
  3055. ARGPTR(HTGlobal.pBGRMC[i].pMap)
  3056. ARGDW(HTGlobal.pBGRMC[i].Checksum)
  3057. ARGDW(HTGlobal.pBGRMC[i].cRef)));
  3058. }
  3059. DBGP_IF(DBGP_BGRMAPTABLE, DBGP("================\n"));
  3060. RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3061. }
  3062. #if 1
  3063. #define SHOW_BGRMC()
  3064. #else
  3065. #define SHOW_BGRMC() ShowBGRMC()
  3066. #endif
  3067. #else
  3068. #define SHOW_BGRMC()
  3069. #endif
  3070. LONG
  3071. TrimBGRMapCache(
  3072. VOID
  3073. )
  3074. /*++
  3075. Routine Description:
  3076. This function trim the BGRMAPCache back to BGRMC_MAX_COUNT if possible
  3077. Arguments:
  3078. VOID
  3079. Return Value:
  3080. Total count that removed
  3081. Author:
  3082. 06-Oct-2000 Fri 14:24:14 created -by- Daniel Chou (danielc)
  3083. Revision History:
  3084. --*/
  3085. {
  3086. PBGRMAPCACHE pSave;
  3087. PBGRMAPCACHE pCur;
  3088. LONG cb;
  3089. LONG Count = 0;
  3090. LONG cTot;
  3091. ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3092. if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
  3093. pSave =
  3094. pCur = HTGlobal.pBGRMC;
  3095. cTot =
  3096. Count = HTGlobal.cBGRMC;
  3097. while ((cTot--) && (HTGlobal.cBGRMC > BGRMC_MAX_COUNT)) {
  3098. if (pCur->cRef == 0) {
  3099. DBGP_IF(DBGP_BGRMAPTABLE,
  3100. DBGP("Remove %ld, pMap=%p"
  3101. ARGDW((DWORD)(pCur - HTGlobal.pBGRMC))
  3102. ARGPTR(pCur->pMap)));
  3103. HTFreeMem(pCur->pMap);
  3104. --HTGlobal.cBGRMC;
  3105. --HTGlobal.cIdleBGRMC;
  3106. } else {
  3107. if (pSave != pCur) {
  3108. *pSave = *pCur;
  3109. }
  3110. ++pSave;
  3111. }
  3112. ++pCur;
  3113. }
  3114. DBGP_IF(DBGP_BGRMAPTABLE,
  3115. DBGP("pSave=%p, pCur=%p, (%ld), [%ld / %ld]"
  3116. ARGPTR(pSave) ARGPTR(pCur) ARGDW((DWORD)(pCur - pSave))
  3117. ARGDW((DWORD)(&HTGlobal.pBGRMC[Count] - pCur))
  3118. ARGDW((DWORD)((LPBYTE)&HTGlobal.pBGRMC[Count] - (LPBYTE)pCur))));
  3119. if (Count != HTGlobal.cBGRMC) {
  3120. if ((pCur > pSave) &&
  3121. ((cb = (LONG)((LPBYTE)&HTGlobal.pBGRMC[Count] -
  3122. (LPBYTE)pCur)) > 0)) {
  3123. CopyMemory(pSave, pCur, cb);
  3124. }
  3125. Count -= HTGlobal.cBGRMC;
  3126. DBGP_IF(DBGP_BGRMAPTABLE,
  3127. DBGP("TriBGRMapCache=%ld" ARGDW(Count)));
  3128. } else {
  3129. DBGP_IF(DBGP_BGRMAPTABLE, DBGP("!!!! TriBGRMapCache=0"));
  3130. }
  3131. }
  3132. DBGP_IF(DBGP_BGRMAPTABLE,
  3133. DBGP(" TTrimBGRMapCache: pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
  3134. ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
  3135. ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
  3136. RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3137. ASSERT(HTGlobal.cBGRMC >= 0);
  3138. ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
  3139. ASSERT(HTGlobal.cIdleBGRMC >= 0);
  3140. SHOW_BGRMC();
  3141. return(Count);
  3142. }
  3143. PBGR8
  3144. FindBGRMapCache(
  3145. PBGR8 pDeRefMap,
  3146. DWORD Checksum
  3147. )
  3148. /*++
  3149. Routine Description:
  3150. This function found a BGRMapCache with same checksum and move that
  3151. link to the begining.
  3152. Arguments:
  3153. pDeRefMap - Find pMap for deference (NULL if not)
  3154. Checksum - Find checksum (only if pDeRefMap == NULL
  3155. Return Value:
  3156. PBGR8 - The map that found
  3157. Author:
  3158. 06-Oct-2000 Fri 13:30:14 created -by- Daniel Chou (danielc)
  3159. Revision History:
  3160. --*/
  3161. {
  3162. LONG Count;
  3163. PBGR8 pRet = NULL;
  3164. ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3165. if ((HTGlobal.pBGRMC) && (Count = HTGlobal.cBGRMC)) {
  3166. PBGRMAPCACHE pCur = &HTGlobal.pBGRMC[Count - 1];
  3167. while ((Count) && (!pRet)) {
  3168. if (pDeRefMap == pCur->pMap) {
  3169. ASSERT(pCur->cRef);
  3170. pRet = pDeRefMap;
  3171. if (pCur->cRef) {
  3172. if (--pCur->cRef == 0) {
  3173. ++HTGlobal.cIdleBGRMC;
  3174. }
  3175. }
  3176. } else if (pCur->Checksum == Checksum) {
  3177. DBGP_IF(DBGP_BGRMAPTABLE,
  3178. DBGP("find Cached %08lx = %p at Index %ld, cRef=%ld"
  3179. ARGDW(Checksum) ARGPTR(pCur->pMap)
  3180. ARGDW((DWORD)(pCur - HTGlobal.pBGRMC))
  3181. ARGDW(pCur->cRef)));
  3182. pRet = pCur->pMap;
  3183. if (pCur->cRef++ == 0) {
  3184. --HTGlobal.cIdleBGRMC;
  3185. }
  3186. //
  3187. // Move this reference to the end of the list as most recent
  3188. //
  3189. if (Count < HTGlobal.cBGRMC) {
  3190. BGRMAPCACHE BGRMC = *pCur;
  3191. CopyMemory(pCur,
  3192. pCur + 1,
  3193. (HTGlobal.cBGRMC - Count) * sizeof(BGRMAPCACHE));
  3194. HTGlobal.pBGRMC[HTGlobal.cBGRMC - 1] = BGRMC;
  3195. }
  3196. }
  3197. --Count;
  3198. --pCur;
  3199. }
  3200. }
  3201. if ((pDeRefMap) && (!pRet)) {
  3202. DBGP_IF(DBGP_BGRMAPTABLE,
  3203. DBGP("Cannot find the pMap=%p that to be DeReference"
  3204. ARGPTR(pDeRefMap)));
  3205. }
  3206. DBGP_IF(DBGP_BGRMAPTABLE,
  3207. DBGP("%s_BGRMapCache(%p, %08lx): pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
  3208. ARGPTR((pDeRefMap) ? "DEREF" : " FIND")
  3209. ARGPTR(pDeRefMap) ARGDW(Checksum)
  3210. ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
  3211. ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
  3212. if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
  3213. TrimBGRMapCache();
  3214. }
  3215. RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3216. ASSERT(HTGlobal.cBGRMC >= 0);
  3217. ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
  3218. ASSERT(HTGlobal.cIdleBGRMC >= 0);
  3219. SHOW_BGRMC();
  3220. return(pRet);
  3221. }
  3222. BOOL
  3223. AddBGRMapCache(
  3224. PBGR8 pMap,
  3225. DWORD Checksum
  3226. )
  3227. /*++
  3228. Routine Description:
  3229. Add pMap with Checksum to the cache table
  3230. Arguments:
  3231. Return Value:
  3232. Author:
  3233. 06-Oct-2000 Fri 13:29:52 created -by- Daniel Chou (danielc)
  3234. Revision History:
  3235. --*/
  3236. {
  3237. PBGRMAPCACHE pBGRMC;
  3238. LONG cAlloc;
  3239. BOOL bRet = TRUE;
  3240. ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3241. if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
  3242. TrimBGRMapCache();
  3243. }
  3244. ASSERT(HTGlobal.cBGRMC <= HTGlobal.cAllocBGRMC);
  3245. if (HTGlobal.cBGRMC >= (cAlloc = HTGlobal.cAllocBGRMC)) {
  3246. DBGP_IF(DBGP_BGRMAPTABLE,
  3247. DBGP("AddBGRMapCache() Increase cAllocBGRMC %ld to %ld"
  3248. ARGDW(HTGlobal.cAllocBGRMC)
  3249. ARGDW(HTGlobal.cAllocBGRMC + BGRMC_SIZE_INC)));
  3250. cAlloc += BGRMC_SIZE_INC;
  3251. if (pBGRMC = (PBGRMAPCACHE)HTAllocMem((LPVOID)NULL,
  3252. HTMEM_BGRMC_CACHE,
  3253. LPTR,
  3254. cAlloc * sizeof(BGRMAPCACHE))) {
  3255. if (HTGlobal.pBGRMC) {
  3256. CopyMemory(pBGRMC,
  3257. HTGlobal.pBGRMC,
  3258. HTGlobal.cBGRMC * sizeof(BGRMAPCACHE));
  3259. HTFreeMem(HTGlobal.pBGRMC);
  3260. }
  3261. HTGlobal.pBGRMC = pBGRMC;
  3262. HTGlobal.cAllocBGRMC = cAlloc;
  3263. } else {
  3264. DBGP_IF(DBGP_BGRMAPTABLE,
  3265. DBGP("AddBGRMapCache() Allocation %ld bytes of Memory Failed"
  3266. ARGDW(HTGlobal.cAllocBGRMC * sizeof(BGRMAPCACHE))));
  3267. }
  3268. }
  3269. if ((HTGlobal.pBGRMC) &&
  3270. (HTGlobal.cBGRMC < HTGlobal.cAllocBGRMC)) {
  3271. pBGRMC = &HTGlobal.pBGRMC[HTGlobal.cBGRMC++];
  3272. pBGRMC->pMap = pMap;
  3273. pBGRMC->Checksum = Checksum;
  3274. pBGRMC->cRef = 1;
  3275. DBGP_IF(DBGP_BGRMAPTABLE,
  3276. DBGP(" AddBGRMapCache() Added %p (%08lx) to Cache"
  3277. ARGPTR(pMap) ARGDW(Checksum)));
  3278. } else {
  3279. bRet = FALSE;
  3280. }
  3281. DBGP_IF(DBGP_BGRMAPTABLE,
  3282. DBGP(" AddBGRMapCache: pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
  3283. ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
  3284. ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
  3285. RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
  3286. ASSERT(HTGlobal.cBGRMC >= 0);
  3287. ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
  3288. ASSERT(HTGlobal.cIdleBGRMC >= 0);
  3289. SHOW_BGRMC();
  3290. return(bRet);
  3291. }
  3292. LONG
  3293. HTENTRY
  3294. CreateDyesColorMappingTable(
  3295. PHALFTONERENDER pHR
  3296. )
  3297. /*++
  3298. Routine Description:
  3299. this function allocate the memory for the dyes color mapping table depends
  3300. on the source surface type information, it then go throug the color table
  3301. and calculate dye densities for each RGB color in the color table.
  3302. Arguments:
  3303. pHalftoneRender - Pointer to the HALFTONERENDER data structure.
  3304. Return Value:
  3305. a negative return value indicate failue.
  3306. HTERR_INVALID_SRC_FORMAT - Invalid source surface format, this
  3307. function only recongnized 1/4/8/24 bits
  3308. per pel source surfaces.
  3309. HTERR_COLORTABLE_TOO_BIG - can not create the color table to map
  3310. the colors to the dyes' densities.
  3311. HTERR_INSUFFICIENT_MEMORY - not enough memory for the pattern.
  3312. HTERR_INTERNAL_ERRORS_START - any other negative number indicate
  3313. halftone internal failure.
  3314. else - size of the color table entries created.
  3315. Author:
  3316. 29-Jan-1991 Tue 11:13:02 created -by- Daniel Chou (danielc)
  3317. Revision History:
  3318. --*/
  3319. {
  3320. PAAHEADER pAAHdr;
  3321. PDEVICECOLORINFO pDCI;
  3322. PDEVCLRADJ pDevClrAdj;
  3323. CTSTD_UNION CTSTDUnion;
  3324. LONG Result;
  3325. pDCI = pHR->pDeviceColorInfo;
  3326. pDevClrAdj = pHR->pDevClrAdj;
  3327. pAAHdr = (PAAHEADER)pHR->pAAHdr;
  3328. CTSTDUnion.b = pDevClrAdj->DMI.CTSTDInfo;
  3329. CTSTDUnion.b.SrcOrder =
  3330. pDevClrAdj->DMI.CTSTDInfo.SrcOrder = PRIMARY_ORDER_BGR;
  3331. //
  3332. // Make sure these call are semaphore protected
  3333. //
  3334. ComputeRGBLUTAA(pDCI, pDevClrAdj, &(pDCI->rgbLUT));
  3335. if (!(pDevClrAdj->PrimAdj.Flags & DCA_NO_MAPPING_TABLE)) {
  3336. PBGR8 pBGRMap;
  3337. PBGR8 pNewMap = NULL;
  3338. DWORD Checksum;
  3339. ASSERT(CTSTDUnion.b.cbPrim == sizeof(BGR8));
  3340. ASSERT(pAAHdr->Flags & AAHF_DO_CLR_MAPPING);
  3341. //
  3342. // Compute checksum for all necessary component that computing it
  3343. // 1. rgbCSXForm (which is sRGB constant in GDI implementation)
  3344. // 2. DevCSXForm
  3345. // 3. ColorAdjustment (illum, colorfulness, tint)
  3346. //
  3347. Checksum = ComputeChecksum((LPBYTE)&pDevClrAdj->PrimAdj.rgbCSXForm,
  3348. 0x12345678,
  3349. sizeof(COLORSPACEXFORM));
  3350. Checksum = ComputeChecksum((LPBYTE)&pDevClrAdj->PrimAdj.DevCSXForm,
  3351. Checksum,
  3352. sizeof(COLORSPACEXFORM));
  3353. Checksum = ComputeChecksum((LPBYTE)&(pDevClrAdj->ca),
  3354. Checksum,
  3355. sizeof(pDevClrAdj->ca));
  3356. if (!(pBGRMap = FIND_BGRMAPCACHE(Checksum))) {
  3357. DBGP_IF(DBGP_BGRMAPTABLE,
  3358. DBGP("*** No CACHE: Alloc %ld bytes of CACHE pBGRMap ***"
  3359. ARGDW(SIZE_BGR_MAPPING_TABLE)));
  3360. if (!(pBGRMap =
  3361. pNewMap = (PBGR8)HTAllocMem((LPVOID)NULL,
  3362. HTMEM_BGRMC_MAP,
  3363. NONZEROLPTR,
  3364. SIZE_BGR_MAPPING_TABLE))) {
  3365. DBGP_IF(DBGP_BGRMAPTABLE,
  3366. DBGP("\n*** FAILED Alloc %ld bytes of pBGRMap ***\n"));
  3367. return((LONG)HTERR_INSUFFICIENT_MEMORY);
  3368. }
  3369. }
  3370. if (pNewMap) {
  3371. DBGP_IF(DBGP_BGRMAPTABLE,
  3372. DBGP("Cached map Checksum (%08lx) not found, compute Re-Compute RGB555"
  3373. ARGDW(Checksum)));
  3374. if ((Result = ComputeBGRMappingTable(pDCI,
  3375. pDevClrAdj,
  3376. NULL,
  3377. pNewMap)) ==
  3378. HT_RGB_CUBE_COUNT) {
  3379. if (!(AddBGRMapCache(pNewMap, Checksum))) {
  3380. DBGP_IF(DBGP_BGRMAPTABLE,
  3381. DBGP("Adding BGRMapCache failed, Free pNewMap=%p"
  3382. ARGPTR(pNewMap)));
  3383. HTFreeMem(pNewMap);
  3384. return((LONG)HTERR_INSUFFICIENT_MEMORY);
  3385. }
  3386. } else {
  3387. DBGP_IF(DBGP_BGRMAPTABLE,
  3388. DBGP("ColorTriadSrcTodev() Failed, Result=%ld"
  3389. ARGDW(Result)));
  3390. return(INTERR_INVALID_DEVRGB_SIZE);
  3391. }
  3392. }
  3393. pAAHdr->pBGRMapTable = pBGRMap;
  3394. }
  3395. Result = CachedHalftonePattern(pDCI,
  3396. pDevClrAdj,
  3397. &(pAAHdr->AAPI),
  3398. pAAHdr->ptlBrushOrg.x,
  3399. pAAHdr->ptlBrushOrg.y,
  3400. (BOOL)(pAAHdr->Flags & AAHF_FLIP_Y));
  3401. return(Result);
  3402. }