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