Code: Address |Command:
PXLATE CreateXlateObject(
HANDLE hcmXform,
LONG lIcmMode,
XEPALOBJ palSrc,
XEPALOBJ palDestSurf,
XEPALOBJ palSrcDC,
XEPALOBJ palDestDC,
ULONG iForeDst,
ULONG iBackDst,
ULONG iBackSrc,
ULONG flCreateFlag
){
- no machine code -
/*
Allocates an xlate and sets it up.

Arguments:
palSrc - src surface palette
palDestSurf - dst surface palette
palSrcDC - src DC palette
palDestDC - dst DC palette
iForeDst - For Mono->Color this is
           what a 0 goes to
iBackDst - For Mono->Color this is
           what a 1 goes to
iBackSrc - For Color->Mono this is
           the color that goes to 1,
           all other colors go to 0.

History:
02-May-1991 -by- ...
*/

// set up the frame pointer
000E216B|push ebp
000E216C|mov ebp, esp

// save some registers
000E2174|push ebx
000E2175|push esi
000E2176|push edi
ASSERTGDI(
palDestDC.bValid(),
"CreateXlateObject recieved bad ppalDstDC,
bug in GDI"
);

ASSERTGDI(
palSrc.bValid() || palDestSurf.bValid(),
"CreateXlaetObject recieved bad ppalSrc,
bug in GDI"
);

ASSERTGDI(
palSrc.ppalGet() != palDestSurf.ppalGet(),
"Didn't recognize ident quickly"
);

- no machine code -
ULONG ulTemp;

000E216E|sub esp, 0C
// cEntry == 0 means the source palette is an
// RGB/Bitfields type.
// An invalid palette means it's a compatible
// bitmap on a palette managed device.

ULONG cEntry = (
palSrc.bValid() ? palSrc.cEntries() : 256
);
// bug: Some of the following code paths assume,
// that they can write up to 256 entries.
// If this is not the case, we have a buffer overrun.


000E2171|mov eax, dword ptr [ebp+10]
000E2177|test eax, eax
000E2179|je short 000E2180
000E217B|mov eax, dword ptr [eax+14]
000E217E|jmp short 000E2185
000E2180|mov eax, 100
000E2186|mov dword ptr [ebp-4], eax
// Allocate room for the structure.
PXLATE pxlate = pCreateXlate(cEntry);

000E2185|push eax
000E2189|call 0000EDC9
...

// Ok, lets build the translate vector.
if(
!palSrc.bValid() || (
palSrc.bIsPalManaged() && (
ptransFore == ptransCurrent ||
flCreateFlag & XLATE_USE_FOREGROUND
)
)
){
// bug related note: At this point palSrc might
// be valid and cEntry might be smaller than 256.


000E221A|test edx, edx
000E221F|je 000E2482

000E2225|mov ecx, dword ptr [edx+10]
000E2228|test ch, 08
000E222B|je short 000E2240

000E222D|cmp dword ptr [ebp+0C], eax
000E2230|je 000E2482

000E2236|test byte ptr [ebp+2D], 40
000E223A|jne 000E2482
// The source is a compatible bitmap on a
// palette managed device or the screen
// with Dst DC palette having been realized
// in the foreground.
//
// We start out assuming an identity blt.
// This means, that the color translation
// is:
//    color on dest. surface = color of src. surf.


- no machine code -
...

ASSERTGDI(
cEntry == 256,
"ERROR xlate too small"
);

- no machine code -
// bug related note: This is a code snippet,
// where a buffer overrun might happen.

for(
ulTemp = 0;
ulTemp < 256;
ulTemp++
){
pxlate->ai[ulTemp] = ulTemp;
}

000E249F|xor eax, eax
000E24A1|lea ecx, [esi+3C]
000E24A4|mov dword ptr [ecx], eax
000E24A6|inc eax
000E24A7|add ecx, 4
000E24AA|cmp eax, 100
000E24AF|jb short 000E24A4
if(!palDestSurf.bValid()){
// Compatible bitmap to compatible bitmap
// on palette managed device. Both are
// relevant to the foreground realize of
// the DestDC palette so the xlate is
// identity.

...
000E24B1|test ebx, ebx
000E24B3|je short 000E24F2

000E24F2|...
000E24F6|jmp 000E2677
}else if(
palDestSurf.bIsPalDibsection() &&
bEqualRGB_In_Palette(palDestSurf, palDestDC)
){
// If you blt from a compatible bitmap to a
// DIBSECTION it will be identity if the
// RGB's of both the DC palette and the
// DIBSECTION's palette are the same. We do
// this special check so that if they
// contain duplicates we still get an
// identity xlate.

...
000E24B5|test byte ptr [ebx+11], 80
000E24B9|je short 000E24DE

000E24BB|push edi
000E24BC|push ebx
000E24BD|call 00048E90
000E24C2|test eax, eax
000E24C4|jne short 000E24F2

000E24F2|...
000E24F6|jmp 000E2677
}else if(
palDestSurf.bIsPalDibsection() &&
palSrc.bValid() &&
bEqualRGB_In_Palette(palDestSurf, palSrc)
){
...
000E24C6|test byte ptr [ebx+11], 80
000E24CD|je short 000E24DE

000E24CA|mov edx, dword ptr [ebp+10]
000E24CF|test edx, edx
000E24D1|je short 000E24DE

000E24D3|push edx
000E24D4|push ebx
000E24D5|call 00048E90
000E24DA|test eax, eax
000E24DC|jne short 000E24F2

000E24F2|...
000E24F6|jmp 000E2677
}else if(palDestSurf.bIsPalManaged()){
// Compatible bitmap to the screen on a
// palette managed device. The compatible
// bitmaps colors are defined as the
// foreground realization of the
// destination DC's palette.
//
// If the Dst DC's palette is realized in
// the foreground it's identity.
//
// Otherwise we translate from the current
// to the foreground indices.


000E24DE|mov eax, dword ptr [ebx+10]
000E24E1|test ah, 08
000E24E4|je 000E257E
if(ptransCurrent == ptransFore){
// It's in the foreground or not
// realized yet so it's identity.

// Not realized case also hits on
// default logical palette.

...
000E24EA|mov eax, dword ptr [ebp+0C]
000E24ED|cmp dword ptr [ebp+8], eax
000E24F0|jne short 000E24FB

000E24F2|...
000E24F6|jmp 000E2677
}else{
// It's foreground to current
// translation.


ASSERTGDI(
ptransFore != ptransCurrent,
"Should have been identity,
never get here"
);

ASSERTGDI(
ptransFore,
"ERROR this should not have
got here Fore"
);

ASSERTGDI(
ptransCurrent,
"ERROR this should not have
got here Current"
);

- no machine code -
// bug related note: This is a code
// snippet, where a buffer overrun
// might happen.

for(
ulTemp = 0;
ulTemp < palDestDC.cEntries();
ulTemp++
){
pxlate->ai[
ptransFore->ajVector[
ulTemp
]
] = (ULONG)(
ptransCurrent->ajVector[
ulTemp
]
);
}

// if: palDestDC.cEntries <= 0,
// then: jump to: end of the loop

000E24FB|cmp dword ptr [edi+14], 0
000E24FF|jbe short 000E2533

// ulTemp = ptransFore + 4
000E2501|mov ecx, dword ptr [ebp+0C]
000E250B|lea eax, [ecx+4]

// [ebp+10] = ptransCurrent - ptransFore
000E2504|mov edx, dword ptr [ebp+8]
000E2509|sub edx, ecx
000E2512|mov dword ptr [ebp+10], edx

// [ebp+1C] = -4 - ptransFore
000E2507|push -4
000E250E|pop ecx
000E250F|sub ecx, dword ptr [ebp+0C]
000E2515|mov dword ptr [ebp+1C], ecx

...

// 000E251A|- beginning of the loop -

// edx = ptransCurrent - ptransFore
000E251A|mov edx, dword ptr [ebp+10]

// ecx = ptransCurrent->ajVector[ulTemp]
000E251D|movzx ecx, byte ptr [eax+edx]

// edx = ptransFore->ajVector[ulTemp]
000E2521|movzx edx, byte ptr [eax]

// pxlate->ai[edx] = ecx
000E2525|mov dword ptr [edx*4+esi+3C], ecx

// ulTemp++
000E2524|inc eax

// ecx = -4 - ptransFore + ulTemp
000E2529|mov ecx, dword ptr [ebp+1C]
000E252C|add ecx, eax

// if: ecx < palDestDC.cEntries,
// then: jump to: 000E251A

000E252E|cmp ecx, dword ptr [edi+14]
000E2531|jb short 000E251A

// 000E2533|- end of the loop -

// Now map the default colors that
// are really there, independent of
// logical palette.

if(palDestSurf.bIsNoStatic()){
000E2533|mov ebx, dword ptr [ebx+10]
000E2536|test bh, 10
000E2539|je short 000E254E
// bug related note: This is a
// code snippet, where a buffer
// overrun might happen.


// Only black and white are
// here.

pxlate->ai[0] = 0;
pxlate->ai[255] = 255;
000E253B|and dword ptr [esi+3C], 00000000
000E253F|mov dword ptr [esi+3C+(FF*4)], FF
000E2549|jmp 000E2677
}else if(
!palDestSurf.bIsNoStatic256()
){
000E254E|test ebx, 00010000
000E2554|jne 000E2677
// All the 20 holy colors are
// here. Fix them up.

for(
ulTemp = 0;
ulTemp < 10;
ulTemp++
){
pxlate->ai[
ulTemp
] = ulTemp;

// bug related note: This
// is a code snippet,
// where a buffer overrun
// might happen.

pxlate->ai[
ulTemp + 246
] = ulTemp + 246;
}
}
}
}else if(palDestSurf.bIsMonochrome()){
// bug related note: This is a code snippet,
// where a buffer overrun might happen.

RtlZeroMemory(
pxlate->ai,
256 * sizeof(ULONG)
);

There is much more code in this function, so I shortened it from here drastically ...

pxlate->vCheckForTrivial();

return(pxlate);
}

PXLATE pCreateXlate(
ULONG ulNumEntries
){
/*
This allocates an xlate object with ulNumEntries.

Returns:
The pointer to the xlate object, NULL for failure.

History:
17-May-1991 -by- ...
*/

// Allocate room for the XLATE.
PXLATE pxlate = (PXLATE)PALLOCNOZ(
(
  sizeof(XLATE)
+ sizeof(ULONG) * ulNumEntries
),
'tlxG'
);

...

return(pxlate);
}