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