[WIN32K]
[reactos.git] / reactos / 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 blue */
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 (!ppalSrc || !ppalDst)
365 {
366 return;
367 }
368
369 pexlo->ppalSrc = ppalSrc;
370 pexlo->ppalDst = ppalDst;
371 pexlo->xlo.iSrcType = ppalSrc->flFlags;
372 pexlo->xlo.iDstType = ppalDst->flFlags;
373
374 if (ppalDst == ppalSrc ||
375 ((ppalDst->flFlags == PAL_RGB || ppalDst->flFlags == PAL_BGR) &&
376 ppalDst->flFlags == ppalSrc->flFlags))
377 {
378 return;
379 }
380
381 /* Chack if both of the pallettes are indexed */
382 if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED))
383 {
384 /* At least one palette is not indexed, calculate shifts/masks */
385 ULONG aulMasksSrc[3], aulMasksDst[3];
386
387 PALETTE_vGetBitMasks(ppalSrc, aulMasksSrc);
388 PALETTE_vGetBitMasks(ppalDst, aulMasksDst);
389
390 pexlo->ulRedMask = aulMasksDst[0];
391 pexlo->ulGreenMask = aulMasksDst[1];
392 pexlo->ulBlueMask = aulMasksDst[2];
393
394 pexlo->ulRedShift = CalculateShift(aulMasksSrc[0], aulMasksDst[0]);
395 pexlo->ulGreenShift = CalculateShift(aulMasksSrc[1], aulMasksDst[1]);
396 pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
397 }
398
399 if (ppalSrc->flFlags & PAL_MONOCHROME)
400 {
401 /* This is a monochrome palette */
402 if (!(ppalDst->flFlags & PAL_MONOCHROME))
403 {
404 /* Mono to color, use the dest DC's fore and back color */
405 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
406 pexlo->xlo.flXlate |= XO_TABLE;
407 pexlo->xlo.cEntries = 2;
408 pexlo->xlo.pulXlate[0] =
409 PALETTE_ulGetNearestIndex(ppalDst, crDstForeColor);
410 pexlo->xlo.pulXlate[1] =
411 PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
412 }
413 }
414 else if (ppalDst->flFlags & PAL_MONOCHROME)
415 {
416 pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
417 pexlo->xlo.flXlate |= XO_TO_MONO;
418 pexlo->xlo.cEntries = 1;
419
420 if (ppalSrc->flFlags & PAL_INDEXED)
421 {
422 pexlo->aulXlate[0] =
423 PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
424 }
425 else if (ppalSrc->flFlags & PAL_RGB)
426 {
427 pexlo->aulXlate[0] = crSrcBackColor;
428 }
429 else if (ppalSrc->flFlags & PAL_BGR)
430 {
431 pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
432 GetGValue(crSrcBackColor),
433 GetRValue(crSrcBackColor));
434 }
435 else if (ppalSrc->flFlags & PAL_BITFIELDS)
436 {
437 PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
438 pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask);
439 pexlo->ulGreenShift = CalculateShift(0xFF00, pexlo->ulGreenMask);
440 pexlo->ulBlueShift = CalculateShift(0xFF0000, pexlo->ulBlueMask);
441
442 pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
443 }
444 }
445 else if (ppalSrc->flFlags & PAL_INDEXED)
446 {
447 cEntries = ppalSrc->NumColors;
448
449 /* Allocate buffer if needed */
450 if (cEntries > 6)
451 {
452 pexlo->xlo.pulXlate = EngAllocMem(0,
453 cEntries * sizeof(ULONG),
454 GDITAG_PXLATE);
455 if (!pexlo->xlo.pulXlate)
456 {
457 DPRINT1("Could not allocate pulXlate buffer.\n");
458 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
459 pexlo->xlo.flXlate = XO_TRIVIAL;
460 return;
461 }
462 }
463 pexlo->xlo.cEntries = cEntries;
464
465 pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
466 if (ppalDst->flFlags & PAL_INDEXED)
467 {
468 pexlo->xlo.flXlate |= XO_TABLE;
469
470 for (i = 0; i < cEntries; i++)
471 {
472 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
473 ppalSrc->IndexedColors[i].peGreen,
474 ppalSrc->IndexedColors[i].peBlue);
475
476 pexlo->xlo.pulXlate[i] =
477 PALETTE_ulGetNearestPaletteIndex(ppalDst, ulColor);
478
479 if (pexlo->xlo.pulXlate[i] != i)
480 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
481 }
482
483 if (pexlo->xlo.flXlate & XO_TRIVIAL)
484 {
485 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
486 {
487 EngFreeMem(pexlo->xlo.pulXlate);
488 pexlo->xlo.pulXlate = pexlo->aulXlate;
489 }
490 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
491 pexlo->xlo.flXlate = XO_TRIVIAL;
492 return;
493 }
494 }
495 else
496 {
497 // FIXME: use PALETTE_ulGetNearest
498 EXLATEOBJ exloTmp = *pexlo;
499 exloTmp.xlo.pulXlate = exloTmp.aulXlate;
500
501 pexlo->xlo.flXlate |= XO_TABLE;
502 for (i = 0; i < pexlo->xlo.cEntries; i++)
503 {
504 ulColor = RGB(ppalSrc->IndexedColors[i].peRed,
505 ppalSrc->IndexedColors[i].peGreen,
506 ppalSrc->IndexedColors[i].peBlue);
507 pexlo->xlo.pulXlate[i] =
508 EXLATEOBJ_iXlateShiftAndMask(&exloTmp, ulColor);
509 }
510 }
511 }
512 else if (ppalSrc->flFlags & PAL_RGB)
513 {
514 if (ppalDst->flFlags & PAL_INDEXED)
515 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
516
517 else if (ppalDst->flFlags & PAL_BGR)
518 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
519
520 else if (ppalDst->flFlags & PAL_RGB16_555)
521 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
522
523 else if (ppalDst->flFlags & PAL_RGB16_565)
524 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
525
526 else if (ppalDst->flFlags & PAL_BITFIELDS)
527 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
528 }
529 else if (ppalSrc->flFlags & PAL_BGR)
530 {
531 if (ppalDst->flFlags & PAL_INDEXED)
532 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
533
534 else if (ppalDst->flFlags & PAL_RGB)
535 /* The inverse function works the same */
536 pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
537
538 else if (ppalDst->flFlags & PAL_RGB16_555)
539 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
540
541 else if (ppalDst->flFlags & PAL_RGB16_565)
542 pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
543
544 else if (ppalDst->flFlags & PAL_BITFIELDS)
545 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
546 }
547 else if (ppalSrc->flFlags & PAL_RGB16_555)
548 {
549 if (ppalDst->flFlags & PAL_INDEXED)
550 pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
551
552 else if (ppalDst->flFlags & PAL_RGB)
553 pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
554
555 else if (ppalDst->flFlags & PAL_BGR)
556 pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
557
558 else if (ppalDst->flFlags & PAL_RGB16_565)
559 pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
560
561 else if (ppalDst->flFlags & PAL_BITFIELDS)
562 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
563 }
564 else if (ppalSrc->flFlags & PAL_RGB16_565)
565 {
566 if (ppalDst->flFlags & PAL_INDEXED)
567 pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
568
569 else if (ppalDst->flFlags & PAL_RGB)
570 pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
571
572 else if (ppalDst->flFlags & PAL_BGR)
573 pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
574
575 else if (ppalDst->flFlags & PAL_RGB16_555)
576 pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
577
578 else if (ppalDst->flFlags & PAL_BITFIELDS)
579 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
580 }
581 else if (ppalSrc->flFlags & PAL_BITFIELDS)
582 {
583 if (ppalDst->flFlags & PAL_INDEXED)
584 pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
585 else
586 pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
587 }
588
589 /* Check for a trivial shift and mask operation */
590 if (pexlo->pfnXlate == EXLATEOBJ_iXlateShiftAndMask &&
591 !pexlo->ulRedShift && !pexlo->ulGreenShift && !pexlo->ulBlueShift)
592 {
593 pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial;
594 }
595
596 /* Check for trivial xlate */
597 if (pexlo->pfnXlate == EXLATEOBJ_iXlateTrivial)
598 pexlo->xlo.flXlate = XO_TRIVIAL;
599 else
600 pexlo->xlo.flXlate &= ~XO_TRIVIAL;
601 }
602
603 VOID
604 NTAPI
605 EXLATEOBJ_vInitXlateFromDCs(
606 EXLATEOBJ* pexlo,
607 PDC pdcSrc,
608 PDC pdcDst)
609 {
610 PSURFACE psurfDst, psurfSrc;
611
612 psurfDst = pdcDst->dclevel.pSurface;
613 psurfSrc = pdcSrc->dclevel.pSurface;
614
615 /* Normal initialisation. No surface means DEFAULT_BITMAP */
616 EXLATEOBJ_vInitialize(pexlo,
617 psurfSrc ? psurfSrc->ppal : &gpalMono,
618 psurfDst ? psurfDst->ppal : &gpalMono,
619 pdcSrc->pdcattr->crBackgroundClr,
620 pdcDst->pdcattr->crBackgroundClr,
621 pdcDst->pdcattr->crForegroundClr);
622 }
623
624 VOID
625 NTAPI
626 EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)
627 {
628 if (pexlo->xlo.pulXlate != pexlo->aulXlate)
629 {
630 EngFreeMem(pexlo->xlo.pulXlate);
631 }
632 pexlo->xlo.pulXlate = pexlo->aulXlate;
633 }
634
635 INIT_FUNCTION
636 NTSTATUS
637 NTAPI
638 InitXlateImpl(VOID)
639 {
640 EXLATEOBJ_vInitTrivial(&gexloTrivial);
641 return STATUS_SUCCESS;
642 }
643
644
645 /** Public DDI Functions ******************************************************/
646
647 #undef XLATEOBJ_iXlate
648 ULONG
649 NTAPI
650 XLATEOBJ_iXlate(XLATEOBJ *pxlo, ULONG iColor)
651 {
652 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
653
654 if (!pxlo)
655 return iColor;
656
657 /* Call the iXlate function */
658 return pexlo->pfnXlate(pexlo, iColor);
659 }
660
661 ULONG
662 NTAPI
663 XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
664 {
665 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
666 PPALETTE ppal;
667 INT i;
668
669 if (!pxlo)
670 {
671 return 0;
672 }
673
674 if (iPal > 5)
675 {
676 DPRINT1("XLATEOBJ_cGetPalette called with wrong iPal: %d\n", iPal);
677 return 0;
678 }
679
680 /* Get the requested palette */
681 if (iPal == XO_DESTDCPALETTE)
682 {
683 ppal = pexlo->ppalDstDc;
684 }
685 else if (iPal == XO_SRCPALETTE || iPal == XO_SRCBITFIELDS)
686 {
687 ppal = pexlo->ppalSrc;
688 }
689 else
690 {
691 ppal = pexlo->ppalDst;
692 }
693
694 /* Verify palette type match */
695 if (!ppal ||
696 ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
697 && !(ppal->flFlags & PAL_INDEXED)) ||
698 ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
699 && !(ppal->flFlags & PAL_BITFIELDS)))
700 {
701 return 0;
702 }
703
704 if(!pPalOut)
705 {
706 return ppal->NumColors;
707 }
708
709 /* Copy the values into the buffer */
710 if (ppal->flFlags & PAL_INDEXED)
711 {
712 cPal = min(cPal, ppal->NumColors);
713 for (i = 0; i < cPal; i++)
714 {
715 pPalOut[i] = RGB(ppal->IndexedColors[i].peRed,
716 ppal->IndexedColors[i].peGreen,
717 ppal->IndexedColors[i].peBlue);
718 }
719 }
720 else
721 {
722 // FIXME: should use the above code
723 pPalOut[0] = ppal->RedMask;
724 pPalOut[1] = ppal->GreenMask;
725 pPalOut[2] = ppal->BlueMask;
726 }
727
728 return cPal;
729 }
730
731 HANDLE
732 NTAPI
733 XLATEOBJ_hGetColorTransform(XLATEOBJ *pxlo)
734 {
735 PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo;
736 return pexlo->hColorTransform;
737 }
738
739 PULONG
740 NTAPI
741 XLATEOBJ_piVector(XLATEOBJ *pxlo)
742 {
743 if (pxlo->iSrcType == PAL_INDEXED)
744 {
745 return pxlo->pulXlate;
746 }
747
748 return NULL;
749 }
750
751 /* EOF */