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.

2443 lines
69 KiB

  1. /****************************Module*Header*******************************\
  2. * Module Name: ylateobj.cxx
  3. *
  4. * This contains the xlate object constructors, destructors and methods
  5. * An xlateobj is used to translate indexes from one palette to another.
  6. *
  7. * When blting between raster surfaces we create a translate object
  8. * between to speed up the BitBlt. When the destination surface is
  9. * palette managed we have to do a bit more work.
  10. *
  11. * Created: 18-Nov-1990 14:23:55
  12. * Author: Patrick Haluptzok patrickh
  13. *
  14. * Copyright (c) 1990-1999 Microsoft Corporation
  15. \**************************************************************************/
  16. #include "precomp.hxx"
  17. extern "C" VOID vInitXLATE();
  18. #pragma alloc_text(INIT, vInitXLATE)
  19. // These two variables are for the translate components cacheing of
  20. // translate objects. There access is restricted to being done only
  21. // after the palette semaphore has been grabbed.
  22. XLATETABLE xlateTable[XLATE_CACHE_SIZE];
  23. ULONG ulTableIndex = 0;
  24. TRANSLATE20 defaultTranslate =
  25. {
  26. 0,
  27. {0,1,2,3,4,5,6,7,8,9,246,247,248,249,250,251,252,253,254,255}
  28. };
  29. // This is the identity xlate object
  30. XLATE256 xloIdent;
  31. /******************************Public*Routine******************************\
  32. * vInitXLATE
  33. *
  34. * initialize the xlateobj component
  35. *
  36. * History:
  37. * 10-Jan-1991 -by- Patrick Haluptzok patrickh
  38. * Wrote it.
  39. \**************************************************************************/
  40. extern "C" VOID vInitXLATE()
  41. {
  42. RtlZeroMemory(xlateTable, (UINT) XLATE_CACHE_SIZE * sizeof(XLATETABLE));
  43. xloIdent.iUniq = XLATE_IDENTITY_UNIQ;
  44. xloIdent.flXlate = XO_TRIVIAL;
  45. xloIdent.iSrcType = 0;
  46. xloIdent.iDstType = 0;
  47. xloIdent.cEntries = 256;
  48. xloIdent.pulXlate = xloIdent.ai;
  49. xloIdent.iBackSrc = 0;
  50. xloIdent.iForeDst = 0;
  51. xloIdent.iBackDst = 0;
  52. //
  53. // This may seem hackish but XLATE_CACHE_JOURANL ensures that
  54. // it doesn't cause anything to get unlocked or freed in
  55. // the destructor.
  56. //
  57. xloIdent.lCacheIndex = XLATE_CACHE_JOURNAL;
  58. xloIdent.ppalSrc = (PPALETTE) NULL;
  59. xloIdent.ppalDst = (PPALETTE) NULL;
  60. xloIdent.ppalDstDC = (PPALETTE) NULL;
  61. xloIdent.hcmXform = NULL;
  62. xloIdent.lIcmMode = DC_ICM_OFF;
  63. UINT uiTemp;
  64. for (uiTemp = 0; uiTemp < 256; uiTemp++)
  65. {
  66. xloIdent.ai[uiTemp] = uiTemp;
  67. }
  68. }
  69. /******************************Public*Routine******************************\
  70. * EXLATEOBJ::vDelete
  71. *
  72. * Deletes the object.
  73. *
  74. * History:
  75. * Sun 17-Oct-1993 -by- Patrick Haluptzok [patrickh]
  76. * Kill hmgr references.
  77. *
  78. * 26-Nov-1990 -by- Patrick Haluptzok patrickh
  79. * Wrote it.
  80. \**************************************************************************/
  81. VOID EXLATEOBJ::vDelete()
  82. {
  83. if (pxlate != (PXLATE) NULL)
  84. {
  85. if (pxlate->lCacheIndex == XLATE_CACHE_JOURNAL)
  86. {
  87. if (ppalSrc())
  88. {
  89. bDeletePalette((HPAL) ppalSrc()->hGet());
  90. }
  91. }
  92. VFREEMEM(pxlate);
  93. pxlate = (PXLATE) NULL;
  94. }
  95. }
  96. /******************************Public*Routine******************************\
  97. * XLATEMEMOBJ destructor
  98. *
  99. * destructor for xlate memory objects
  100. *
  101. * History:
  102. * Mon 19-Nov-1990 -by- Patrick Haluptzok [patrickh]
  103. * Wrote it.
  104. \**************************************************************************/
  105. XLATEMEMOBJ::~XLATEMEMOBJ()
  106. {
  107. if (pxlate != (PXLATE) NULL)
  108. {
  109. VFREEMEM(pxlate);
  110. pxlate = (PXLATE) NULL;
  111. }
  112. }
  113. /******************************Public*Routine******************************\
  114. * XLATE::vMapNewXlate
  115. *
  116. * Maps a pxlate from being relative to one palette to being relative to
  117. * another palette.
  118. *
  119. * Arguments:
  120. *
  121. * ptrans - Translate to map
  122. *
  123. * History:
  124. * 10-Jan-1991 -by- Patrick Haluptzok patrickh
  125. * Wrote it.
  126. \**************************************************************************/
  127. VOID
  128. FASTCALL
  129. XLATE::vMapNewXlate(
  130. PTRANSLATE ptrans
  131. )
  132. {
  133. ULONG ulTemp;
  134. ULONG ulCount = cEntries;
  135. if (ptrans == NULL)
  136. {
  137. //
  138. // This is the default palette case
  139. //
  140. while (ulCount--)
  141. {
  142. ulTemp = ai[ulCount];
  143. if (ulTemp >= 10)
  144. {
  145. ai[ulCount] = ulTemp + 236;
  146. }
  147. //
  148. // else
  149. //
  150. //
  151. // do nothing, the first 10 are a 1 to 1 mapping.
  152. //
  153. }
  154. }
  155. else
  156. {
  157. ULONG *pultemp = ai;
  158. while (ulCount--)
  159. {
  160. *pultemp = (ULONG) ptrans->ajVector[*pultemp];
  161. pultemp++;
  162. //
  163. // ai[ulCount] = (ULONG) ptrans->ajVector[ai[ulCount]];
  164. //
  165. }
  166. }
  167. }
  168. /******************************Public*Routine******************************\
  169. * EXLATEOBJ::bMakeXlate
  170. *
  171. * This is called by SetDIBitsToDevice for the DIB_PAL_COLORS case.
  172. * This takes the indices in bmiColors and translates them through
  173. * a logical palette.
  174. *
  175. * Arguments:
  176. *
  177. * pusIndices -
  178. * palDC -
  179. * pSurfDst -
  180. * cEntriesInit -
  181. * cEntriesMax -
  182. *
  183. * History:
  184. * 17-Apr-1991 -by- Patrick Haluptzok patrickh
  185. * Wrote it.
  186. \**************************************************************************/
  187. BOOL
  188. EXLATEOBJ::bMakeXlate(
  189. PUSHORT pusIndices,
  190. XEPALOBJ palDC,
  191. SURFACE *pSurfDst,
  192. ULONG cEntriesInit,
  193. ULONG cEntriesMax
  194. )
  195. {
  196. ASSERTGDI(pSurfDst != NULL, "ERROR GDI bMakeXlate1");
  197. ASSERTGDI(palDC.bValid(), "ERROR bMakeXlate 134");
  198. XEPALOBJ palDst(pSurfDst->ppal());
  199. ULONG ulTemp;
  200. ULONG ulIndex;
  201. //
  202. // count of colors in DC
  203. //
  204. ULONG cColorsDC;
  205. PXLATE pXlateTemp;
  206. ASSERTGDI(palDC.cEntries() != 0, "ERROR 0 entry dc palette isn't allowed");
  207. //
  208. // Allocate room for the Xlate.
  209. //
  210. pxlate = pXlateTemp = (PXLATE) PALLOCNOZ(sizeof(XLATE) +
  211. (sizeof(ULONG) * cEntriesMax),
  212. 'tlxG');
  213. if (pXlateTemp == (PXLATE)NULL)
  214. {
  215. WARNING("GDISRV bMakeXlate failed memory allocation\n");
  216. return(FALSE);
  217. }
  218. pXlateTemp->iUniq = ulGetNewUniqueness(ulXlatePalUnique);
  219. pXlateTemp->flXlate = XO_TABLE;
  220. pXlateTemp->iSrcType = pXlateTemp->iDstType = 0;
  221. pXlateTemp->cEntries = cEntriesMax;
  222. pXlateTemp->pulXlate = pXlateTemp->ai;
  223. pXlateTemp->iBackSrc = 0;
  224. pXlateTemp->iForeDst = 0;
  225. pXlateTemp->iBackDst = 0;
  226. pXlateTemp->lCacheIndex = XLATE_CACHE_INVALID;
  227. pXlateTemp->ppalSrc = (PPALETTE) NULL;
  228. pXlateTemp->ppalDst = palDst.ppalGet();
  229. pXlateTemp->ppalDstDC = palDC.ppalGet();
  230. RtlZeroMemory(((ULONG *)pXlateTemp->ai) + cEntriesInit,
  231. (UINT) (cEntriesMax - cEntriesInit) * sizeof(ULONG));
  232. PAL_ULONG palentry;
  233. PTRANSLATE ptrans;
  234. cColorsDC = palDC.cEntries();
  235. //
  236. // Grab the palette semaphore so you can touch the pxlates.
  237. //
  238. SEMOBJ semo(ghsemPalette);
  239. //
  240. // Ok fill in the pxlate correctly.
  241. //
  242. if ((!palDst.bValid()) || (palDst.bIsPalManaged()))
  243. {
  244. //
  245. // Do the palette managed cases
  246. //
  247. if (palDC.bIsPalDefault())
  248. {
  249. for(ulTemp = 0; ulTemp < cEntriesInit; ulTemp++)
  250. {
  251. //
  252. // Get the index into the logical palette
  253. //
  254. ulIndex = (ULONG) pusIndices[ulTemp];
  255. //
  256. // Make sure it isn't too large
  257. //
  258. if (ulIndex >= 20)
  259. {
  260. ulIndex = ulIndex % 20;
  261. }
  262. if (ulIndex < 10)
  263. {
  264. pXlateTemp->ai[ulTemp] = ulIndex;
  265. }
  266. else
  267. {
  268. pXlateTemp->ai[ulTemp] = ulIndex + 236;
  269. }
  270. }
  271. }
  272. else if (palDst.bValid() && (palDC.ptransCurrent() != NULL))
  273. {
  274. //
  275. // Map through the current translate.
  276. //
  277. ptrans = palDC.ptransCurrent();
  278. for(ulTemp = 0; ulTemp < cEntriesInit; ulTemp++)
  279. {
  280. //
  281. // Get the index into the logical palette
  282. //
  283. ulIndex = (ULONG) pusIndices[ulTemp];
  284. if (ulIndex >= cColorsDC)
  285. {
  286. ulIndex = ulIndex % cColorsDC;
  287. }
  288. pXlateTemp->ai[ulTemp] = (ULONG) ptrans->ajVector[ulIndex];
  289. ASSERTGDI(pXlateTemp->ai[ulTemp] < 256, "ERROR GDI bMakeXlate6");
  290. }
  291. }
  292. else if ((!palDst.bValid()) && (palDC.ptransFore() != NULL))
  293. {
  294. //
  295. // It's a bitmap, Map through the foreground translate.
  296. //
  297. ptrans = palDC.ptransFore();
  298. for(ulTemp = 0; ulTemp < cEntriesInit; ulTemp++)
  299. {
  300. //
  301. // Get the index into the logical palette
  302. //
  303. ulIndex = (ULONG) pusIndices[ulTemp];
  304. if (ulIndex >= cColorsDC)
  305. {
  306. ulIndex = ulIndex % cColorsDC;
  307. }
  308. pXlateTemp->ai[ulTemp] = (ULONG) ptrans->ajVector[ulIndex];
  309. ASSERTGDI(pXlateTemp->ai[ulTemp] < 256, "ERROR GDI bMakeXlate6");
  310. }
  311. }
  312. else
  313. {
  314. //
  315. // It's palette hasn't been realized. Grab the palette value and
  316. // then map into default palette if not PC_EXPLICIT entry.
  317. //
  318. for (ulTemp = 0; ulTemp < cEntriesInit; ulTemp++)
  319. {
  320. //
  321. // Get the index into the logical palette
  322. //
  323. ulIndex = (ULONG) pusIndices[ulTemp];
  324. if (ulIndex >= cColorsDC)
  325. {
  326. ulIndex = ulIndex % cColorsDC;
  327. }
  328. palentry.ul = palDC.ulEntryGet(ulIndex);
  329. if (palentry.pal.peFlags == PC_EXPLICIT)
  330. {
  331. //
  332. // Get the correct index in the surface palette.
  333. //
  334. ulIndex = palentry.ul & 0x0000FFFF;
  335. if (ulIndex >= 256)
  336. {
  337. ulIndex = ulIndex % 256;
  338. }
  339. }
  340. else
  341. {
  342. //
  343. // Match against the default palette entries.
  344. //
  345. ulIndex = ((XEPALOBJ) ppalDefault).ulGetNearestFromPalentry(palentry.pal);
  346. if (ulIndex >= 10)
  347. {
  348. ulIndex = ulIndex + 236;
  349. }
  350. }
  351. pXlateTemp->ai[ulTemp] = ulIndex;
  352. ASSERTGDI(pXlateTemp->ai[ulTemp] < 256, "ERROR GDI bMakeXlate6");
  353. }
  354. }
  355. }
  356. else
  357. {
  358. //
  359. // Find the RGB in the palDC (reaching down to palDst for
  360. // PC_EXPLICIT entries). Then find closest match in surface palette.
  361. //
  362. ASSERTGDI(palDst.bValid(), "ERROR palDst is not valid");
  363. for (ulTemp = 0; ulTemp < cEntriesInit; ulTemp++)
  364. {
  365. //
  366. // Get the index into the logical palette
  367. //
  368. palentry.ul = (ULONG) pusIndices[ulTemp];
  369. if (palentry.ul >= cColorsDC)
  370. {
  371. palentry.ul = palentry.ul % cColorsDC;
  372. }
  373. palentry.pal = palDC.palentryGet(palentry.ul);
  374. if (palentry.pal.peFlags == PC_EXPLICIT)
  375. {
  376. //
  377. // Get the correct index in the surface palette.
  378. //
  379. if (palDst.cEntries())
  380. {
  381. palentry.ul = palentry.ul & 0x0000FFFF;
  382. if (palentry.ul >= palDst.cEntries())
  383. {
  384. palentry.ul = palentry.ul % palDst.cEntries();
  385. }
  386. }
  387. else
  388. {
  389. //
  390. // Well what else can we do ?
  391. //
  392. palentry.ul = 0;
  393. }
  394. pXlateTemp->ai[ulTemp] = palentry.ul;
  395. }
  396. else
  397. {
  398. pXlateTemp->ai[ulTemp] = palDst.ulGetNearestFromPalentry(palentry.pal);
  399. }
  400. }
  401. }
  402. pxlate->vCheckForTrivial();
  403. return(TRUE);
  404. }
  405. //
  406. // This describes the overall logic of surface to surface xlates.
  407. // There are basically n types of xlates to worry about:
  408. //
  409. // 1. XO_TRIVIAL - no translation occurs, identity.
  410. //
  411. // 2. XO_TABLE - look up in a table for the correct table translation.
  412. //
  413. // a. XO_TO_MONO - look in to table for the correct tranlation,
  414. // but when getting it out of the cache make sure iBackSrc is the
  415. // same. iBackSrc goes to 1, everything else to 0.
  416. // b. XLATE_FROM_MONO - look into table for the correct translation
  417. // but when getting it out of the cache make sure iBackDst and
  418. // iForeDst are both still valid. 1 goes to iBackDst, 0 to iForeDst.
  419. // c. just plain jane indexed to indexed or rgb translation.
  420. //
  421. // 3. XLATE_RGB_SRC - Have to call XLATEOBJ_iXlate to get it translated.
  422. //
  423. // a. XO_TO_MONO - we have saved the iBackColor in ai[0]
  424. // b. just plain jane RGB to indexed. Grab the RGB, find the closest
  425. // match in Dst palette. Lot's of work.
  426. //
  427. // 4. XLATE_RGB_BOTH - Bit mashing time. Call XLATEOBJ_iXlate
  428. //
  429. /******************************Public*Routine******************************\
  430. * EXLATEOBJ::bInitXlateObj
  431. *
  432. * Cache aware initializer for Xlates.
  433. *
  434. * Arguments:
  435. *
  436. * hcmXform - hColorTransform, may be NULL
  437. * pdc - pointer to DC object
  438. * palSrc - src surface palette
  439. * palDst - dst surface palette
  440. * palSrcDC - src DC palette
  441. * palDstDC - dst DC palette
  442. * iForeDst - For Mono->Color this is what a 0 goes to
  443. * iBackDst - For Mono->Color this is what a 1 goes to
  444. * iBackSrc - For Color->Mono this is the color that goes to
  445. * 1, all other colors go to 0.
  446. * flCear - Used for multi-monitor systems
  447. *
  448. * History:
  449. * Sun 23-Jun-1991 -by- Patrick Haluptzok [patrickh]
  450. *
  451. \**************************************************************************/
  452. BOOL
  453. EXLATEOBJ::bInitXlateObj(
  454. HANDLE hcmXform,
  455. LONG lIcmMode,
  456. XEPALOBJ palSrc,
  457. XEPALOBJ palDst,
  458. XEPALOBJ palSrcDC,
  459. XEPALOBJ palDstDC,
  460. ULONG iForeDst,
  461. ULONG iBackDst,
  462. ULONG iBackSrc,
  463. ULONG flCreate
  464. )
  465. {
  466. //
  467. // Check if blting from compatible bitmap to screen. This is a common
  468. // occurrence on 8bpp devices we want to accelerate.
  469. //
  470. if (!palSrc.bValid())
  471. {
  472. if (
  473. !palDst.bValid() ||
  474. (
  475. palDst.bIsPalManaged() &&
  476. (
  477. (palDstDC.ptransCurrent() == NULL) ||
  478. (palDstDC.ptransCurrent() == palDstDC.ptransFore())
  479. )
  480. )
  481. )
  482. {
  483. vMakeIdentity();
  484. return(TRUE);
  485. }
  486. }
  487. //
  488. // Check if blting from screen to compatible bitmap.
  489. //
  490. if (!palDst.bValid())
  491. {
  492. if (palSrc.bIsPalManaged())
  493. {
  494. //
  495. // Blting from screen to memory bitmap. Check for identity.
  496. //
  497. if ((palDstDC.ptransCurrent() == NULL) ||
  498. (palDstDC.ptransCurrent() == palDstDC.ptransFore()))
  499. {
  500. vMakeIdentity();
  501. return(TRUE);
  502. }
  503. }
  504. }
  505. ASSERTGDI(palDstDC.bValid(), "7GDIERROR vInitXlateObj");
  506. ASSERTGDI(palDst.bValid() || palSrc.bValid(), "8GDIERROR vInitXlateObj");
  507. //
  508. // Check for the easy identity out. This check does the right thing for
  509. // ppal==ppal and equal times of two different ppals.
  510. //
  511. if ((palSrc.bValid()) && (palDst.bValid()))
  512. {
  513. if (palSrc.ulTime() == palDst.ulTime())
  514. {
  515. ASSERTGDI(palSrc.cEntries() == palDst.cEntries(), "Xlateobj matching times, different # of entries");
  516. vMakeIdentity();
  517. return(TRUE);
  518. }
  519. }
  520. BOOL bCacheXlate = TRUE;
  521. if (IS_ICM_ON(lIcmMode) && (hcmXform != NULL))
  522. {
  523. //
  524. // If we enable ICM and have a valid color tranform,
  525. // don't search from cache and don't insert new Xlate to cache.
  526. //
  527. bCacheXlate = FALSE;
  528. }
  529. else if ((palSrc.bValid()) && (palDst.bValid()))
  530. {
  531. if (bSearchCache(palSrc, palDst, palSrcDC, palDstDC,
  532. iForeDst, iBackDst, iBackSrc, flCreate))
  533. {
  534. return(TRUE);
  535. }
  536. }
  537. pxlate = CreateXlateObject(hcmXform,
  538. lIcmMode,
  539. palSrc,
  540. palDst,
  541. palSrcDC,
  542. palDstDC,
  543. iForeDst,
  544. iBackDst,
  545. iBackSrc,
  546. flCreate);
  547. if (pxlate != (PXLATE) NULL)
  548. {
  549. if (bCacheXlate &&
  550. palSrc.bValid() &&
  551. palDst.bValid() &&
  552. (!(pxlate->flPrivate & XLATE_RGB_SRC)))
  553. {
  554. vAddToCache(palSrc, palDst, palSrcDC, palDstDC);
  555. }
  556. return(TRUE);
  557. }
  558. else
  559. {
  560. return(FALSE);
  561. }
  562. }
  563. /******************************Public*Routine******************************\
  564. * CreateXlateObject
  565. *
  566. * Allocates an xlate sets it up.
  567. *
  568. * Arguments:
  569. *
  570. * palSrc - src surface palette
  571. * palDestSurf - dst surface palette
  572. * palSrcDC - src DC palette
  573. * palDestDC - dst DC palette
  574. * iForeDst - For Mono->Color this is what a 0 goes to
  575. * iBackDst - For Mono->Color this is what a 1 goes to
  576. * iBackSrc - For Color->Mono this is the color that goes to
  577. * 1, all other colors go to 0.
  578. *
  579. * History:
  580. * 02-May-1991 -by- Patrick Haluptzok patrickh
  581. * Wrote it.
  582. \**************************************************************************/
  583. PXLATE
  584. CreateXlateObject(
  585. HANDLE hcmXform,
  586. LONG lIcmMode,
  587. XEPALOBJ palSrc,
  588. XEPALOBJ palDestSurf,
  589. XEPALOBJ palSrcDC,
  590. XEPALOBJ palDestDC,
  591. ULONG iForeDst,
  592. ULONG iBackDst,
  593. ULONG iBackSrc,
  594. ULONG flCreateFlag
  595. )
  596. {
  597. ASSERTGDI(palDestDC.bValid(), "CreateXlateObject recieved bad ppalDstDC, bug in GDI");
  598. ASSERTGDI(palSrc.bValid() || palDestSurf.bValid(), "CreateXlaetObject recieved bad ppalSrc, bug in GDI");
  599. ASSERTGDI(palSrc.ppalGet() != palDestSurf.ppalGet(), "Didn't recognize ident quickly");
  600. //
  601. // cEntry == 0 means the source palette is an RGB/Bitfields type.
  602. // An invalid palette means it's a compatible bitmap on a palette managed device.
  603. //
  604. ULONG ulTemp;
  605. ULONG cEntry = palSrc.bValid() ? palSrc.cEntries() : 256;
  606. //
  607. // Allocate room for the structure.
  608. //
  609. PXLATE pxlate = pCreateXlate(cEntry);
  610. if (pxlate == NULL)
  611. {
  612. WARNING("CreateXlateObject failed pCreateXlate\n");
  613. return(pxlate);
  614. }
  615. //
  616. // Grab the palette semaphore so you can access the ptrans in palDestDC.
  617. //
  618. SEMOBJ semo(ghsemPalette); // ??? This may not need to be grabbed
  619. // ??? since we have the DC's locked that
  620. // ??? this palette DC is in. Investigate.
  621. //
  622. // Initialize ICM stuffs.
  623. //
  624. pxlate->vCheckForICM(hcmXform,lIcmMode);
  625. BOOL bCMYKColor = ((pxlate->flXlate & XO_FROM_CMYK) ? TRUE : FALSE);
  626. //
  627. // See if we should be matching to the Dest DC palette instead of the
  628. // surface. This occurs when the surface is palette managed and the
  629. // user hasn't selected an RGB palette into his destination DC.
  630. // Note we check for a valid pxlate in the Destination DC palette.
  631. // In multi-task OS the user can do things to get the translate in a
  632. // invalid or NULL state easily. We match against the reserved palette
  633. // in this case.
  634. //
  635. BOOL bPalManaged = (!palDestSurf.bValid()) || (palDestSurf.bIsPalManaged());
  636. if (bPalManaged)
  637. {
  638. //
  639. // We are blting to a compatible bitmap or the screen on a palette managed
  640. // device. Check that we have a foreground realization already done,
  641. // otherwise just use the default palette for the DC palette.
  642. //
  643. ASSERTGDI(((palDestDC.ptransFore() == NULL) && (palDestDC.ptransCurrent() == NULL)) ||
  644. ((palDestDC.ptransFore() != NULL) && (palDestDC.ptransCurrent() != NULL)),
  645. "ERROR translates are either both valid or both invalid");
  646. if (palDestDC.ptransFore() == NULL)
  647. {
  648. //
  649. // Match against the default palette, valid translate is not available.
  650. //
  651. palDestDC.ppalSet(ppalDefault);
  652. }
  653. if (!(flCreateFlag & XLATE_USE_SURFACE_PAL))
  654. {
  655. pxlate->flPrivate |= XLATE_PAL_MANAGED;
  656. //
  657. // Set a flag that says whether we are background or foreground.
  658. //
  659. if (palDestSurf.bValid())
  660. {
  661. pxlate->flPrivate |= XLATE_USE_CURRENT;
  662. }
  663. }
  664. }
  665. pxlate->ppalSrc = palSrc.ppalGet();
  666. pxlate->ppalDst = palDestSurf.ppalGet();
  667. pxlate->ppalDstDC = palDestDC.ppalGet();
  668. PTRANSLATE ptransFore = palDestDC.ptransFore();
  669. PTRANSLATE ptransCurrent = palDestDC.ptransCurrent();
  670. //
  671. // Ok, lets build the translate vector.
  672. //
  673. if (
  674. (!palSrc.bValid()) ||
  675. (
  676. (palSrc.bIsPalManaged()) &&
  677. ((ptransFore == ptransCurrent) || (flCreateFlag & XLATE_USE_FOREGROUND))
  678. )
  679. )
  680. {
  681. //
  682. // The source is a compatible bitmap on a palette managed device or the screen
  683. // with Dst DC palette having been realized in the foreground.
  684. //
  685. // We start out assuming an identity blt.
  686. //
  687. if (ptransFore == NULL)
  688. {
  689. //
  690. // Match against the default palette since a
  691. // valid translate is not available.
  692. //
  693. palDestDC.ppalSet(ppalDefault);
  694. pxlate->ppalDstDC = ppalDefault;
  695. ptransFore = ptransCurrent = (TRANSLATE *) &defaultTranslate;
  696. }
  697. ASSERTGDI(cEntry == 256, "ERROR xlate too small");
  698. for (ulTemp = 0; ulTemp < 256; ulTemp++)
  699. {
  700. pxlate->ai[ulTemp] = ulTemp;
  701. }
  702. if (!palDestSurf.bValid())
  703. {
  704. //
  705. // Compatible bitmap to compatible bitmap on palette managed
  706. // device. Both are relevant to the foreground realize of the
  707. // DestDC palette so the xlate is identity.
  708. //
  709. pxlate->flXlate |= XO_TRIVIAL;
  710. }
  711. else if ((palDestSurf.bIsPalDibsection()) && (bEqualRGB_In_Palette(palDestSurf, palDestDC)))
  712. {
  713. //
  714. // If you blt from a compatible bitmap to a DIBSECTION it will be identity
  715. // if the RGB's of both the DC palette and the DIBSECTION's palette are the same.
  716. // We do this special check so that if they contain duplicates we still get an
  717. // identity xlate.
  718. //
  719. pxlate->flXlate |= XO_TRIVIAL; // Size wise this will combine with first check
  720. }
  721. else if ((palDestSurf.bIsPalDibsection()) && (palSrc.bValid()) && (bEqualRGB_In_Palette(palDestSurf, palSrc)))
  722. {
  723. pxlate->flXlate |= XO_TRIVIAL; // Size wise this will combine with first check
  724. }
  725. else if (palDestSurf.bIsPalManaged())
  726. {
  727. //
  728. // Compatible bitmap to the screen on a palette managed device.
  729. // The compatible bitmaps colors are defined as the foreground
  730. // realization of the destination DC's palette. If the Dst
  731. // DC's palette is realized in the foreground it's identity.
  732. // Otherwise we translate from the current to the foreground
  733. // indices.
  734. //
  735. if (ptransCurrent == ptransFore)
  736. {
  737. //
  738. // It's in the foreground or not realized yet so it's
  739. // identity. Not realized case also hits on default logical palette.
  740. //
  741. pxlate->flXlate |= XO_TRIVIAL;
  742. }
  743. else
  744. {
  745. //
  746. // It's foreground to current translation.
  747. //
  748. ASSERTGDI(ptransFore != ptransCurrent, "Should have been identity, never get here");
  749. ASSERTGDI(ptransFore != NULL, "ERROR this should not have got here Fore");
  750. ASSERTGDI(ptransCurrent != NULL, "ERROR this should not have got here Current");
  751. for (ulTemp = 0; ulTemp < palDestDC.cEntries(); ulTemp++)
  752. {
  753. pxlate->ai[ptransFore->ajVector[ulTemp]] = (ULONG) ptransCurrent->ajVector[ulTemp];
  754. }
  755. //
  756. // Now map the default colors that are really there independant of logical palette.
  757. //
  758. if (palDestSurf.bIsNoStatic())
  759. {
  760. //
  761. // Only black and white are here.
  762. //
  763. pxlate->ai[0] = 0;
  764. pxlate->ai[255] = 255;
  765. }
  766. else if (!palDestSurf.bIsNoStatic256())
  767. {
  768. //
  769. // All the 20 holy colors are here.
  770. // Fix them up.
  771. //
  772. for (ulTemp = 0; ulTemp < 10; ulTemp++)
  773. {
  774. pxlate->ai[ulTemp] = ulTemp;
  775. pxlate->ai[ulTemp + 246] = ulTemp + 246;
  776. }
  777. }
  778. }
  779. }
  780. else if (palDestSurf.bIsMonochrome())
  781. {
  782. RtlZeroMemory(pxlate->ai, 256 * sizeof(ULONG));
  783. ulTemp = ulGetNearestIndexFromColorref(palSrc, palSrcDC, iBackSrc);
  784. ASSERTGDI(ulTemp < 256, "ERROR palSrc invalid - ulGetNearest is > 256");
  785. pxlate->vSetIndex(ulTemp, 1);
  786. pxlate->flXlate |= XO_TO_MONO;
  787. pxlate->iBackSrc = iBackSrc;
  788. }
  789. else
  790. {
  791. //
  792. // Blting from palette-managed bitmap to non-palette managed surface.
  793. //
  794. // Do all the non-default colors that are realized.
  795. //
  796. if (palDestSurf.cEntries() != 256)
  797. {
  798. //
  799. // If the dest is 256 entries we will just leave
  800. // the identity xlate as the initial state.
  801. // Otherwise we 0 it out so we don't have a translation
  802. // index left that's potentially bigger than the
  803. // destination palette.
  804. //
  805. RtlZeroMemory(pxlate->ai, 256 * sizeof(ULONG));
  806. }
  807. //
  808. // We need to fill in where the default colors map.
  809. //
  810. for (ulTemp = 0; ulTemp < 10; ulTemp++)
  811. {
  812. pxlate->ai[ulTemp] =
  813. palDestSurf.ulGetNearestFromPalentry(logDefaultPal.palPalEntry[ulTemp]);
  814. pxlate->ai[ulTemp + 246] =
  815. palDestSurf.ulGetNearestFromPalentry(logDefaultPal.palPalEntry[ulTemp+10]);
  816. }
  817. if (flCreateFlag & XLATE_USE_SURFACE_PAL)
  818. {
  819. //
  820. // Map directly to destination surface palette from source surface palette.
  821. //
  822. for (ulTemp = 0; ulTemp < palSrc.cEntries(); ulTemp++)
  823. {
  824. pxlate->ai[ulTemp] = palDestSurf.ulGetNearestFromPalentry(palSrc.palentryGet(ulTemp));
  825. }
  826. pxlate->flPrivate |= XLATE_USE_SURFACE_PAL;
  827. }
  828. else
  829. {
  830. //
  831. // Go through DC palette and then map to destination surface palette.
  832. //
  833. if (ptransFore != NULL)
  834. {
  835. for (ulTemp = 0; ulTemp < palDestDC.cEntries(); ulTemp++)
  836. {
  837. pxlate->ai[ptransFore->ajVector[ulTemp]] =
  838. palDestSurf.ulGetNearestFromPalentry(palDestDC.palentryGet(ulTemp));
  839. }
  840. }
  841. }
  842. }
  843. }
  844. else if (palSrc.bIsPalDibsection() &&
  845. ((palDestSurf.bValid() &&
  846. palDestSurf.bIsPalDibsection() &&
  847. bEqualRGB_In_Palette(palSrc, palDestSurf)
  848. ) ||
  849. (((!palDestSurf.bValid()) ||
  850. (palDestSurf.bIsPalManaged() && (ptransFore == ptransCurrent))
  851. ) &&
  852. bEqualRGB_In_Palette(palSrc, palDestDC)
  853. )
  854. )
  855. )
  856. {
  857. //
  858. // Blting from a Dibsection &&
  859. // ((To another Dibsection with ident palette) ||
  860. // (((To a compatible palette managed bitmap) ||
  861. // (To a palette managed screen with the DstDc's logical palette realized in the foreground)) &&
  862. // (the dst logical palette == Dibsection's palette)
  863. // ))
  864. //
  865. // This is identity. We do this special check so even if there are duplicate
  866. // colors in the palette we still get identity.
  867. //
  868. for (ulTemp = 0; ulTemp < 256; ulTemp++)
  869. {
  870. pxlate->ai[ulTemp] = ulTemp;
  871. }
  872. pxlate->flXlate |= XO_TRIVIAL;
  873. }
  874. else if ((palSrc.bIsPalManaged()) && (!palDestSurf.bValid()))
  875. {
  876. //
  877. // We are blting from the screen to a compatible bitmap on a palette
  878. // managed device where the screen is realized in the background.
  879. //
  880. //
  881. // Make it identity by default.
  882. //
  883. for (ulTemp = 0; ulTemp < 256; ulTemp++)
  884. {
  885. pxlate->ai[ulTemp] = ulTemp;
  886. }
  887. //
  888. // We are blting background to foreground.
  889. // i.e. we are blting current realize to foreground realize.
  890. //
  891. ASSERTGDI(pxlate->cEntries == 256, "ERROR xlate too small");
  892. ASSERTGDI(ptransFore != ptransCurrent, "Should have been identity, never get here");
  893. ASSERTGDI(ptransFore != NULL, "ERROR this should not have got here Fore");
  894. ASSERTGDI(ptransCurrent != NULL, "ERROR this should not have got here Current");
  895. for (ulTemp = 0; ulTemp < palDestDC.cEntries(); ulTemp++)
  896. {
  897. pxlate->ai[ptransCurrent->ajVector[ulTemp]] = (ULONG) ptransFore->ajVector[ulTemp];
  898. }
  899. //
  900. // Now map the default colors that are really there independant of logical palette realization.
  901. //
  902. if (palSrc.bIsNoStatic())
  903. {
  904. //
  905. // Only black and white are here.
  906. //
  907. pxlate->ai[0] = 0;
  908. pxlate->ai[255] = 255;
  909. }
  910. else if (!palSrc.bIsNoStatic256())
  911. {
  912. //
  913. // All the 20 holy colors are here.
  914. // Fix them up.
  915. //
  916. for (ulTemp = 0; ulTemp < 10; ulTemp++)
  917. {
  918. pxlate->ai[ulTemp] = ulTemp;
  919. pxlate->ai[ulTemp + 246] = ulTemp + 246;
  920. }
  921. }
  922. }
  923. else if (palSrc.bIsMonochrome())
  924. {
  925. if (palDestSurf.bIsMonochrome())
  926. {
  927. //
  928. // It's identity blt.
  929. //
  930. pxlate->vSetIndex(0, 0);
  931. pxlate->vSetIndex(1, 1);
  932. }
  933. else
  934. {
  935. if (bCMYKColor)
  936. {
  937. pxlate->vSetIndex(0, iForeDst);
  938. pxlate->vSetIndex(1, iBackDst);
  939. }
  940. else
  941. {
  942. pxlate->vSetIndex(0, ulGetNearestIndexFromColorref(palDestSurf,
  943. palDestDC,
  944. iForeDst));
  945. pxlate->vSetIndex(1, ulGetNearestIndexFromColorref(palDestSurf,
  946. palDestDC,
  947. iBackDst));
  948. }
  949. //
  950. // XLATE_FROM_MONO is set so we know to look at colors in
  951. // cache code for getting a hit.
  952. //
  953. pxlate->flPrivate |= XLATE_FROM_MONO;
  954. pxlate->iForeDst = iForeDst;
  955. pxlate->iBackDst = iBackDst;
  956. }
  957. }
  958. else if (cEntry == 0)
  959. {
  960. ASSERTGDI(palSrc.cEntries() == 0, "ERROR how could this happen");
  961. //
  962. // Src is a RGB/Bitfields palette.
  963. //
  964. if (palDestSurf.bIsMonochrome())
  965. {
  966. //
  967. // Put the color the Background of the source matches in pulXlate[0]
  968. //
  969. pxlate->ai[0] = ulGetNearestIndexFromColorref(palSrc, palSrcDC, iBackSrc);
  970. pxlate->flXlate |= XO_TO_MONO;
  971. pxlate->iBackSrc = iBackSrc;
  972. //
  973. // The S3 and other snazzy drivers look at this and get the color out
  974. // of slot 0 when XO_TO_MONO is set to get way better performance in
  975. // WinBench.
  976. //
  977. pxlate->pulXlate = pxlate->ai;
  978. }
  979. }
  980. else
  981. {
  982. //
  983. // Src is a regular indexed palette, it wouldn't have duplicating entries
  984. // in it so we don't need to check for the Dibsection case. This is like
  985. // a palette for a 16 color VGA or a printer or a SetDIBitsToDevice.
  986. //
  987. if (palDestSurf.bValid() && palDestSurf.bIsMonochrome())
  988. {
  989. RtlZeroMemory(pxlate->ai,(UINT) cEntry * sizeof(*pxlate->ai));
  990. cEntry = ulGetNearestIndexFromColorref(palSrc, palSrcDC, iBackSrc);
  991. ASSERTGDI(cEntry < pxlate->cEntries, "ERROR this is not in range");
  992. pxlate->vSetIndex(cEntry, 1);
  993. pxlate->flXlate |= XO_TO_MONO;
  994. pxlate->iBackSrc = iBackSrc;
  995. }
  996. else
  997. {
  998. if (bCMYKColor)
  999. {
  1000. //
  1001. // Copy source CMYK color table to index table.
  1002. //
  1003. while(cEntry--)
  1004. {
  1005. pxlate->ai[cEntry] = palSrc.ulEntryGet(cEntry);
  1006. }
  1007. }
  1008. else
  1009. {
  1010. //
  1011. // If the destination is palette managed, map to logical palette
  1012. // and then translate to physical indices accordingly. Otherwise
  1013. // map to the physical palette directly.
  1014. //
  1015. PPALETTE ppalTemp;
  1016. if (bPalManaged && !(flCreateFlag & XLATE_USE_SURFACE_PAL))
  1017. {
  1018. ppalTemp = palDestDC.ppalGet();
  1019. }
  1020. else
  1021. {
  1022. ppalTemp = palDestSurf.ppalGet();
  1023. if (flCreateFlag & XLATE_USE_SURFACE_PAL)
  1024. {
  1025. pxlate->flPrivate |= XLATE_USE_SURFACE_PAL;
  1026. }
  1027. }
  1028. XEPALOBJ palTemp(ppalTemp);
  1029. while(cEntry--)
  1030. {
  1031. pxlate->ai[cEntry] =
  1032. palTemp.ulGetNearestFromPalentry(
  1033. palSrc.palentryGet(cEntry));
  1034. }
  1035. if (bPalManaged && !(flCreateFlag & XLATE_USE_SURFACE_PAL))
  1036. {
  1037. //
  1038. // Map from DC palette to surface palette.
  1039. //
  1040. pxlate->vMapNewXlate((palDestSurf.bValid()) ? ptransCurrent
  1041. : ptransFore);
  1042. }
  1043. }
  1044. }
  1045. }
  1046. pxlate->vCheckForTrivial();
  1047. return(pxlate);
  1048. }
  1049. /******************************Public*Routine******************************\
  1050. * pCreateXlate
  1051. *
  1052. * This allocates an xlate object with ulNumEntries.
  1053. *
  1054. * Returns: The pointer to the xlate object, NULL for failure.
  1055. *
  1056. * History:
  1057. * 17-May-1991 -by- Patrick Haluptzok patrickh
  1058. * Wrote it.
  1059. \**************************************************************************/
  1060. PXLATE pCreateXlate(ULONG ulNumEntries)
  1061. {
  1062. //
  1063. // Allocate room for the XLATE.
  1064. //
  1065. PXLATE pxlate = (PXLATE) PALLOCNOZ((sizeof(XLATE) + sizeof(ULONG) * ulNumEntries),
  1066. 'tlxG');
  1067. if (pxlate != NULL)
  1068. {
  1069. pxlate->iUniq = ulGetNewUniqueness(ulXlatePalUnique);
  1070. if (ulNumEntries > 0)
  1071. {
  1072. pxlate->flXlate = XO_TABLE;
  1073. pxlate->pulXlate = pxlate->ai;
  1074. pxlate->flPrivate = 0;
  1075. }
  1076. else
  1077. {
  1078. pxlate->flXlate = 0;
  1079. pxlate->pulXlate = NULL;
  1080. pxlate->flPrivate = XLATE_RGB_SRC;
  1081. }
  1082. pxlate->iSrcType = pxlate->iDstType = 0;
  1083. pxlate->cEntries = ulNumEntries;
  1084. pxlate->lCacheIndex = XLATE_CACHE_INVALID;
  1085. pxlate->ppalSrc = (PPALETTE) NULL;
  1086. pxlate->ppalDst = (PPALETTE) NULL;
  1087. pxlate->ppalDstDC = (PPALETTE) NULL;
  1088. }
  1089. #if DBG
  1090. else
  1091. {
  1092. WARNING("pCreateXlate failed memory allocation\n");
  1093. }
  1094. #endif
  1095. return(pxlate);
  1096. }
  1097. /******************************Public*Routine******************************\
  1098. * vCheckForTrivial
  1099. *
  1100. * We need to check for trivial translation, it speeds up the inner-loop
  1101. * for blting a great deal.
  1102. *
  1103. * History:
  1104. *
  1105. * 11-Oct-1995 -by- Tom Zakrajsek [tomzak]
  1106. * Fixed it to not mark xlates as trivial unless the Src and Dst were
  1107. * the same color depth.
  1108. *
  1109. * 17-Oct-1993 -by- Patrick Haluptzok patrickh
  1110. * Wrote it.
  1111. \**************************************************************************/
  1112. VOID XLATE::vCheckForTrivial()
  1113. {
  1114. //
  1115. // Check if we already recognized trivial during creation
  1116. //
  1117. if (flXlate & XO_TRIVIAL)
  1118. return;
  1119. //
  1120. // Source Color is CMYK, XO_TRIVIAL will not be on.
  1121. //
  1122. if (flXlate & XO_FROM_CMYK)
  1123. return;
  1124. //
  1125. // See if it's really just a trivial xlate.
  1126. //
  1127. if (cEntries)
  1128. {
  1129. //
  1130. // Just make sure that each index translates to itself, and
  1131. // that the color depths are the same for the source and
  1132. // destination.
  1133. //
  1134. ULONG ulTemp;
  1135. if ((ppalSrc != NULL) &&
  1136. (ppalDst != NULL) &&
  1137. (ppalSrc->cEntries != ppalDst->cEntries))
  1138. {
  1139. return;
  1140. }
  1141. for (ulTemp = 0; ulTemp < cEntries; ulTemp++)
  1142. {
  1143. if (pulXlate[ulTemp] != ulTemp)
  1144. return;
  1145. }
  1146. }
  1147. else
  1148. {
  1149. //
  1150. // If the Src and Dst have the same masks it's identity.
  1151. //
  1152. XEPALOBJ palSrc(ppalSrc);
  1153. XEPALOBJ palDst(ppalDst);
  1154. if ((palSrc.bValid()) &&
  1155. (palDst.bValid()) &&
  1156. (!palDst.bIsIndexed()))
  1157. {
  1158. ASSERTGDI(!palSrc.bIsIndexed(), "ERROR Src not indexed?");
  1159. FLONG flRedSrc, flGreSrc, flBluSrc;
  1160. FLONG flRedDst, flGreDst, flBluDst;
  1161. if (palSrc.bIsBitfields())
  1162. {
  1163. flRedSrc = palSrc.flRed();
  1164. flGreSrc = palSrc.flGre();
  1165. flBluSrc = palSrc.flBlu();
  1166. }
  1167. else
  1168. {
  1169. flGreSrc = 0x0000FF00;
  1170. if (palSrc.bIsRGB())
  1171. {
  1172. flRedSrc = 0x000000FF;
  1173. flBluSrc = 0x00FF0000;
  1174. }
  1175. else
  1176. {
  1177. ASSERTGDI(palSrc.bIsBGR(), "What is it then?");
  1178. flRedSrc = 0x00FF0000;
  1179. flBluSrc = 0x000000FF;
  1180. }
  1181. }
  1182. if (palDst.bIsBitfields())
  1183. {
  1184. flRedDst = palDst.flRed();
  1185. flGreDst = palDst.flGre();
  1186. flBluDst = palDst.flBlu();
  1187. }
  1188. else
  1189. {
  1190. flGreDst = 0x0000FF00;
  1191. if (palDst.bIsRGB())
  1192. {
  1193. flRedDst = 0x000000FF;
  1194. flBluDst = 0x00FF0000;
  1195. }
  1196. else
  1197. {
  1198. ASSERTGDI(palDst.bIsBGR(), "What is it then?");
  1199. flRedDst = 0x00FF0000;
  1200. flBluDst = 0x000000FF;
  1201. }
  1202. }
  1203. if ((flRedSrc != flRedDst) ||
  1204. (flGreSrc != flGreDst) ||
  1205. (flBluSrc != flBluDst))
  1206. {
  1207. return;
  1208. }
  1209. }
  1210. else
  1211. return;
  1212. }
  1213. //
  1214. // We found it is really just trivial.
  1215. //
  1216. flXlate |= XO_TRIVIAL;
  1217. }
  1218. /******************************Public*Routine******************************\
  1219. * EXLATEOBJ::vAddToCache
  1220. *
  1221. * Adds an xlate object to the cache.
  1222. *
  1223. * Arguments:
  1224. *
  1225. * palSrc -
  1226. * palDst -
  1227. * palSrcDC -
  1228. * palDstDC -
  1229. *
  1230. * History:
  1231. * 13-Jun-1991 -by- Patrick Haluptzok patrickh
  1232. * Wrote it.
  1233. \**************************************************************************/
  1234. VOID
  1235. EXLATEOBJ::vAddToCache(
  1236. XEPALOBJ palSrc,
  1237. XEPALOBJ palDst,
  1238. XEPALOBJ palSrcDC,
  1239. XEPALOBJ palDstDC
  1240. )
  1241. {
  1242. ULONG cEntries;
  1243. SEMOBJ semo(ghsemPalette);
  1244. for (cEntries = 0; cEntries < XLATE_CACHE_SIZE; cEntries++)
  1245. {
  1246. ASSERTGDI(ulTableIndex < XLATE_CACHE_SIZE, "table index out of range");
  1247. if (xlateTable[ulTableIndex].pxlate != (PXLATE) 0)
  1248. {
  1249. if (xlateTable[ulTableIndex].ulReference != 0)
  1250. {
  1251. ulTableIndex = (ulTableIndex + 1) & XLATE_MODULA;
  1252. continue;
  1253. }
  1254. VFREEMEM(xlateTable[ulTableIndex].pxlate);
  1255. }
  1256. //
  1257. // Now add ours into the cache.
  1258. //
  1259. xlateTable[ulTableIndex].ulReference = 1;
  1260. xlateTable[ulTableIndex].pxlate = (PXLATE)pxlate;
  1261. xlateTable[ulTableIndex].ulPalSrc = palSrc.ulTime();
  1262. xlateTable[ulTableIndex].ulPalDst = palDst.ulTime();
  1263. xlateTable[ulTableIndex].ulPalSrcDC = palSrcDC.ulTime();
  1264. xlateTable[ulTableIndex].ulPalDstDC = palDstDC.ulTime();
  1265. //
  1266. // Mark it so the destructor doesn't free it
  1267. //
  1268. pxlate->lCacheIndex = (LONG) ulTableIndex;
  1269. //
  1270. // Put in palSrc the index where to be found most quickly
  1271. //
  1272. palSrc.iXlateIndex(ulTableIndex);
  1273. //
  1274. // Move the cache ahead so we don't get deleted right away
  1275. //
  1276. ulTableIndex = (ulTableIndex + 1) & XLATE_MODULA;
  1277. return;
  1278. }
  1279. }
  1280. /******************************Public*Routine******************************\
  1281. * EXLATEOBJ::bSearchCache
  1282. *
  1283. * Searches cache for a previously created xlate.
  1284. *
  1285. * Arguments:
  1286. *
  1287. * palSrc - src surface palette
  1288. * palDst - dst surface palette
  1289. * palSrcDC - src DC palette
  1290. * palDstDC - dst DC palette
  1291. * iForeDst - For Mono->Color this is what a 0 goes to
  1292. * iBackDst - For Mono->Color this is what a 1 goes to
  1293. * iBackSrc - For Color->Mono this is the color that goes to
  1294. * 1, all other colors go to 0.
  1295. *
  1296. * History:
  1297. * 13-Jun-1991 -by- Patrick Haluptzok patrickh
  1298. * Wrote it.
  1299. \**************************************************************************/
  1300. BOOL
  1301. EXLATEOBJ::bSearchCache(
  1302. XEPALOBJ palSrc,
  1303. XEPALOBJ palDst,
  1304. XEPALOBJ palSrcDC,
  1305. XEPALOBJ palDstDC,
  1306. ULONG iForeDst,
  1307. ULONG iBackDst,
  1308. ULONG iBackSrc,
  1309. ULONG flCreate
  1310. )
  1311. {
  1312. //
  1313. // Start ulIndex at the last place in the cache that an pxlate match was
  1314. // found for palSrc.
  1315. //
  1316. ULONG ulIndex = palSrc.iXlateIndex();
  1317. ULONG ulLoop;
  1318. SEMOBJ semo(ghsemPalette);
  1319. for (ulLoop = 0; ulLoop < XLATE_CACHE_SIZE; ulLoop++)
  1320. {
  1321. //
  1322. // If the destination is palette managed we need to make sure we are going
  1323. // through the correct Destination DC and that it is up to date.
  1324. //
  1325. if ((xlateTable[ulIndex].ulPalSrc == palSrc.ulTime()) &&
  1326. (xlateTable[ulIndex].ulPalDst == palDst.ulTime()) &&
  1327. (xlateTable[ulIndex].ulPalDstDC == palDstDC.ulTime()))
  1328. {
  1329. //
  1330. // Lock down all the cache objects.
  1331. //
  1332. pxlate = xlateTable[ulIndex].pxlate;
  1333. ASSERTGDI(bValid(), "GDIERROR:invalid pxlate xlate cache entry\n");
  1334. ASSERTGDI(pxlate->lCacheIndex == (LONG) ulIndex, "GDIERROR:bad xlate.lCacheIndex\n");
  1335. ASSERTGDI(!(pxlate->flPrivate & XLATE_RGB_SRC), "GDIERROR:a RGB_SRC in the cache ???\n");
  1336. ASSERTGDI(palSrc.cEntries() == pxlate->cEntries, "ERROR bSearchCache cEntries not matching palSrc");
  1337. //
  1338. // Now check if it's a to/from monochrome and if it is,
  1339. // are the fore/back colors still valid.
  1340. //
  1341. if (
  1342. (
  1343. ((XLATE_USE_SURFACE_PAL|XLATE_USE_FOREGROUND) & pxlate->flPrivate) == flCreate
  1344. )
  1345. &&
  1346. (
  1347. (
  1348. !((XO_TO_MONO & pxlate->flXlate) || (XLATE_FROM_MONO & pxlate->flPrivate))
  1349. )
  1350. ||
  1351. (
  1352. (XO_TO_MONO & pxlate->flXlate) &&
  1353. (iBackSrc == pxlate->iBackSrc) &&
  1354. (xlateTable[ulIndex].ulPalSrcDC == palSrcDC.ulTime())
  1355. )
  1356. ||
  1357. (
  1358. (XLATE_FROM_MONO & pxlate->flPrivate) &&
  1359. (iForeDst == pxlate->iForeDst) &&
  1360. (iBackDst == pxlate->iBackDst)
  1361. )
  1362. )
  1363. )
  1364. {
  1365. //
  1366. // HOT DOG, valid cache entry. It isn't deletable now
  1367. // because we have it locked down. Cache the index in palSrc.
  1368. //
  1369. InterlockedIncrement((LPLONG) &(xlateTable[ulIndex].ulReference));
  1370. palSrc.iXlateIndex(ulIndex);
  1371. return(TRUE);
  1372. }
  1373. }
  1374. ulIndex = (ulIndex + 1) & XLATE_MODULA;
  1375. }
  1376. pxlate = (PXLATE) NULL;
  1377. return(FALSE);
  1378. }
  1379. /******************************Public*Routine******************************\
  1380. * XLATEOBJ_iXlate
  1381. *
  1382. * This translates an index of a src palette to the closest index in the
  1383. * dst palette.
  1384. *
  1385. * Arguments:
  1386. *
  1387. * pxlo -
  1388. * cIndex -
  1389. *
  1390. * History:
  1391. * Mon 16-Mar-1992 -by- Patrick Haluptzok [patrickh]
  1392. * Fixed something.
  1393. *
  1394. * Wed 24-Jul-1991 -by- Patrick Haluptzok [patrickh]
  1395. * put in support for RGB-->monochrome.
  1396. *
  1397. * 22-Jul-1991 -by- Patrick Haluptzok patrickh
  1398. * Wrote it.
  1399. \**************************************************************************/
  1400. extern "C"
  1401. ULONG
  1402. XLATEOBJ_iXlate(
  1403. XLATEOBJ *pxlo,
  1404. ULONG cIndex
  1405. )
  1406. {
  1407. if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
  1408. {
  1409. return(cIndex);
  1410. }
  1411. if (pxlo->flXlate & XO_TABLE)
  1412. {
  1413. if (cIndex > pxlo->cEntries)
  1414. {
  1415. cIndex = cIndex % pxlo->cEntries;
  1416. }
  1417. return(((XLATE *) pxlo)->ai[cIndex]);
  1418. }
  1419. //
  1420. // We are beyond source palette being PAL_INDEXED.
  1421. //
  1422. if (pxlo->flXlate & XO_TO_MONO)
  1423. {
  1424. if (cIndex == ((XLATE *) pxlo)->ai[0])
  1425. {
  1426. return(1);
  1427. }
  1428. else
  1429. {
  1430. return(0);
  1431. }
  1432. }
  1433. ASSERTGDI(((XLATE *) pxlo)->ppalSrc != (PPALETTE) NULL, "ERROR ppalSrc is NULL");
  1434. //
  1435. // For 8bpp destinations, go through MarkE's optimized tablelookup code. This is
  1436. // not so much for performance reasons (XLATEOBJ_iXlate is already hopelessly slow),
  1437. // but to make sure GDI always performs this translation in the same way (with some drivers,
  1438. // StretchBlt to a device surface ends up in EngCopyBits which uses MarkE's table, but
  1439. // on the same machines StretchBlt to a memory surface goes through ulTranslate)
  1440. //
  1441. PPALETTE ppal = (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED ?
  1442. ((XLATE *) pxlo)->ppalDstDC : ((XLATE *) pxlo)->ppalDst);
  1443. ASSERTGDI(ppal != (PPALETTE) NULL, "ERROR ppal is NULL");
  1444. ASSERTGDI(((XLATE *) pxlo)->ppalDstDC != (PPALETTE) NULL, "ERROR ppalDstDC is NULL");
  1445. if ((ppal->flPal & PAL_INDEXED) &&
  1446. (((XLATE *) pxlo)->ppalDstDC->cEntries == 256))
  1447. {
  1448. PBYTE pxlate555 = ((XEPALOBJ) ppal).pGetRGBXlate();
  1449. if (pxlate555 == NULL)
  1450. {
  1451. WARNING1("Error in XLATEOBJ_iXlate: can't generate pxlate555");
  1452. return 0;
  1453. }
  1454. cIndex = XLATEOBJ_ulIndexToPalSurf(pxlo, pxlate555, cIndex);
  1455. }
  1456. else
  1457. {
  1458. PAL_ULONG palul;
  1459. palul.ul = ((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).ulIndexToRGB(cIndex);
  1460. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1461. {
  1462. ASSERTGDI(((XLATE *) pxlo)->ppalDstDC != (PPALETTE) NULL, "ERROR ppalDstDC is NULL");
  1463. cIndex = ((XEPALOBJ) (((XLATE *) pxlo)->ppalDstDC)).ulGetNearestFromPalentry(palul.pal, SE_DONT_SEARCH_EXACT_FIRST);
  1464. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1465. {
  1466. if (cIndex >= 10)
  1467. {
  1468. cIndex += 236;
  1469. }
  1470. }
  1471. else
  1472. {
  1473. ASSERTGDI(((XLATE *) pxlo)->ppalDstDC->flPal & PAL_DC, "ERROR in ulTranslate XLATEOBJ is hosed \n");
  1474. ASSERTGDI(cIndex < ((XLATE *) pxlo)->ppalDstDC->cEntries, "ERROR in ultranslate3");
  1475. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1476. {
  1477. cIndex = (ULONG) ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[cIndex];
  1478. }
  1479. else
  1480. {
  1481. cIndex = (ULONG) ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[cIndex];
  1482. }
  1483. }
  1484. }
  1485. else
  1486. {
  1487. ASSERTGDI(((XLATE *) pxlo)->ppalDst != (PPALETTE) NULL, "ERROR ppalDst is NULL");
  1488. cIndex = ((XEPALOBJ) (((XLATE *) pxlo)->ppalDst)).ulGetNearestFromPalentry(palul.pal, ((XEPALOBJ) (((XLATE *) pxlo)->ppalDst)).cEntries() ? SE_DONT_SEARCH_EXACT_FIRST : SE_DO_SEARCH_EXACT_FIRST);
  1489. }
  1490. }
  1491. return(cIndex);
  1492. }
  1493. /**************************************************************************\
  1494. * XLATEOBJ_pGetXlate555
  1495. *
  1496. * Retrieve 555 rgb xlate vector from appropriate palette
  1497. *
  1498. * Arguments:
  1499. *
  1500. * pxlo
  1501. *
  1502. * Return Value:
  1503. *
  1504. * rgb555 xlate vector or NULL
  1505. *
  1506. * History:
  1507. *
  1508. * 2/27/1997 Mark Enstrom [marke]
  1509. *
  1510. \**************************************************************************/
  1511. PBYTE
  1512. XLATEOBJ_pGetXlate555(
  1513. XLATEOBJ *pxlo
  1514. )
  1515. {
  1516. PBYTE pxlate555 = NULL;
  1517. //
  1518. // return hi color to palette 555 translate table if the xlateobj
  1519. // is appropriate
  1520. //
  1521. if (
  1522. (pxlo == NULL) ||
  1523. (pxlo->flXlate & XO_TRIVIAL) ||
  1524. (pxlo->flXlate & XO_TABLE) ||
  1525. (pxlo->flXlate & XO_TO_MONO)
  1526. )
  1527. {
  1528. return(NULL);
  1529. }
  1530. //
  1531. // determine palette type to map.
  1532. //
  1533. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1534. {
  1535. ASSERTGDI(((XLATE *) pxlo)->ppalDstDC != (PPALETTE) NULL, "ERROR ppalDstDC is NULL");
  1536. pxlate555 = ((XEPALOBJ) (((XLATE *) pxlo)->ppalDstDC)).pGetRGBXlate();
  1537. }
  1538. else
  1539. {
  1540. if (((XEPALOBJ) (((XLATE *) pxlo)->ppalDst)).bValid())
  1541. {
  1542. pxlate555 = ((XEPALOBJ) (((XLATE *) pxlo)->ppalDst)).pGetRGBXlate();
  1543. }
  1544. }
  1545. return(pxlate555);
  1546. }
  1547. /**************************************************************************\
  1548. * XLATEOBJ_ulIndexToPalSurf
  1549. * - take generic pixel input, convert it to RGB, then use the rgb555
  1550. * to palette index table to look up a palette index
  1551. *
  1552. * Arguments:
  1553. *
  1554. * pxlo - xlate object
  1555. * pxlate555 - member of dest palette object, 555RGB to palette
  1556. * ulRGB - index input
  1557. *
  1558. *
  1559. * Return Value:
  1560. *
  1561. * Destination 8 bit pixel
  1562. *
  1563. * History:
  1564. *
  1565. * 2/20/1997 Mark Enstrom [marke]
  1566. *
  1567. \**************************************************************************/
  1568. BYTE
  1569. XLATEOBJ_ulIndexToPalSurf(
  1570. XLATEOBJ *pxlo,
  1571. PBYTE pxlate555,
  1572. ULONG ulRGB
  1573. )
  1574. {
  1575. ALPHAPIX apix;
  1576. BYTE palIndex = 0;
  1577. ASSERTGDI(pxlate555 != NULL,"XLATEOBJ_ulIndexToPalSurf: NULL pxlate555\n");
  1578. apix.ul = ulRGB;
  1579. apix.ul = ((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).ulIndexToRGB(ulRGB);
  1580. palIndex = pxlate555[((apix.pix.b & 0xf8) << 7) |
  1581. ((apix.pix.g & 0xf8) << 2) |
  1582. ((apix.pix.r & 0xf8) >> 3)];
  1583. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1584. {
  1585. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1586. {
  1587. if (palIndex >= 10)
  1588. {
  1589. palIndex += 236;
  1590. }
  1591. }
  1592. else
  1593. {
  1594. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1595. {
  1596. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[palIndex];
  1597. }
  1598. else
  1599. {
  1600. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[palIndex];
  1601. }
  1602. }
  1603. }
  1604. return(palIndex);
  1605. }
  1606. /**************************************************************************\
  1607. * XLATEOBJ_RGB32ToPalSurf
  1608. * - take 32 RGB pixel input, then use the rgb555
  1609. * to palette index table to look up a palette index
  1610. *
  1611. * Arguments:
  1612. *
  1613. * pxlo - xlate object
  1614. * pxlate555 - member of dest palette object, 555RGB to palette
  1615. * ulRGB - 32 bit RGB input pixel
  1616. *
  1617. *
  1618. * Return Value:
  1619. *
  1620. * Destination 8 bit pixel
  1621. *
  1622. * History:
  1623. *
  1624. * 2/20/1997 Mark Enstrom [marke]
  1625. *
  1626. \**************************************************************************/
  1627. BYTE
  1628. XLATEOBJ_RGB32ToPalSurf(
  1629. XLATEOBJ *pxlo,
  1630. PBYTE pxlate555,
  1631. ULONG ulRGB
  1632. )
  1633. {
  1634. ALPHAPIX apix;
  1635. BYTE palIndex = 0;
  1636. ASSERTGDI(pxlate555 != NULL,"XLATEOBJ_RGB32ToPalSurf: NULL pxlate555\n");
  1637. apix.ul = ulRGB;
  1638. palIndex = pxlate555[((apix.pix.b & 0xf8) << 7) |
  1639. ((apix.pix.g & 0xf8) << 2) |
  1640. ((apix.pix.r & 0xf8) >> 3)];
  1641. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1642. {
  1643. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1644. {
  1645. if (palIndex >= 10)
  1646. {
  1647. palIndex += 236;
  1648. }
  1649. }
  1650. else
  1651. {
  1652. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1653. {
  1654. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[palIndex];
  1655. }
  1656. else
  1657. {
  1658. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[palIndex];
  1659. }
  1660. }
  1661. }
  1662. return(palIndex);
  1663. }
  1664. /**************************************************************************\
  1665. * XLATEOBJ_RGB32ToPalSurf
  1666. * - take 32 BGR pixel input, then use the rgb555
  1667. * to palette index table to look up a palette index
  1668. *
  1669. * Arguments:
  1670. *
  1671. * pxlo - xlate object
  1672. * pxlate555 - member of dest palette object, 555RGB to palette
  1673. * ulRGB - 32 bit BGR input pixel
  1674. *
  1675. *
  1676. * Return Value:
  1677. *
  1678. * Destination 8 bit pixel
  1679. *
  1680. * History:
  1681. *
  1682. * 2/20/1997 Mark Enstrom [marke]
  1683. *
  1684. \**************************************************************************/
  1685. BYTE
  1686. XLATEOBJ_BGR32ToPalSurf(
  1687. XLATEOBJ *pxlo,
  1688. PBYTE pxlate555,
  1689. ULONG ulRGB
  1690. )
  1691. {
  1692. BYTE palIndex;
  1693. ALPHAPIX apix;
  1694. ASSERTGDI(pxlate555 != NULL,"XLATEOBJ_BGR32ToPalSurf: NULL pxlate555\n");
  1695. apix.ul = ulRGB;
  1696. palIndex = pxlate555[((apix.pix.r & 0xf8) << 7) |
  1697. ((apix.pix.g & 0xf8) << 2) |
  1698. ((apix.pix.b & 0xf8) >> 3)];
  1699. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1700. {
  1701. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1702. {
  1703. if (palIndex >= 10)
  1704. {
  1705. palIndex += 236;
  1706. }
  1707. }
  1708. else
  1709. {
  1710. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1711. {
  1712. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[palIndex];
  1713. }
  1714. else
  1715. {
  1716. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[palIndex];
  1717. }
  1718. }
  1719. }
  1720. return(palIndex);
  1721. }
  1722. /**************************************************************************\
  1723. * XLATEOBJ_RGB16_565ToPalSurf
  1724. * - take 16 bit 565 pixel input, then use the rgb555
  1725. * to palette index table to look up a palette index
  1726. *
  1727. * Arguments:
  1728. *
  1729. * pxlo - xlate object
  1730. * pxlate555 - member of dest palette object, 555RGB to palette
  1731. * ulRGB - 16 bit 565 input pixel
  1732. *
  1733. *
  1734. * Return Value:
  1735. *
  1736. * Destination 8 bit pixel
  1737. *
  1738. * History:
  1739. *
  1740. * 2/20/1997 Mark Enstrom [marke]
  1741. *
  1742. \**************************************************************************/
  1743. BYTE
  1744. XLATEOBJ_RGB16_565ToPalSurf(
  1745. XLATEOBJ *pxlo,
  1746. PBYTE pxlate555,
  1747. ULONG ulRGB
  1748. )
  1749. {
  1750. BYTE palIndex = 0;
  1751. ASSERTGDI(pxlate555 != NULL,"XLATEOBJ_BGR16_565ToPalSurf: NULL pxlate555\n");
  1752. palIndex = pxlate555[((ulRGB & 0xf800) >> 1) |
  1753. ((ulRGB & 0x07c0) >> 1) |
  1754. ((ulRGB & 0x001f))];
  1755. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1756. {
  1757. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1758. {
  1759. if (palIndex >= 10)
  1760. {
  1761. palIndex += 236;
  1762. }
  1763. }
  1764. else
  1765. {
  1766. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1767. {
  1768. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[palIndex];
  1769. }
  1770. else
  1771. {
  1772. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[palIndex];
  1773. }
  1774. }
  1775. }
  1776. return(palIndex);
  1777. }
  1778. /**************************************************************************\
  1779. * XLATEOBJ_RGB16_555ToPalSurf
  1780. * - take 16 bit 555 pixel input, then use the rgb555
  1781. * to palette index table to look up a palette index
  1782. *
  1783. * Arguments:
  1784. *
  1785. * pxlo - xlate object
  1786. * pxlate555 - member of dest palette object, 555RGB to palette
  1787. * ulRGB - 16 bit 555 input pixel
  1788. *
  1789. *
  1790. * Return Value:
  1791. *
  1792. * Destination 8 bit pixel
  1793. *
  1794. * History:
  1795. *
  1796. * 2/20/1997 Mark Enstrom [marke]
  1797. *
  1798. \**************************************************************************/
  1799. BYTE
  1800. XLATEOBJ_RGB16_555ToPalSurf(
  1801. XLATEOBJ *pxlo,
  1802. PBYTE pxlate555,
  1803. ULONG ulRGB
  1804. )
  1805. {
  1806. BYTE palIndex = 0;
  1807. ASSERTGDI(pxlate555 != NULL,"XLATEOBJ_BGR16_555ToPalSurf: NULL pxlate555\n");
  1808. palIndex = pxlate555[ulRGB & 0x7fff];
  1809. if (((XLATE *) pxlo)->flPrivate & XLATE_PAL_MANAGED)
  1810. {
  1811. if (((XLATE *) pxlo)->ppalDstDC == ppalDefault)
  1812. {
  1813. if (palIndex >= 10)
  1814. {
  1815. palIndex += 236;
  1816. }
  1817. }
  1818. else
  1819. {
  1820. if (((XLATE *) pxlo)->flPrivate & XLATE_USE_CURRENT)
  1821. {
  1822. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransCurrent->ajVector[palIndex];
  1823. }
  1824. else
  1825. {
  1826. palIndex = ((XLATE *) pxlo)->ppalDstDC->ptransFore->ajVector[palIndex];
  1827. }
  1828. }
  1829. }
  1830. return(palIndex);
  1831. }
  1832. /******************************Public*Routine******************************\
  1833. * XLATEMEMOBJ
  1834. *
  1835. * This is a special constructor for the UpdateColors case. It deletes the
  1836. * old xlate when it is done.
  1837. *
  1838. * History:
  1839. * 12-Dec-1991 -by- Patrick Haluptzok patrickh
  1840. * Wrote it.
  1841. \**************************************************************************/
  1842. XLATEMEMOBJ::XLATEMEMOBJ(
  1843. XEPALOBJ palSurf,
  1844. XEPALOBJ palDC
  1845. )
  1846. {
  1847. //
  1848. // Assert some fundamental truths.
  1849. //
  1850. ASSERTGDI(palDC.bValid(), "invalid palDC in xlatememobj123\n");
  1851. ASSERTGDI(palSurf.bIsPalManaged(), "invalid surface palette in UpdateColors xlate");
  1852. ASSERTGDI(palSurf.bValid(), "invalid palSurf in xlatememobj123\n");
  1853. ASSERTGDI(!(palDC.bIsRGB()), "RGB palDC in DC->surf xlate constructor123\n");
  1854. ASSERTGDI(!(palSurf.bIsRGB()), "RGB palSurf in DC->surf xlate constructor123\n");
  1855. ASSERTGDI(palDC.bIsPalDC(), "not a palDC for palDC in xlatememobj123\n");
  1856. ASSERTGDI(palDC.ptransCurrent() != NULL, "ERROR ptrans Null UpdateColors");
  1857. ASSERTGDI(palDC.ptransOld() != NULL, "ERROR ptransOld Null UpdateColors");
  1858. ULONG ulTemp;
  1859. PULONG pulTemp;
  1860. pxlate = pCreateXlate(palSurf.cEntries());
  1861. if (pxlate)
  1862. {
  1863. pxlate->ppalSrc = palSurf.ppalGet();
  1864. pxlate->ppalDst = palSurf.ppalGet();
  1865. pxlate->ppalDstDC = palDC.ppalGet();
  1866. pulTemp = pxlate->ai;
  1867. //
  1868. // Set up identity vector for all entries
  1869. //
  1870. for (ulTemp = 0; ulTemp < pxlate->cEntries; ulTemp++)
  1871. {
  1872. pulTemp[ulTemp] = ulTemp;
  1873. }
  1874. //
  1875. // Change the ones that are affected by the palette realizations.
  1876. //
  1877. PTRANSLATE ptransOld = palDC.ptransOld();
  1878. PTRANSLATE ptransCurrent = palDC.ptransCurrent();
  1879. for (ulTemp = 0; ulTemp < palDC.cEntries(); ulTemp++)
  1880. {
  1881. pulTemp[ptransOld->ajVector[ulTemp]] = (ULONG) ptransCurrent->ajVector[ulTemp];
  1882. }
  1883. pxlate->vCheckForTrivial();
  1884. }
  1885. }
  1886. /******************************Public*Routine******************************\
  1887. * EXLATEOBJ::bCreateXlateFromTable
  1888. *
  1889. * This is used to initialize an xlate when the table is already computed.
  1890. * We need this to support journaling.
  1891. *
  1892. * History:
  1893. * 17-Mar-1992 -by- Patrick Haluptzok patrickh
  1894. * Wrote it.
  1895. \**************************************************************************/
  1896. BOOL
  1897. EXLATEOBJ::bCreateXlateFromTable(
  1898. ULONG cEntry,
  1899. PULONG pulVector,
  1900. XEPALOBJ palDst
  1901. )
  1902. {
  1903. //
  1904. // Assert good input data.
  1905. //
  1906. ASSERTGDI(palDst.bValid(), "ERROR bInitXlate bad palDst");
  1907. ASSERTGDI(pulVector != (PULONG) NULL, "ERROR bInitXlate bad pulVector");
  1908. ASSERTGDI(cEntry != 0, "ERROR bInitXlate cEntry is 0");
  1909. //
  1910. // Allocate room for the Xlate.
  1911. //
  1912. pxlate = pCreateXlate(cEntry);
  1913. if (pxlate == NULL)
  1914. {
  1915. WARNING("ERROR bInitXlate failed call to pCreateXlate\n");
  1916. return(FALSE);
  1917. }
  1918. pxlate->ppalDst = palDst.ppalGet();
  1919. pxlate->iDstType = (USHORT) palDst.iPalMode();
  1920. //
  1921. // Ok, fill in the xlate vector.
  1922. //
  1923. RtlCopyMemory(pxlate->ai, pulVector, (UINT) (cEntry * sizeof(ULONG)));
  1924. //
  1925. // Init accelerators, out of here.
  1926. //
  1927. pxlate->vCheckForTrivial();
  1928. return(TRUE);
  1929. }
  1930. /******************************Public*Routine******************************\
  1931. * XLATE::vCheckForICM()
  1932. *
  1933. * History:
  1934. * 26-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  1935. * Wrote it.
  1936. \**************************************************************************/
  1937. VOID XLATE::vCheckForICM(HANDLE _hcmXform,ULONG _lIcmMode)
  1938. {
  1939. //
  1940. // First, initialize ICM mode as default (off)
  1941. //
  1942. lIcmMode = DC_ICM_OFF;
  1943. hcmXform = NULL;
  1944. //
  1945. // Check is there any ICM is enabled ?
  1946. //
  1947. if (IS_ICM_ON(_lIcmMode))
  1948. {
  1949. if (IS_ICM_INSIDEDC(_lIcmMode))
  1950. {
  1951. //
  1952. // Inside DC ICM is enabled with valid color transform.
  1953. //
  1954. //
  1955. // Copy mode and color transform handle to XLATE.
  1956. //
  1957. lIcmMode = _lIcmMode;
  1958. hcmXform = _hcmXform;
  1959. if (IS_ICM_DEVICE(lIcmMode))
  1960. {
  1961. COLORTRANSFORMOBJ CXFormObj(_hcmXform);
  1962. //
  1963. // Check transform handle is valid or not.
  1964. //
  1965. if (CXFormObj.bValid())
  1966. {
  1967. ICMMSG(("vCheckForICM():XO_DEVICE_ICM\n"));
  1968. //
  1969. // Device driver will do color matching.
  1970. //
  1971. flXlate |= XO_DEVICE_ICM;
  1972. }
  1973. }
  1974. else if (IS_ICM_HOST(lIcmMode))
  1975. {
  1976. ICMMSG(("vCheckForICM():XO_HOST_ICM\n"));
  1977. //
  1978. // Inform the images is corrected by host CMM
  1979. //
  1980. flXlate |= XO_HOST_ICM;
  1981. if (IS_CMYK_COLOR(lIcmMode) && (hcmXform != NULL))
  1982. {
  1983. ICMMSG(("vCheckForICM():XO_FROM_CMYK\n"));
  1984. //
  1985. // The destination surface is 32bits CMYK color,
  1986. // This is only happen when ICM is done by host.
  1987. //
  1988. flXlate |= XO_FROM_CMYK;
  1989. }
  1990. }
  1991. }
  1992. else if (IS_ICM_OUTSIDEDC(_lIcmMode))
  1993. {
  1994. //
  1995. // Outside DC is enabled, color correction is done by application.
  1996. //
  1997. //
  1998. // Copy mode and color transform handle to XLATE.
  1999. //
  2000. lIcmMode = _lIcmMode;
  2001. hcmXform = 0;
  2002. //
  2003. // Inform the images is corrected by Host (application) ICM
  2004. //
  2005. flXlate |= XO_HOST_ICM;
  2006. }
  2007. }
  2008. }
  2009. /******************************Public*Routine******************************\
  2010. * vXlateBitfieldsToBitfields
  2011. *
  2012. * Translates a color between to arbitrary bitfield (or RGB or BGR) formats.
  2013. \**************************************************************************/
  2014. ULONG FASTCALL iXlateBitfieldsToBitfields(XLATEOBJ* pxlo, ULONG ul)
  2015. {
  2016. ul = ((XEPALOBJ) ((XLATE *) pxlo)->ppalSrc).ulIndexToRGB(ul);
  2017. ul = ((XEPALOBJ) ((XLATE *) pxlo)->ppalDst).ulGetNearestFromPalentry(
  2018. *((PALETTEENTRY*) &ul));
  2019. return(ul);
  2020. }
  2021. ULONG FASTCALL iXlate565ToBGR(XLATEOBJ *pxlo, ULONG ul)
  2022. {
  2023. return(((ul << 8) & 0xf80000)
  2024. | ((ul << 3) & 0x070000)
  2025. | ((ul << 5) & 0x00fc00)
  2026. | ((ul >> 1) & 0x000300)
  2027. | ((ul << 3) & 0x0000f8)
  2028. | ((ul >> 2) & 0x000007));
  2029. }
  2030. ULONG FASTCALL iXlate555ToBGR(XLATEOBJ *pxlo, ULONG ul)
  2031. {
  2032. return(((ul << 9) & 0xf80000)
  2033. | ((ul << 4) & 0x070000)
  2034. | ((ul << 6) & 0x00f800)
  2035. | ((ul << 1) & 0x000700)
  2036. | ((ul << 3) & 0x0000f8)
  2037. | ((ul >> 2) & 0x000007));
  2038. }
  2039. ULONG FASTCALL iXlateBGRTo565(XLATEOBJ *pxlo, ULONG ul)
  2040. {
  2041. return(((ul >> 8) & 0xf800)
  2042. | ((ul >> 5) & 0x07e0)
  2043. | ((ul >> 3) & 0x001f));
  2044. }
  2045. ULONG FASTCALL iXlateBGRTo555(XLATEOBJ *pxlo, ULONG ul)
  2046. {
  2047. return(((ul >> 9) & 0x7c00)
  2048. | ((ul >> 6) & 0x03e0)
  2049. | ((ul >> 3) & 0x001f));
  2050. }
  2051. /******************************Public*Routine******************************\
  2052. * pfnXlateBetweenBitfields
  2053. *
  2054. * Returns a pointer to an optimized routine for converting between
  2055. * two bitfields (or RGB or BGR) colors.
  2056. \**************************************************************************/
  2057. PFN_pfnXlate XLATE::pfnXlateBetweenBitfields()
  2058. {
  2059. PFN_pfnXlate pfnXlate;
  2060. XEPALOBJ palSrc(ppalSrc);
  2061. XEPALOBJ palDst(ppalDst);
  2062. ASSERTGDI(palSrc.bIsBitfields() || palSrc.bIsRGB() || palSrc.bIsBGR(),
  2063. "ERROR: Expected bitfields source");
  2064. ASSERTGDI(palDst.bIsBitfields() || palDst.bIsRGB() || palDst.bIsBGR(),
  2065. "ERROR: Expected bitfields destination");
  2066. pfnXlate = iXlateBitfieldsToBitfields;
  2067. if (palDst.bIsBGR())
  2068. {
  2069. if (palSrc.bIs565())
  2070. {
  2071. pfnXlate = iXlate565ToBGR;
  2072. }
  2073. else if (palSrc.bIs555())
  2074. {
  2075. pfnXlate = iXlate555ToBGR;
  2076. }
  2077. }
  2078. else if (palSrc.bIsBGR())
  2079. {
  2080. if (palDst.bIs565())
  2081. {
  2082. pfnXlate = iXlateBGRTo565;
  2083. }
  2084. else if (palDst.bIs555())
  2085. {
  2086. pfnXlate = iXlateBGRTo555;
  2087. }
  2088. }
  2089. return(pfnXlate);
  2090. }