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