ReactOS 0.4.16-dev-2207-geb15453
xlateobj.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: GDI Color Translation Functions
5 * FILE: win32ss/gdi/eng/xlateobj.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9#include <win32k.h>
10
11#define NDEBUG
12#include <debug.h>
13
15_Function_class_(FN_XLATE)
18EXLATEOBJ_iXlateTrivial(
19 _In_ PEXLATEOBJ pexlo,
21
24EXLATEOBJ gexloTrivial = {{0, XO_TRIVIAL, 0, 0, 0, 0}, EXLATEOBJ_iXlateTrivial};
25
27
28static const BYTE gajXlate5to8[32] =
29{ 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99,107,115,123,
30 132,140,148,156,165,173,181,189,197,206,214,222,231,239,247,255};
31
32static const BYTE gajXlate6to8[64] =
33{ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 52, 57, 61,
34 65, 69, 73, 77, 81, 85, 89, 93, 97,101,105,109,113,117,121,125,
35130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,
36194,198,202,207,210,215,219,223,227,231,235,239,243,247,251,255};
37
38
42_Function_class_(FN_XLATE)
45EXLATEOBJ_iXlateTrivial(
46 _In_ PEXLATEOBJ pexlo,
48{
49 return iColor;
50}
51
55EXLATEOBJ_iXlateMonoInvert(
56 _In_ PEXLATEOBJ pexlo,
58{
59 return iColor ^ 1;
60}
61
62_Function_class_(FN_XLATE)
65EXLATEOBJ_iXlateMonoTo0(
66 _In_ PEXLATEOBJ pexlo,
68{
69 return 0;
70}
71
72_Function_class_(FN_XLATE)
75EXLATEOBJ_iXlateMonoTo1(
76 _In_ PEXLATEOBJ pexlo,
78{
79 return 1;
80}
81
82_Function_class_(FN_XLATE)
85EXLATEOBJ_iXlateRGBToBW(_In_ PEXLATEOBJ pexlo, ULONG iColor)
86{
90 return ((r + g + b) >= 383);
91}
92
93_Function_class_(FN_XLATE)
96EXLATEOBJ_iXlateRGBToWB(_In_ PEXLATEOBJ pexlo, ULONG iColor)
97{
101 return ((r + g + b) < 383);
102}
103
104_Function_class_(FN_XLATE)
105ULONG
107EXLATEOBJ_iXlateRGBToMono(_In_ PEXLATEOBJ pexlo, ULONG rgbColor)
108{
109 /* Get the RGB values */
110 LONG r = GetRValue(rgbColor);
111 LONG g = GetGValue(rgbColor);
112 LONG b = GetBValue(rgbColor);
113
114 /* Calculate the dot product of the color vector and the
115 back-to-fore distance vector. */
116 LONG lDist = r * pexlo->ToMono.lDeltaR +
117 g * pexlo->ToMono.lDeltaG +
118 b * pexlo->ToMono.lDeltaB;
119
120 return (lDist > pexlo->ToMono.lHalfDist);
121}
122
123_Function_class_(FN_XLATE)
124ULONG
126EXLATEOBJ_iXlateBGRToMono(_In_ PEXLATEOBJ pexlo, ULONG rgbColor)
127{
128 /* Inverted usage of the color macros compared to RGB! */
129 LONG b = GetRValue(rgbColor);
130 LONG g = GetGValue(rgbColor);
131 LONG r = GetBValue(rgbColor);
132
133 /* Calculate the dot product of the color vector and the
134 back-to-fore distance vector. */
135 LONG lDist = r * pexlo->ToMono.lDeltaR +
136 g * pexlo->ToMono.lDeltaG +
137 b * pexlo->ToMono.lDeltaB;
138
139 return (lDist > pexlo->ToMono.lHalfDist);
140}
141
142static
143VOID
145 _Inout_ PEXLATEOBJ pexlo,
146 _In_ ULONG rgbBack,
147 _In_ ULONG rgbFore,
148 _In_ BOOL bIsBGR)
149{
150 /* Check if dest durface is B/W or W/B */
151 if ((rgbBack == 0x000000) && (rgbFore == 0xFFFFFF))
152 {
153 /* Black/White (symmetric between RGB and BGR) */
154 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBToBW;
155 }
156 else if ((rgbBack == 0xFFFFFF) && (rgbFore == 0x000000))
157 {
158 /* White/Black (symmetric between RGB and BGR) */
159 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBToWB;
160 }
161 else
162 {
163 /* Use generic mono translation function */
164 if (bIsBGR)
165 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRToMono;
166 else
167 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBToMono;
168
169 /* Precompute evaluation constants */
170 LONG lForeR = GetRValue(rgbFore);
171 LONG lForeG = GetGValue(rgbFore);
172 LONG lForeB = GetBValue(rgbFore);
173 LONG lBackR = GetRValue(rgbBack);
174 LONG lBackG = GetGValue(rgbBack);
175 LONG lBackB = GetBValue(rgbBack);
176 pexlo->ToMono.lDeltaR = lForeR - lBackR;
177 pexlo->ToMono.lDeltaG = lForeG - lBackG;
178 pexlo->ToMono.lDeltaB = lForeB - lBackB;
179 pexlo->ToMono.lHalfDist =
180 (((lForeR * lForeR) + (lForeG * lForeG) + (lForeB * lForeB)) -
181 ((lBackR * lBackR) + (lBackG * lBackG) + (lBackB * lBackB))) / 2;
182 }
183}
184
185_Function_class_(FN_XLATE)
186ULONG
188EXLATEOBJ_iXlateToMono(_In_ PEXLATEOBJ pexlo, ULONG iColor)
189{
190 return (iColor == pexlo->xlo.pulXlate[0]);
191}
192
193_Function_class_(FN_XLATE)
194ULONG
196EXLATEOBJ_iXlateTable(PEXLATEOBJ pexlo, ULONG iColor)
197{
198 if (iColor >= pexlo->xlo.cEntries) return 0;
199 return pexlo->xlo.pulXlate[iColor];
200}
201
202_Function_class_(FN_XLATE)
203ULONG
205EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor)
206{
207 ULONG iNewColor;
208
209 /* Copy green */
210 iNewColor = iColor & 0xff00ff00;
211
212 /* Mask red and blue */
213 iColor &= 0x00ff00ff;
214
215 /* Shift and copy red and blue */
216 iNewColor |= iColor >> 16;
217 iNewColor |= iColor << 16;
218
219 return iNewColor;
220}
221
222_Function_class_(FN_XLATE)
223ULONG
225EXLATEOBJ_iXlateRGBto555(PEXLATEOBJ pxlo, ULONG iColor)
226{
227 ULONG iNewColor;
228
229 /* Copy red */
230 iColor <<= 7;
231 iNewColor = iColor & 0x7C00;
232
233 /* Copy green */
234 iColor >>= 13;
235 iNewColor |= iColor & 0x3E0;
236
237 /* Copy blue */
238 iColor >>= 13;
239 iNewColor |= iColor & 0x1F;
240
241 return iNewColor;
242}
243
244_Function_class_(FN_XLATE)
245ULONG
247EXLATEOBJ_iXlateBGRto555(PEXLATEOBJ pxlo, ULONG iColor)
248{
249 ULONG iNewColor;
250
251 /* Copy blue */
252 iColor >>= 3;
253 iNewColor = iColor & 0x1f;
254
255 /* Copy green */
256 iColor >>= 3;
257 iNewColor |= (iColor & 0x3E0);
258
259 /* Copy red */
260 iColor >>= 3;
261 iNewColor |= (iColor & 0x7C00);
262
263 return iNewColor;
264}
265
266_Function_class_(FN_XLATE)
267ULONG
269EXLATEOBJ_iXlateRGBto565(PEXLATEOBJ pxlo, ULONG iColor)
270{
271 ULONG iNewColor;
272
273 /* Copy red */
274 iColor <<= 8;
275 iNewColor = iColor & 0xF800;
276
277 /* Copy green */
278 iColor >>= 13;
279 iNewColor |= iColor & 0x7E0;
280
281 /* Copy green */
282 iColor >>= 14;
283 iNewColor |= iColor & 0x1F;
284
285 return iNewColor;
286}
287
288_Function_class_(FN_XLATE)
289ULONG
291EXLATEOBJ_iXlateBGRto565(PEXLATEOBJ pxlo, ULONG iColor)
292{
293 ULONG iNewColor;
294
295 /* Copy blue */
296 iColor >>= 3;
297 iNewColor = iColor & 0x1f;
298
299 /* Copy green */
300 iColor >>= 2;
301 iNewColor |= (iColor & 0x7E0);
302
303 /* Copy red */
304 iColor >>= 3;
305 iNewColor |= (iColor & 0xF800);
306
307 return iNewColor;
308}
309
310_Function_class_(FN_XLATE)
311ULONG
313EXLATEOBJ_iXlateRGBtoPal(PEXLATEOBJ pexlo, ULONG iColor)
314{
316}
317
318_Function_class_(FN_XLATE)
319ULONG
321EXLATEOBJ_iXlate555toRGB(PEXLATEOBJ pxlo, ULONG iColor)
322{
323 ULONG iNewColor;
324
325 /* Copy blue */
326 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
327
328 /* Copy green */
329 iColor >>= 5;
330 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
331
332 /* Copy red */
333 iColor >>= 5;
334 iNewColor |= gajXlate5to8[iColor & 0x1F];
335
336 return iNewColor;
337}
338
339_Function_class_(FN_XLATE)
340ULONG
342EXLATEOBJ_iXlate555toBGR(PEXLATEOBJ pxlo, ULONG iColor)
343{
344 ULONG iNewColor;
345
346 /* Copy blue */
347 iNewColor = gajXlate5to8[iColor & 0x1F];
348
349 /* Copy green */
350 iColor >>= 5;
351 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
352
353 /* Copy red */
354 iColor >>= 5;
355 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
356
357 return iNewColor;
358}
359
360_Function_class_(FN_XLATE)
361ULONG
363EXLATEOBJ_iXlate555to565(PEXLATEOBJ pxlo, ULONG iColor)
364{
365 ULONG iNewColor;
366
367 /* Copy blue */
368 iNewColor = iColor & 0x1f;
369
370 /* Copy red and green */
371 iColor <<= 1;
372 iNewColor |= iColor & 0xFFC0;
373
374 /* Duplicate highest green bit */
375 iColor >>= 5;
376 iNewColor |= (iColor & 0x20);
377
378 return iNewColor;
379}
380
381_Function_class_(FN_XLATE)
382ULONG
384EXLATEOBJ_iXlate555toPal(PEXLATEOBJ pexlo, ULONG iColor)
385{
386 iColor = EXLATEOBJ_iXlate555toRGB(pexlo, iColor);
387
389}
390
391_Function_class_(FN_XLATE)
392ULONG
394EXLATEOBJ_iXlate565to555(PEXLATEOBJ pxlo, ULONG iColor)
395{
396 ULONG iNewColor;
397
398 /* Copy blue */
399 iNewColor = iColor & 0x1f;
400
401 /* Copy red and green */
402 iColor >>= 1;
403 iNewColor |= iColor & 0x7FE0;
404
405 return iNewColor;
406}
407
408_Function_class_(FN_XLATE)
409ULONG
411EXLATEOBJ_iXlate565toRGB(PEXLATEOBJ pexlo, ULONG iColor)
412{
413 ULONG iNewColor;
414
415 /* Copy blue */
416 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
417
418 /* Copy green */
419 iColor >>= 5;
420 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
421
422 /* Copy red */
423 iColor >>= 6;
424 iNewColor |= gajXlate5to8[iColor & 0x1F];
425
426 return iNewColor;
427}
428
429_Function_class_(FN_XLATE)
430ULONG
432EXLATEOBJ_iXlate565toBGR(PEXLATEOBJ pexlo, ULONG iColor)
433{
434 ULONG iNewColor;
435
436 /* Copy blue */
437 iNewColor = gajXlate5to8[iColor & 0x1F];
438
439 /* Copy green */
440 iColor >>= 5;
441 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
442
443 /* Copy blue */
444 iColor >>= 6;
445 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
446
447 return iNewColor;
448}
449
450_Function_class_(FN_XLATE)
451ULONG
453EXLATEOBJ_iXlate565toPal(EXLATEOBJ *pexlo, ULONG iColor)
454{
455 iColor = EXLATEOBJ_iXlate565toRGB(pexlo, iColor);
456
458}
459
460_Function_class_(FN_XLATE)
461ULONG
463EXLATEOBJ_iXlateShiftAndMask(PEXLATEOBJ pexlo, ULONG iColor)
464{
465 ULONG iNewColor;
466
467 iNewColor = _rotl(iColor, pexlo->ulRedShift) & pexlo->ulRedMask;
468 iNewColor |= _rotl(iColor, pexlo->ulGreenShift) & pexlo->ulGreenMask;
469 iNewColor |= _rotl(iColor, pexlo->ulBlueShift) & pexlo->ulBlueMask;
470
471 return iNewColor;
472}
473
474_Function_class_(FN_XLATE)
475ULONG
477EXLATEOBJ_iXlateBitfieldsToPal(PEXLATEOBJ pexlo, ULONG iColor)
478{
479 /* Convert bitfields to RGB */
480 iColor = EXLATEOBJ_iXlateShiftAndMask(pexlo, iColor);
481
482 /* Return nearest index */
484}
485
486
489VOID
490NTAPI
492 _Out_ PEXLATEOBJ pexlo,
493 _In_opt_ PALETTE *ppalSrc,
494 _In_opt_ PALETTE *ppalDst,
495 _In_ COLORREF crSrcBackColor,
496 _In_ COLORREF crDstBackColor,
497 _In_ COLORREF crDstForeColor)
498{
500 ULONG i, ulColor;
501
502 if (!ppalSrc) ppalSrc = &gpalRGB;
503 if (!ppalDst) ppalDst = &gpalRGB;
504
505 pexlo->xlo.iUniq = InterlockedIncrement((LONG*)&giUniqueXlate);
506 pexlo->xlo.cEntries = 0;
507 pexlo->xlo.flXlate = 0;
508 pexlo->xlo.pulXlate = pexlo->aulXlate;
509 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
510 pexlo->hColorTransform = NULL;
511 pexlo->ppalSrc = ppalSrc;
512 pexlo->ppalDst = ppalDst;
513 pexlo->xlo.iSrcType = (USHORT)ppalSrc->flFlags;
514 pexlo->xlo.iDstType = (USHORT)ppalDst->flFlags;
515 pexlo->ppalDstDc = &gpalRGB;
516
517 if (ppalDst == ppalSrc)
518 {
519 pexlo->xlo.flXlate |= XO_TRIVIAL;
520 return;
521 }
522
523 /* Check if both of the palettes are indexed */
524 if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED))
525 {
526 /* At least one palette is not indexed, calculate shifts/masks */
527 ULONG aulMasksSrc[3], aulMasksDst[3];
528
529 PALETTE_vGetBitMasks(ppalSrc, aulMasksSrc);
530 PALETTE_vGetBitMasks(ppalDst, aulMasksDst);
531
532 pexlo->ulRedMask = aulMasksDst[0];
533 pexlo->ulGreenMask = aulMasksDst[1];
534 pexlo->ulBlueMask = aulMasksDst[2];
535
536 pexlo->ulRedShift = CalculateShift(aulMasksSrc[0], aulMasksDst[0]);
537 pexlo->ulGreenShift = CalculateShift(aulMasksSrc[1], aulMasksDst[1]);
538 pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
539 }
540
541 if (ppalSrc->flFlags & PAL_MONOCHROME)
542 {
543 if (ppalDst->flFlags & PAL_MONOCHROME)
544 {
545 ULONG iColors[2];
546
547 /* Color mapping depends on whether the source or dest are DIBs */
548 if ((ppalSrc->flFlags & PAL_DIBSECTION) && !(ppalDst->flFlags & PAL_DIBSECTION))
549 {
550 /* DIB -> DDB: Use the source back color */
551 iColors[1] = PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
552 iColors[0] = iColors[1] ^ 1;
553 }
554 else if (!(ppalSrc->flFlags & PAL_DIBSECTION) && (ppalDst->flFlags & PAL_DIBSECTION))
555 {
556 /* DDB -> DIB: Use the dest DC's back and fore color (black -> fore, white -> back) */
557 ULONG iBlack = PALETTE_ulGetNearestPaletteIndex(ppalSrc, 0x000000);
558 ULONG iWhite = iBlack ^ 1;
559 iColors[iBlack] = PALETTE_ulGetNearestPaletteIndex(ppalDst, crDstForeColor);
560 iColors[iWhite] = PALETTE_ulGetNearestPaletteIndex(ppalDst, crDstBackColor);
561 }
562 else
563 {
564 /* Either both are DIBs or both are DDBs, fore/back colors are ignored */
565 ULONG rgbColor0 = PALETTE_ulGetRGBColorFromIndex(ppalSrc, 0);
566 ULONG rgbColor1 = PALETTE_ulGetRGBColorFromIndex(ppalSrc, 1);
567 iColors[0] = PALETTE_ulGetNearestPaletteIndex(ppalDst, rgbColor0);
568 iColors[1] = PALETTE_ulGetNearestPaletteIndex(ppalDst, rgbColor1);
569 }
570
571 /* Check for one of 4 cases: trivial, invert, to-0, to-1 */
572 if ((iColors[0] == 0) && (iColors[1] == 1))
573 {
574 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
575 pexlo->xlo.flXlate = XO_TRIVIAL;
576 }
577 else if ((iColors[0] == 1) && (iColors[1] == 0))
578 {
579 pexlo->pfnXlate = EXLATEOBJ_iXlateMonoInvert;
580 }
581 else if (iColors[0] == 0) // && (iColors[1] == 0)
582 {
583 pexlo->pfnXlate = EXLATEOBJ_iXlateMonoTo0;
584 }
585 else // if ((iColors[0] == 1) && (iColors[1] == 1))
586 {
587 pexlo->pfnXlate = EXLATEOBJ_iXlateMonoTo1;
588 }
589 }
590 else
591 {
592 /* Mono to color translation uses a 2-entry table */
593 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
594 pexlo->xlo.flXlate |= XO_TABLE;
595 pexlo->xlo.cEntries = 2;
596
597 /* Check if source is a DIB or direct translation was explicitly
598 requested by passing CLR_INALID as crDstBackColor */
599 if ((ppalSrc->flFlags & PAL_DIBSECTION) ||
600 (crDstBackColor == CLR_INVALID))
601 {
602 /* Direct translation, use the DIB color table */
603 ULONG rgbColor0 = PALETTE_ulGetRGBColorFromIndex(ppalSrc, 0);
604 ULONG rgbColor1 = PALETTE_ulGetRGBColorFromIndex(ppalSrc, 1);
605 pexlo->aulXlate[0] =
606 PALETTE_ulGetNearestIndex(ppalDst, rgbColor0);
607 pexlo->aulXlate[1] =
608 PALETTE_ulGetNearestIndex(ppalDst, rgbColor1);
609 }
610 else
611 {
612 /* Use the dest DCs back and fore color */
613 ULONG iBlack = PALETTE_ulGetNearestPaletteIndex(ppalSrc, 0x000000);
614 ULONG iWhite = iBlack ^ 1;
615 pexlo->xlo.pulXlate[iBlack] = PALETTE_ulGetNearestIndex(ppalDst, crDstForeColor);
616 pexlo->xlo.pulXlate[iWhite] = PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
617 }
618 }
619 }
620 else if (ppalDst->flFlags & PAL_MONOCHROME)
621 {
622 pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
623 pexlo->xlo.flXlate |= XO_TO_MONO;
624 pexlo->xlo.cEntries = 1;
625
626 if (ppalSrc->flFlags & PAL_INDEXED)
627 {
628 pexlo->aulXlate[0] =
629 PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
630 }
631 else if (ppalSrc->flFlags & PAL_RGB)
632 {
633 pexlo->aulXlate[0] = crSrcBackColor;
634
635 /* Check if direct translation was requested (e.g. NtGdiSetPixel) */
636 if (crSrcBackColor == CLR_INVALID)
637 {
641 FALSE);
642 }
643 }
644 else if (ppalSrc->flFlags & PAL_BGR)
645 {
646 pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
647 GetGValue(crSrcBackColor),
648 GetRValue(crSrcBackColor));
649
650 /* Check if direct translation was requested (e.g. NtGdiSetPixel) */
651 if (crSrcBackColor == CLR_INVALID)
652 {
656 TRUE);
657 }
658 }
659 else if (ppalSrc->flFlags & PAL_BITFIELDS)
660 {
661 PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
662 pexlo->ulRedShift = CalculateShift(RGB(0xFF,0,0), pexlo->ulRedMask);
663 pexlo->ulGreenShift = CalculateShift(RGB(0,0xFF,0), pexlo->ulGreenMask);
664 pexlo->ulBlueShift = CalculateShift(RGB(0,0,0xFF), pexlo->ulBlueMask);
665
666 pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
667 }
668 }
669 else if (ppalSrc->flFlags & PAL_INDEXED)
670 {
671 cEntries = ppalSrc->NumColors;
672
673 /* Allocate buffer if needed */
674 if (cEntries > 6)
675 {
676 pexlo->xlo.pulXlate = EngAllocMem(0,
677 cEntries * sizeof(ULONG),
679 if (!pexlo->xlo.pulXlate)
680 {
681 DPRINT1("Could not allocate pulXlate buffer.\n");
682 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
683 pexlo->xlo.flXlate = XO_TRIVIAL;
684 return;
685 }
686 }
687
688 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
689 pexlo->xlo.cEntries = cEntries;
690 pexlo->xlo.flXlate |= XO_TABLE;
691
692 if (ppalDst->flFlags & PAL_INDEXED)
693 {
694 ULONG cDiff = 0;
695
696 for (i = 0; i < cEntries; i++)
697 {
698 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
699 ppalSrc->IndexedColors[i].peGreen,
700 ppalSrc->IndexedColors[i].peBlue);
701
702 pexlo->xlo.pulXlate[i] =
703 PALETTE_ulGetNearestPaletteIndex(ppalDst, ulColor);
704
705 if (pexlo->xlo.pulXlate[i] != i) cDiff++;
706 }
707
708 /* Check if we have only trivial mappings */
709 if (cDiff == 0)
710 {
711 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
712 {
713 EngFreeMem(pexlo->xlo.pulXlate);
714 pexlo->xlo.pulXlate = pexlo->aulXlate;
715 }
716 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
717 pexlo->xlo.flXlate = XO_TRIVIAL;
718 pexlo->xlo.cEntries = 0;
719 return;
720 }
721 }
722 else
723 {
724 for (i = 0; i < pexlo->xlo.cEntries; i++)
725 {
726 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
727 ppalSrc->IndexedColors[i].peGreen,
728 ppalSrc->IndexedColors[i].peBlue);
729 pexlo->xlo.pulXlate[i] = PALETTE_ulGetNearestIndex(ppalDst, ulColor);
730 }
731 }
732 }
733 else if (ppalSrc->flFlags & PAL_RGB)
734 {
735 if (ppalDst->flFlags & PAL_INDEXED)
736 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
737
738 else if (ppalDst->flFlags & PAL_BGR)
739 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
740
741 else if (ppalDst->flFlags & PAL_RGB16_555)
742 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
743
744 else if (ppalDst->flFlags & PAL_RGB16_565)
745 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
746
747 else if (ppalDst->flFlags & PAL_BITFIELDS)
748 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
749 }
750 else if (ppalSrc->flFlags & PAL_BGR)
751 {
752 if (ppalDst->flFlags & PAL_INDEXED)
753 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
754
755 else if (ppalDst->flFlags & PAL_RGB)
756 /* The inverse function works the same */
757 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
758
759 else if (ppalDst->flFlags & PAL_RGB16_555)
760 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
761
762 else if (ppalDst->flFlags & PAL_RGB16_565)
763 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
764
765 else if (ppalDst->flFlags & PAL_BITFIELDS)
766 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
767 }
768 else if (ppalSrc->flFlags & PAL_RGB16_555)
769 {
770 if (ppalDst->flFlags & PAL_INDEXED)
771 pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
772
773 else if (ppalDst->flFlags & PAL_RGB)
774 pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
775
776 else if (ppalDst->flFlags & PAL_BGR)
777 pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
778
779 else if (ppalDst->flFlags & PAL_RGB16_565)
780 pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
781
782 else if (ppalDst->flFlags & PAL_BITFIELDS)
783 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
784 }
785 else if (ppalSrc->flFlags & PAL_RGB16_565)
786 {
787 if (ppalDst->flFlags & PAL_INDEXED)
788 pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
789
790 else if (ppalDst->flFlags & PAL_RGB)
791 pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
792
793 else if (ppalDst->flFlags & PAL_BGR)
794 pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
795
796 else if (ppalDst->flFlags & PAL_RGB16_555)
797 pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
798
799 else if (ppalDst->flFlags & PAL_BITFIELDS)
800 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
801 }
802 else if (ppalSrc->flFlags & PAL_BITFIELDS)
803 {
804 if (ppalDst->flFlags & PAL_INDEXED)
805 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
806 else
807 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
808 }
809
810 /* Check for a trivial shift and mask operation */
811 if (pexlo->pfnXlate == EXLATEOBJ_iXlateShiftAndMask &&
812 !pexlo->ulRedShift && !pexlo->ulGreenShift && !pexlo->ulBlueShift)
813 {
814 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
815 }
816
817 /* Check for trivial xlate */
818 if (pexlo->pfnXlate == EXLATEOBJ_iXlateTrivial)
819 pexlo->xlo.flXlate = XO_TRIVIAL;
820 else
821 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
822}
823
824VOID
825NTAPI
827 _Out_ EXLATEOBJ* pexlo,
828 _In_ PDC pdcSrc,
829 _In_ PDC pdcDst)
830{
831 PSURFACE psurfDst, psurfSrc;
832
833 psurfDst = pdcDst->dclevel.pSurface;
834 psurfSrc = pdcSrc->dclevel.pSurface;
835
836 /* Normal initialisation. No surface means DEFAULT_BITMAP */
838 psurfSrc ? psurfSrc->ppal : gppalMono,
839 psurfDst ? psurfDst->ppal : gppalMono,
840 pdcSrc->pdcattr->crBackgroundClr,
841 pdcDst->pdcattr->crBackgroundClr,
842 pdcDst->pdcattr->crForegroundClr);
843
844 pexlo->ppalDstDc = pdcDst->dclevel.ppal;
845}
846
847VOID
848NTAPI
850 _Out_ EXLATEOBJ* pexlo,
851 _In_ PDC pdcSrc,
852 _In_ PDC pdcDst,
853 _In_ COLORREF crBackColor)
854{
855 PSURFACE psurfDst, psurfSrc;
856
857 psurfDst = pdcDst->dclevel.pSurface;
858 psurfSrc = pdcSrc->dclevel.pSurface;
859
860 if (crBackColor == CLR_INVALID)
861 {
862 crBackColor = pdcSrc->pdcattr->crBackgroundClr;
863 }
864
865 /* Normal initialisation. No surface means DEFAULT_BITMAP */
867 psurfSrc ? psurfSrc->ppal : gppalMono,
868 psurfDst ? psurfDst->ppal : gppalMono,
869 crBackColor,
870 pdcDst->pdcattr->crBackgroundClr,
871 pdcDst->pdcattr->crForegroundClr);
872
873 pexlo->ppalDstDc = pdcDst->dclevel.ppal;
874}
875
876
878 PEXLATEOBJ pexlo,
879 PPALETTE ppalDst,
880 COLORREF crBackgroundClr,
881 COLORREF crForegroundClr)
882{
883 /* Normal initialisation, with mono palette as source */
885 gppalMono,
886 ppalDst,
887 0,
888 crBackgroundClr,
889 crForegroundClr);
890}
891
892VOID
893NTAPI
895 _Inout_ PEXLATEOBJ pexlo)
896{
897 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
898 {
899 EngFreeMem(pexlo->xlo.pulXlate);
900 }
901 pexlo->xlo.pulXlate = pexlo->aulXlate;
902}
903
906#undef XLATEOBJ_iXlate
907ULONG
908NTAPI
912{
913 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
914
915 if (!pxlo)
916 return iColor;
917
918 /* Call the iXlate function */
919 return pexlo->pfnXlate(pexlo, iColor);
920}
921
922ULONG
923NTAPI
926 _In_ ULONG iPal,
927 _In_ ULONG cPal,
928 _Out_cap_(cPal) ULONG *pPalOut)
929{
930 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
931 PPALETTE ppal;
932 ULONG i;
933
934 if (!pxlo)
935 {
936 return 0;
937 }
938
939 if (iPal > 5)
940 {
941 DPRINT1("XLATEOBJ_cGetPalette called with wrong iPal: %lu\n", iPal);
942 return 0;
943 }
944
945 /* Get the requested palette */
946 if (iPal == XO_DESTDCPALETTE)
947 {
948 ppal = pexlo->ppalDstDc;
949 }
950 else if (iPal == XO_SRCPALETTE || iPal == XO_SRCBITFIELDS)
951 {
952 ppal = pexlo->ppalSrc;
953 }
954 else
955 {
956 ppal = pexlo->ppalDst;
957 }
958
959 /* Verify palette type match */
960 if (!ppal ||
961 ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
962 && !(ppal->flFlags & PAL_INDEXED)) ||
963 ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
964 && !(ppal->flFlags & PAL_BITFIELDS)))
965 {
966 return 0;
967 }
968
969 if(!pPalOut)
970 {
971 return ppal->NumColors;
972 }
973
974 /* Copy the values into the buffer */
975 if (ppal->flFlags & PAL_INDEXED)
976 {
977 cPal = min(cPal, ppal->NumColors);
978 for (i = 0; i < cPal; i++)
979 {
980 pPalOut[i] = RGB(ppal->IndexedColors[i].peRed,
981 ppal->IndexedColors[i].peGreen,
982 ppal->IndexedColors[i].peBlue);
983 }
984 }
985 else
986 {
987 // FIXME: should use the above code
988 pPalOut[0] = ppal->RedMask;
989 pPalOut[1] = ppal->GreenMask;
990 pPalOut[2] = ppal->BlueMask;
991 }
992
993 return cPal;
994}
995
996HANDLE
997NTAPI
1000{
1001 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
1002 return pexlo->hColorTransform;
1003}
1004
1005PULONG
1006NTAPI
1009{
1010 if (pxlo->iSrcType == PAL_INDEXED)
1011 {
1012 return pxlo->pulXlate;
1013 }
1014
1015 return NULL;
1016}
1017
1018/* EOF */
#define InterlockedIncrement
Definition: armddk.h:53
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_ACRTIMP unsigned int __cdecl _rotl(unsigned int, int)
Definition: rot.c:43
#define RGB(r, g, b)
Definition: precomp.h:67
#define GetBValue(quad)
Definition: precomp.h:71
#define GetGValue(quad)
Definition: precomp.h:70
#define GetRValue(quad)
Definition: precomp.h:69
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean g
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_cap_(size)
Definition: ms_sal.h:852
#define _Inout_
Definition: no_sal2.h:162
#define _Post_satisfies_(e)
Definition: no_sal2.h:66
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Function_class_(n)
Definition: no_sal2.h:398
#define FASTCALL
Definition: nt_native.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define EngFreeMem
Definition: polytest.cpp:56
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
Definition: polytest.cpp:41
ULONG ulGreenShift
Definition: xlateobj.h:40
XLATEOBJ xlo
Definition: xlateobj.h:21
ULONG ulBlueMask
Definition: xlateobj.h:38
PPALETTE ppalDst
Definition: xlateobj.h:26
PPALETTE ppalSrc
Definition: xlateobj.h:25
ULONG ulGreenMask
Definition: xlateobj.h:37
ULONG ulBlueShift
Definition: xlateobj.h:41
ULONG ulRedMask
Definition: xlateobj.h:36
HANDLE hColorTransform
Definition: xlateobj.h:29
PFN_XLATE pfnXlate
Definition: xlateobj.h:23
PPALETTE ppalDstDc
Definition: xlateobj.h:27
ULONG ulRedShift
Definition: xlateobj.h:39
ULONG BlueMask
Definition: palette.h:45
ULONG GreenMask
Definition: palette.h:44
ULONG NumColors
Definition: palette.h:41
PALETTEENTRY * IndexedColors
Definition: palette.h:42
FLONG flFlags
Definition: palette.h:40
ULONG RedMask
Definition: palette.h:43
struct _PALETTE *const ppal
Definition: surface.h:11
ULONG * pulXlate
Definition: winddi.h:1260
ULONG cEntries
Definition: winddi.h:1259
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
PALETTE * gppalMono
Definition: palette.c:20
PALETTE gpalRGB
Definition: palette.c:20
ULONG NTAPI PALETTE_ulGetNearestIndex(PALETTE *ppal, ULONG ulColor)
Definition: palette.c:317
VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors)
Definition: palette.c:331
ULONG NTAPI PALETTE_ulGetNearestPaletteIndex(PALETTE *ppal, ULONG iColor)
Definition: palette.c:264
@ PAL_MONOCHROME
Definition: palette.h:22
@ PAL_RGB16_565
Definition: palette.h:28
@ PAL_RGB16_555
Definition: palette.h:27
@ PAL_DIBSECTION
Definition: palette.h:24
FORCEINLINE ULONG CalculateShift(ULONG ulMask1, ULONG ulMask2)
Definition: palette.h:130
FORCEINLINE ULONG PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex)
Definition: palette.h:142
#define GDITAG_PXLATE
Definition: tags.h:181
#define XO_SRCPALETTE
Definition: winddi.h:3151
#define PAL_RGB
Definition: winddi.h:1563
#define XO_TO_MONO
Definition: winddi.h:1249
#define PAL_BITFIELDS
Definition: winddi.h:1562
#define XO_TABLE
Definition: winddi.h:1248
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ * pxlo
Definition: winddi.h:3416
#define XO_DESTBITFIELDS
Definition: winddi.h:3155
#define PAL_BGR
Definition: winddi.h:1564
#define XO_TRIVIAL
Definition: winddi.h:1247
#define PAL_INDEXED
Definition: winddi.h:1561
#define XO_SRCBITFIELDS
Definition: winddi.h:3154
#define XO_DESTPALETTE
Definition: winddi.h:3152
#define XO_DESTDCPALETTE
Definition: winddi.h:3153
DWORD COLORREF
Definition: windef.h:100
#define CLR_INVALID
Definition: wingdi.h:883
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:4067
VOID NTAPI EXLATEOBJ_vInitialize(_Out_ PEXLATEOBJ pexlo, _In_opt_ PALETTE *ppalSrc, _In_opt_ PALETTE *ppalDst, _In_ COLORREF crSrcBackColor, _In_ COLORREF crDstBackColor, _In_ COLORREF crDstForeColor)
Definition: xlateobj.c:491
static const BYTE gajXlate5to8[32]
Definition: xlateobj.c:28
static VOID EXLATEOBJ_vInitRGBToMono(_Inout_ PEXLATEOBJ pexlo, _In_ ULONG rgbBack, _In_ ULONG rgbFore, _In_ BOOL bIsBGR)
Definition: xlateobj.c:144
VOID NTAPI EXLATEOBJ_vCleanup(_Inout_ PEXLATEOBJ pexlo)
Definition: xlateobj.c:894
static const BYTE gajXlate6to8[64]
Definition: xlateobj.c:32
VOID NTAPI EXLATEOBJ_vInitXlateFromDCsEx(_Out_ EXLATEOBJ *pexlo, _In_ PDC pdcSrc, _In_ PDC pdcDst, _In_ COLORREF crBackColor)
Definition: xlateobj.c:849
ULONG NTAPI XLATEOBJ_cGetPalette(_In_ XLATEOBJ *pxlo, _In_ ULONG iPal, _In_ ULONG cPal, _Out_cap_(cPal) ULONG *pPalOut)
Definition: xlateobj.c:924
VOID NTAPI EXLATEOBJ_vInitXlateFromDCs(_Out_ EXLATEOBJ *pexlo, _In_ PDC pdcSrc, _In_ PDC pdcDst)
Definition: xlateobj.c:826
ULONG NTAPI XLATEOBJ_iXlate(_In_ XLATEOBJ *pxlo, _In_ ULONG iColor)
Definition: xlateobj.c:909
PULONG NTAPI XLATEOBJ_piVector(_In_ XLATEOBJ *pxlo)
Definition: xlateobj.c:1007
HANDLE NTAPI XLATEOBJ_hGetColorTransform(_In_ XLATEOBJ *pxlo)
Definition: xlateobj.c:998
VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(PEXLATEOBJ pexlo, PPALETTE ppalDst, COLORREF crBackgroundClr, COLORREF crForegroundClr)
Definition: xlateobj.c:877
static ULONG giUniqueXlate
Definition: xlateobj.c:26
_In_ ULONG iColor
Definition: xlateobj.h:17
EXLATEOBJ gexloTrivial
struct _EXLATEOBJ * PEXLATEOBJ
unsigned char BYTE
Definition: xxhash.c:193