[CMAKE]
[reactos.git] / subsystems / win32 / win32k / eng / xlate.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Color Translation Functions
5 * FILE: subsystems/win32/win32k/eng/xlate.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 #include <win32k.h>
10
11 #include <intrin.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /** Globals *******************************************************************/
18
19 ULONG giUniqueXlate = 0;
20 EXLATEOBJ gexloTrivial;
21 XLATEOBJ* gpxloTrivial = &gexloTrivial.xlo;
22
23 const BYTE gajXlate5to8[32] =
24 { 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99,107,115,123,
25 132,140,148,156,165,173,181,189,197,206,214,222,231,239,247,255};
26
27 const BYTE gajXlate6to8[64] =
28 { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 52, 57, 61,
29 65, 69, 73, 77, 81, 85, 89, 93, 97,101,105,109,113,117,121,125,
30 130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,
31 194,198,202,207,210,215,219,223,227,231,235,239,243,247,251,255};
32
33
34 /** iXlate functions **********************************************************/
35
36 ULONG
37 FASTCALL
38 EXLATEOBJ_iXlateTrivial(PEXLATEOBJ pexlo, ULONG iColor)
39 {
40 return iColor;
41 }
42
43 ULONG
44 FASTCALL
45 EXLATEOBJ_iXlateToMono(PEXLATEOBJ pexlo, ULONG iColor)
46 {
47 return (iColor == pexlo->xlo.pulXlate[0]);
48 }
49
50 ULONG
51 FASTCALL
52 EXLATEOBJ_iXlateTable(PEXLATEOBJ pexlo, ULONG iColor)
53 {
54 if (iColor >= pexlo->xlo.cEntries)
55 {
56 iColor %= pexlo->xlo.cEntries;
57 }
58 return pexlo->xlo.pulXlate[iColor];
59 }
60
61 ULONG
62 FASTCALL
63 EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor)
64 {
65 ULONG iNewColor;
66
67 /* Copy green */
68 iNewColor = iColor & 0xff00ff00;
69
70 /* Mask red and blue */
71 iColor &= 0x00ff00ff;
72
73 /* Shift and copy red and blue */
74 iNewColor |= iColor >> 16;
75 iNewColor |= iColor << 16;
76
77 return iNewColor;
78 }
79
80 ULONG
81 FASTCALL
82 EXLATEOBJ_iXlateRGBto555(PEXLATEOBJ pxlo, ULONG iColor)
83 {
84 ULONG iNewColor;
85
86 /* Copy red */
87 iColor <<= 7;
88 iNewColor = iColor & 0x7C00;
89
90 /* Copy green */
91 iColor >>= 13;
92 iNewColor |= iColor & 0x3E0;
93
94 /* Copy green */
95 iColor >>= 13;
96 iNewColor |= iColor & 0x1F;
97
98 return iNewColor;
99 }
100
101 ULONG
102 FASTCALL
103 EXLATEOBJ_iXlateBGRto555(PEXLATEOBJ pxlo, ULONG iColor)
104 {
105 ULONG iNewColor;
106
107 /* Copy blue */
108 iColor >>= 3;
109 iNewColor = iColor & 0x1f;
110
111 /* Copy green */
112 iColor >>= 3;
113 iNewColor |= (iColor & 0x3E0);
114
115 /* Copy red */
116 iColor >>= 3;
117 iNewColor |= (iColor & 0x7C00);
118
119 return iNewColor;
120 }
121
122 ULONG
123 FASTCALL
124 EXLATEOBJ_iXlateRGBto565(PEXLATEOBJ pxlo, ULONG iColor)
125 {
126 ULONG iNewColor;
127
128 /* Copy red */
129 iColor <<= 8;
130 iNewColor = iColor & 0xF800;
131
132 /* Copy green */
133 iColor >>= 13;
134 iNewColor |= iColor & 0x7E0;
135
136 /* Copy green */
137 iColor >>= 14;
138 iNewColor |= iColor & 0x1F;
139
140 return iNewColor;
141 }
142
143 ULONG
144 FASTCALL
145 EXLATEOBJ_iXlateBGRto565(PEXLATEOBJ pxlo, ULONG iColor)
146 {
147 ULONG iNewColor;
148
149 /* Copy blue */
150 iColor >>= 3;
151 iNewColor = iColor & 0x1f;
152
153 /* Copy green */
154 iColor >>= 2;
155 iNewColor |= (iColor & 0x7E0);
156
157 /* Copy red */
158 iColor >>= 3;
159 iNewColor |= (iColor & 0xF800);
160
161 return iNewColor;
162 }
163
164 ULONG
165 FASTCALL
166 EXLATEOBJ_iXlateRGBtoPal(PEXLATEOBJ pexlo, ULONG iColor)
167 {
168 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
169 }
170
171 ULONG
172 FASTCALL
173 EXLATEOBJ_iXlate555toRGB(PEXLATEOBJ pxlo, ULONG iColor)
174 {
175 ULONG iNewColor;
176
177 /* Copy blue */
178 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
179
180 /* Copy green */
181 iColor >>= 5;
182 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
183
184 /* Copy red */
185 iColor >>= 5;
186 iNewColor |= gajXlate5to8[iColor & 0x1F];
187
188 return iNewColor;
189 }
190
191 ULONG
192 FASTCALL
193 EXLATEOBJ_iXlate555toBGR(PEXLATEOBJ pxlo, ULONG iColor)
194 {
195 ULONG iNewColor;
196
197 /* Copy blue */
198 iNewColor = gajXlate5to8[iColor & 0x1F];
199
200 /* Copy green */
201 iColor >>= 5;
202 iNewColor |= gajXlate5to8[iColor & 0x1F] << 8;
203
204 /* Copy red */
205 iColor >>= 5;
206 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
207
208 return iNewColor;
209 }
210
211 ULONG
212 FASTCALL
213 EXLATEOBJ_iXlate555to565(PEXLATEOBJ pxlo, ULONG iColor)
214 {
215 ULONG iNewColor;
216
217 /* Copy blue */
218 iNewColor = iColor & 0x1f;
219
220 /* Copy red and green */
221 iColor <<= 1;
222 iNewColor |= iColor & 0xFFC0;
223
224 /* Duplicate highest green bit */
225 iColor >>= 5;
226 iNewColor |= (iColor & 0x20);
227
228 return iNewColor;
229 }
230
231 ULONG
232 FASTCALL
233 EXLATEOBJ_iXlate555toPal(PEXLATEOBJ pexlo, ULONG iColor)
234 {
235 iColor = EXLATEOBJ_iXlate555toRGB(pexlo, iColor);
236
237 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
238 }
239
240 ULONG
241 FASTCALL
242 EXLATEOBJ_iXlate565to555(PEXLATEOBJ pxlo, ULONG iColor)
243 {
244 ULONG iNewColor;
245
246 /* Copy blue */
247 iNewColor = iColor & 0x1f;
248
249 /* Copy red and green */
250 iColor >>= 1;
251 iNewColor |= iColor & 0x7FE0;
252
253 return iNewColor;
254 }
255
256 ULONG
257 FASTCALL
258 EXLATEOBJ_iXlate565toRGB(PEXLATEOBJ pexlo, ULONG iColor)
259 {
260 ULONG iNewColor;
261
262 /* Copy blue */
263 iNewColor = gajXlate5to8[iColor & 0x1F] << 16;
264
265 /* Copy green */
266 iColor >>= 5;
267 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
268
269 /* Copy red */
270 iColor >>= 6;
271 iNewColor |= gajXlate5to8[iColor & 0x1F];
272
273 return iNewColor;
274 }
275
276 ULONG
277 FASTCALL
278 EXLATEOBJ_iXlate565toBGR(PEXLATEOBJ pexlo, ULONG iColor)
279 {
280 ULONG iNewColor;
281
282 /* Copy blue */
283 iNewColor = gajXlate5to8[iColor & 0x1F];
284
285 /* Copy green */
286 iColor >>= 5;
287 iNewColor |= gajXlate6to8[iColor & 0x3F] << 8;
288
289 /* Copy blue */
290 iColor >>= 6;
291 iNewColor |= gajXlate5to8[iColor & 0x1F] << 16;
292
293 return iNewColor;
294 }
295
296 ULONG
297 FASTCALL
298 EXLATEOBJ_iXlate565toPal(EXLATEOBJ *pexlo, ULONG iColor)
299 {
300 iColor = EXLATEOBJ_iXlate565toRGB(pexlo, iColor);
301
302 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
303 }
304
305 ULONG
306 FASTCALL
307 EXLATEOBJ_iXlateShiftAndMask(PEXLATEOBJ pexlo, ULONG iColor)
308 {
309 ULONG iNewColor;
310
311 iNewColor = _rotl(iColor, pexlo->ulRedShift) & pexlo->ulRedMask;
312 iNewColor |= _rotl(iColor, pexlo->ulGreenShift) & pexlo->ulGreenMask;
313 iNewColor |= _rotl(iColor, pexlo->ulBlueShift) & pexlo->ulBlueMask;
314
315 return iNewColor;
316 }
317
318 ULONG
319 FASTCALL
320 EXLATEOBJ_iXlateBitfieldsToPal(PEXLATEOBJ pexlo, ULONG iColor)
321 {
322 /* Convert bitfields to RGB */
323 iColor = EXLATEOBJ_iXlateShiftAndMask(pexlo, iColor);
324
325 /* Return nearest index */
326 return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor);
327 }
328
329
330 /** Private Functions *********************************************************/
331
332 VOID
333 NTAPI
334 EXLATEOBJ_vInitTrivial(PEXLATEOBJ pexlo)
335 {
336 pexlo->xlo.iUniq = InterlockedIncrement((LONG*)&giUniqueXlate);
337 pexlo->xlo.flXlate = XO_TRIVIAL;
338 pexlo->xlo.iSrcType = PAL_RGB;
339 pexlo->xlo.iDstType = PAL_RGB;
340 pexlo->xlo.cEntries = 0;
341 pexlo->xlo.pulXlate = pexlo->aulXlate;
342 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
343 pexlo->ppalSrc = &gpalRGB;
344 pexlo->ppalDst = &gpalRGB;
345 pexlo->ppalDstDc = &gpalRGB;
346 pexlo->hColorTransform = NULL;
347 }
348
349 VOID
350 NTAPI
351 EXLATEOBJ_vInitialize(
352 PEXLATEOBJ pexlo,
353 PALETTE *ppalSrc,
354 PALETTE *ppalDst,
355 COLORREF crSrcBackColor,
356 COLORREF crDstBackColor,
357 COLORREF crDstForeColor)
358 {
359 ULONG cEntries;
360 ULONG i, ulColor;
361
362 EXLATEOBJ_vInitTrivial(pexlo);
363
364 if (ppalDst == ppalSrc || !ppalSrc || !ppalDst ||
365 ((ppalDst->flFlags == PAL_RGB || ppalDst->flFlags == PAL_BGR) &&
366 ppalDst->flFlags == ppalSrc->flFlags))
367 {
368 return;
369 }
370
371 pexlo->ppalSrc = ppalSrc;
372 pexlo->ppalDst = ppalDst;
373 pexlo->xlo.iSrcType = ppalSrc->flFlags;
374 pexlo->xlo.iDstType = ppalDst->flFlags;
375
376 /* Chack if both of the pallettes are indexed */
377 if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED))
378 {
379 /* At least one palette is not indexed, calculate shifts/masks */
380 ULONG aulMasksSrc[3], aulMasksDst[3];
381
382 PALETTE_vGetBitMasks(ppalSrc, aulMasksSrc);
383 PALETTE_vGetBitMasks(ppalDst, aulMasksDst);
384
385 pexlo->ulRedMask = aulMasksDst[0];
386 pexlo->ulGreenMask = aulMasksDst[1];
387 pexlo->ulBlueMask = aulMasksDst[2];
388
389 pexlo->ulRedShift = CalculateShift(aulMasksSrc[0], aulMasksDst[0]);
390 pexlo->ulGreenShift = CalculateShift(aulMasksSrc[1], aulMasksDst[1]);
391 pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
392 }
393
394 if (ppalSrc->flFlags & PAL_MONOCHROME)
395 {
396 /* This is a monochrome palette */
397 if (!(ppalDst->flFlags & PAL_MONOCHROME))
398 {
399 /* Mono to color, use the dest DC's fore and back color */
400 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
401 pexlo->xlo.flXlate |= XO_TABLE;
402 pexlo->xlo.cEntries = 2;
403 pexlo->xlo.pulXlate[0] =
404 PALETTE_ulGetNearestIndex(ppalDst, crDstForeColor);
405 pexlo->xlo.pulXlate[1] =
406 PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
407 }
408 }
409 else if (ppalDst->flFlags & PAL_MONOCHROME)
410 {
411 pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
412 pexlo->xlo.flXlate |= XO_TO_MONO;
413 pexlo->xlo.cEntries = 1;
414
415 if (ppalSrc->flFlags & PAL_INDEXED)
416 {
417 pexlo->aulXlate[0] =
418 PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
419 }
420 else if (ppalSrc->flFlags & PAL_BGR)
421 {
422 pexlo->aulXlate[0] = crSrcBackColor;
423 }
424 else if (ppalSrc->flFlags & PAL_RGB)
425 {
426 pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
427 GetGValue(crSrcBackColor),
428 GetRValue(crSrcBackColor));
429 }
430 else if (ppalSrc->flFlags & PAL_BITFIELDS)
431 {
432 PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
433 pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask);
434 pexlo->ulGreenShift = CalculateShift(0xFF00, pexlo->ulGreenMask);
435 pexlo->ulBlueShift = CalculateShift(0xFF0000, pexlo->ulBlueMask);
436
437 pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
438 }
439 }
440 else if (ppalSrc->flFlags & PAL_INDEXED)
441 {
442 cEntries = ppalSrc->NumColors;
443
444 /* Allocate buffer if needed */
445 if (cEntries > 6)
446 {
447 pexlo->xlo.pulXlate = EngAllocMem(0,
448 cEntries * sizeof(ULONG),
449 TAG_XLATEOBJ);
450 if (!pexlo->xlo.pulXlate)
451 {
452 DPRINT1("Could not allocate pulXlate buffer.\n");
453 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
454 pexlo->xlo.flXlate = XO_TRIVIAL;
455 return;
456 }
457 }
458 pexlo->xlo.cEntries = cEntries;
459
460 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
461 if (ppalDst->flFlags & PAL_INDEXED)
462 {
463 pexlo->xlo.flXlate |= XO_TABLE;
464
465 for (i = 0; i < cEntries; i++)
466 {
467 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
468 ppalSrc->IndexedColors[i].peGreen,
469 ppalSrc->IndexedColors[i].peBlue);
470
471 pexlo->xlo.pulXlate[i] =
472 PALETTE_ulGetNearestPaletteIndex(ppalDst, ulColor);
473
474 if (pexlo->xlo.pulXlate[i] != i)
475 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
476 }
477
478 if (pexlo->xlo.flXlate & XO_TRIVIAL)
479 {
480 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
481 {
482 EngFreeMem(pexlo->xlo.pulXlate);
483 pexlo->xlo.pulXlate = pexlo->aulXlate;
484 }
485 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
486 pexlo->xlo.flXlate = XO_TRIVIAL;
487 return;
488 }
489 }
490 else
491 {
492 // FIXME: use PALETTE_ulGetNearest
493 EXLATEOBJ exloTmp = *pexlo;
494 exloTmp.xlo.pulXlate = exloTmp.aulXlate;
495
496 pexlo->xlo.flXlate |= XO_TABLE;
497 for (i = 0; i < pexlo->xlo.cEntries; i++)
498 {
499 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
500 ppalSrc->IndexedColors[i].peGreen,
501 ppalSrc->IndexedColors[i].peBlue);
502 pexlo->xlo.pulXlate[i] =
503 EXLATEOBJ_iXlateShiftAndMask(&exloTmp, ulColor);
504 }
505 }
506 }
507 else if (ppalSrc->flFlags & PAL_RGB)
508 {
509 if (ppalDst->flFlags & PAL_INDEXED)
510 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
511
512 else if (ppalDst->flFlags & PAL_BGR)
513 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
514
515 else if (ppalDst->flFlags & PAL_RGB16_555)
516 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
517
518 else if (ppalDst->flFlags & PAL_RGB16_565)
519 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
520
521 else if (ppalDst->flFlags & PAL_BITFIELDS)
522 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
523 }
524 else if (ppalSrc->flFlags & PAL_BGR)
525 {
526 if (ppalDst->flFlags & PAL_INDEXED)
527 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
528
529 else if (ppalDst->flFlags & PAL_RGB)
530 /* The inverse function works the same */
531 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
532
533 else if (ppalDst->flFlags & PAL_RGB16_555)
534 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
535
536 else if (ppalDst->flFlags & PAL_RGB16_565)
537 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
538
539 else if (ppalDst->flFlags & PAL_BITFIELDS)
540 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
541 }
542 else if (ppalSrc->flFlags & PAL_RGB16_555)
543 {
544 if (ppalDst->flFlags & PAL_INDEXED)
545 pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
546
547 else if (ppalDst->flFlags & PAL_RGB)
548 pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
549
550 else if (ppalDst->flFlags & PAL_BGR)
551 pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
552
553 else if (ppalDst->flFlags & PAL_RGB16_565)
554 pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
555
556 else if (ppalDst->flFlags & PAL_BITFIELDS)
557 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
558 }
559 else if (ppalSrc->flFlags & PAL_RGB16_565)
560 {
561 if (ppalDst->flFlags & PAL_INDEXED)
562 pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
563
564 else if (ppalDst->flFlags & PAL_RGB)
565 pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
566
567 else if (ppalDst->flFlags & PAL_BGR)
568 pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
569
570 else if (ppalDst->flFlags & PAL_RGB16_555)
571 pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
572
573 else if (ppalDst->flFlags & PAL_BITFIELDS)
574 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
575 }
576 else if (ppalSrc->flFlags & PAL_BITFIELDS)
577 {
578 if (ppalDst->flFlags & PAL_INDEXED)
579 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
580 else
581 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
582 }
583
584 /* Check for a trivial shift and mask operation */
585 if (pexlo->pfnXlate == EXLATEOBJ_iXlateShiftAndMask &&
586 !pexlo->ulRedShift && !pexlo->ulGreenShift && !pexlo->ulBlueShift)
587 {
588 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
589 }
590
591 /* Check for trivial xlate */
592 if (pexlo->pfnXlate == EXLATEOBJ_iXlateTrivial)
593 pexlo->xlo.flXlate = XO_TRIVIAL;
594 else
595 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
596 }
597
598 VOID
599 NTAPI
600 EXLATEOBJ_vInitXlateFromDCs(
601 EXLATEOBJ* pexlo,
602 PDC pdcSrc,
603 PDC pdcDst)
604 {
605 PSURFACE psurfDst, psurfSrc;
606
607 psurfDst = pdcDst->dclevel.pSurface;
608 psurfSrc = pdcSrc->dclevel.pSurface;
609
610 /* Check for trivial color translation */
611 if (psurfDst == psurfSrc)
612 {
613 EXLATEOBJ_vInitTrivial(pexlo);
614 return;
615 }
616
617 /* Normal initialisation. No surface means DEFAULT_BITMAP */
618 EXLATEOBJ_vInitialize(pexlo,
619 psurfSrc ? psurfSrc->ppal : &gpalMono,
620 psurfDst ? psurfDst->ppal : &gpalMono,
621 pdcSrc->pdcattr->crBackgroundClr,
622 pdcDst->pdcattr->crBackgroundClr,
623 pdcDst->pdcattr->crForegroundClr);
624 }
625
626 VOID
627 NTAPI
628 EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)
629 {
630 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
631 {
632 EngFreeMem(pexlo->xlo.pulXlate);
633 }
634 pexlo->xlo.pulXlate = pexlo->aulXlate;
635 }
636
637 INIT_FUNCTION
638 NTSTATUS
639 NTAPI
640 InitXlateImpl(VOID)
641 {
642 EXLATEOBJ_vInitTrivial(&gexloTrivial);
643 return STATUS_SUCCESS;
644 }
645
646
647 /** Public DDI Functions ******************************************************/
648
649 #undef XLATEOBJ_iXlate
650 ULONG
651 NTAPI
652 XLATEOBJ_iXlate(XLATEOBJ *pxlo, ULONG iColor)
653 {
654 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
655
656 if (!pxlo)
657 return iColor;
658
659 /* Call the iXlate function */
660 return pexlo->pfnXlate(pexlo, iColor);
661 }
662
663 ULONG
664 NTAPI
665 XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
666 {
667 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
668 PPALETTE ppal;
669 INT i;
670
671 if (!pxlo)
672 {
673 return 0;
674 }
675
676 if (iPal > 5)
677 {
678 DPRINT1("XLATEOBJ_cGetPalette called with wrong iPal: %d\n", iPal);
679 return 0;
680 }
681
682 /* Get the requested palette */
683 if (iPal == XO_DESTDCPALETTE)
684 {
685 ppal = pexlo->ppalDstDc;
686 }
687 else if (iPal == XO_SRCPALETTE || iPal == XO_SRCBITFIELDS)
688 {
689 ppal = pexlo->ppalSrc;
690 }
691 else
692 {
693 ppal = pexlo->ppalDst;
694 }
695
696 /* Verify palette type match */
697 if (!ppal ||
698 ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
699 && !(ppal->flFlags & PAL_INDEXED)) ||
700 ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
701 && !(ppal->flFlags & PAL_BITFIELDS)))
702 {
703 return 0;
704 }
705
706 if(!pPalOut)
707 {
708 return ppal->NumColors;
709 }
710
711 /* Copy the values into the buffer */
712 if (ppal->flFlags & PAL_INDEXED)
713 {
714 cPal = min(cPal, ppal->NumColors);
715 for (i = 0; i < cPal; i++)
716 {
717 pPalOut[i] = RGB(ppal->IndexedColors[i].peRed,
718 ppal->IndexedColors[i].peGreen,
719 ppal->IndexedColors[i].peBlue);
720 }
721 }
722 else
723 {
724 // FIXME: should use the above code
725 pPalOut[0] = ppal->RedMask;
726 pPalOut[1] = ppal->GreenMask;
727 pPalOut[2] = ppal->BlueMask;
728 }
729
730 return cPal;
731 }
732
733 HANDLE
734 NTAPI
735 XLATEOBJ_hGetColorTransform(XLATEOBJ *pxlo)
736 {
737 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
738 return pexlo->hColorTransform;
739 }
740
741 PULONG
742 NTAPI
743 XLATEOBJ_piVector(XLATEOBJ *pxlo)
744 {
745 if (pxlo->iSrcType == PAL_INDEXED)
746 {
747 return pxlo->pulXlate;
748 }
749
750 return NULL;
751 }
752
753 /* EOF */