|
|
/******************************Module*Header*******************************\
* Module Name: srcblt4.cxx * * This contains the bitmap simulation functions that blt to a 4 bit/pel * DIB surface. * * Created: 07-Feb-1991 19:27:49 * Author: Patrick Haluptzok patrickh * * Copyright (c) 1990-1999 Microsoft Corporation * \**************************************************************************/
#include "precomp.hxx"
/*******************Public*Routine*****************\
* vSrcCopyS1D4 * * There are three main loops in this function. * * The first loop deals with the full bytes part of * the Dst while fetching/shifting the matching 8 bits * from the Src. * * The second loop deals with the starting pixels * We use a dword mask here. * * The third loop deals with the Ending pixels * We use a dword mask here. * * We use a 4 entry dword table to expand the * Src bits. We walk thru Src one byte at a time * and expand the byte to 1 dword * * History: * 17-Oct-1994 -by- Lingyun Wang [lingyunw] * Wrote it. * \**************************************************/
VOID vSrcCopyS1D4(PBLTINFO psb) { BYTE jSrc; // holds a source byte
BYTE jDst; // holds a dest byte
INT iSrc; // bit position in the first Src byte
INT iDst; // bit position in the first 8 Dst nibbles
PBYTE pjDst; // pointer to the Src bytes
PBYTE pjSrc; // pointer to the Dst bytes
LONG xSrcEnd = psb->xSrcEnd; LONG cy; // number of rows
LONG cx; // number of pixels
BYTE jAlignL; // alignment bits to the left
BYTE jAlignR; // alignment bits to the right
LONG cFullBytes; //number of full 8 bytes dealed with
BOOL bNextByte; LONG xDstEnd; LONG lDeltaDst; LONG lDeltaSrc; BYTE jB = (BYTE) (psb->pxlo->pulXlate[0]); BYTE jF = (BYTE) (psb->pxlo->pulXlate[1]); BYTE ajExpTable[4]; INT count; INT i; BYTE ajSrc[4]; static ULONG aulStartMask[8] = {0XFFFFFFFF, 0XFFFFFF0F, 0XFFFFFF00, 0XFFFF0F00, 0XFFFF0000, 0XFF0F0000, 0XFF000000, 0X0F000000}; static ULONG aulEndMask[8] = {0X00000000, 0X000000F0, 0X000000FF, 0X0000F0FF, 0X0000FFFF, 0X00F0FFFF, 0X00FFFFFF, 0XF0FFFFFF}; ULONG ulMask; BOOL bNextSrc=TRUE;
// We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D4 - direction not up to down"); ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
//DbgPrint ("vsrccopys1d4\n");
// Build table
ajExpTable[0] = jB | (jB << 4); // 0 0
ajExpTable[1] = jF | (jB << 4); // 0 1
ajExpTable[2] = jB | (jF << 4); // 1 0
ajExpTable[3] = jF | (jF << 4); //1 1
//Get Src and Dst start positions
iSrc = psb->xSrcStart & 0x0007; iDst = psb->xDstStart & 0x0007;
// Checking alignment
// If Src starting point is ahead of Dst
if (iSrc < iDst) jAlignL = 8 - (iDst - iSrc); else // If Dst starting point is ahead of Src
jAlignL = iSrc - iDst;
jAlignR = 8 - jAlignL;
cx=psb->cx;
xDstEnd = psb->xDstStart + cx;
lDeltaDst = psb->lDeltaDst; lDeltaSrc = psb->lDeltaSrc;
// check if there is a next 8 nibbles
bNextByte = !((xDstEnd>>3) == (psb->xDstStart>>3));
if (bNextByte) { long iStrideSrc; long iStrideDst; PBYTE pjSrcEnd; //pointer to the Last full Src byte
// Get first Dst full 8 nibbles (1 dword expanding from
// 1 Src byte)
pjDst = psb->pjDst + (((psb->xDstStart+7)&~0x07)>>1);
// Get the Src byte that matches the first Dst
// full 8 nibbles
pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
//Get the number of full bytes
cFullBytes = (xDstEnd>>3)-((psb->xDstStart+7)>>3);
//the increment to the full byte on the next scan line
iStrideDst = lDeltaDst - cFullBytes*4; iStrideSrc = lDeltaSrc - cFullBytes;
// deal with our special case
cy = psb->cy;
if (!jAlignL) { while (cy--) { pjSrcEnd = pjSrc+cFullBytes;
while (pjSrc != pjSrcEnd) { jSrc = *pjSrc++;
*pjDst = ajExpTable[(jSrc&0xC0)>>6]; *(pjDst+1) = ajExpTable[(jSrc&0x30)>>4]; *(pjDst+2) = ajExpTable[(jSrc&0x0C)>>2]; *(pjDst+3) = ajExpTable[jSrc&0x03];
pjDst +=4; }
pjDst += iStrideDst; pjSrc += iStrideSrc; }
} //end of if (!jAlignL)
else // if not aligned
{ BYTE jRem; //remainder
while (cy--) { jRem = *pjSrc << jAlignL;
pjSrcEnd = pjSrc+cFullBytes;
while (pjSrc != pjSrcEnd) { jSrc = ((*(++pjSrc))>>jAlignR) | jRem;
*pjDst = ajExpTable[(jSrc&0xC0)>>6]; *(pjDst+1) = ajExpTable[(jSrc&0x30)>>4]; *(pjDst+2) = ajExpTable[(jSrc&0x0C)>>2]; *(pjDst+3) = ajExpTable[jSrc&0x03];
pjDst +=4;
//next remainder
jRem = *pjSrc << jAlignL; }
pjDst += iStrideDst; pjSrc += iStrideSrc; } } //else
} //if
// End of our dealing with the full bytes
//Deal with the starting pixels
if (iDst | !bNextByte) { //build our masks
ulMask = aulStartMask[iDst];
// if there are only one partial left byte,
// the mask is special
// for example, when we have 00111000 for
// Dst
if (!bNextByte) { ulMask &= aulEndMask[xDstEnd&0x0007]; }
bNextSrc = ((iSrc+cx)>8);
pjDst = psb->pjDst + ((psb->xDstStart&~0x07)>>1);
pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
cy = psb->cy;
if (iSrc >= iDst) { if (bNextSrc) { while (cy--) { jSrc = *pjSrc << jAlignL; jSrc |= *(pjSrc+1) >> jAlignR;
ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6]; ajSrc[1] = ajExpTable[(jSrc&0x30)>>4]; ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2]; ajSrc[3] = ajExpTable[jSrc&0x03];
*(PULONG) ajSrc &= ulMask;
*(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
pjDst += lDeltaDst; pjSrc += lDeltaSrc; } } else { while (cy--) { jSrc = *pjSrc << jAlignL;
ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6]; ajSrc[1] = ajExpTable[(jSrc&0x30)>>4]; ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2]; ajSrc[3] = ajExpTable[jSrc&0x03];
*(PULONG) ajSrc &= ulMask;
*(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
pjDst += lDeltaDst; pjSrc += lDeltaSrc; } } } else //if (iSrc < iDst)
{ while (cy--) { jSrc = *pjSrc >> jAlignR;
ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6]; ajSrc[1] = ajExpTable[(jSrc&0x30)>>4]; ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2]; ajSrc[3] = ajExpTable[jSrc&0x03];
*(PULONG) ajSrc &= ulMask;
*(PULONG) pjDst = (*(PULONG)pjDst & ~ulMask) | *(PULONG) ajSrc;
pjDst += lDeltaDst; pjSrc += lDeltaSrc; } } }
// Dealing with Ending pixels
if ((xDstEnd & 0x0007) && bNextByte) { ulMask = aulEndMask[xDstEnd & 0x0007];
pjDst = psb->pjDst + ((xDstEnd&~0x07)>>1); pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
iSrc = (xSrcEnd-1) & 0x0007; iDst = (xDstEnd-1) & 0x0007;
cy = psb->cy;
if (iSrc >= iDst) { while (cy--) { jSrc = *pjSrc << jAlignL;
ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6]; ajSrc[1] = ajExpTable[(jSrc&0x30)>>4]; ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2]; ajSrc[3] = ajExpTable[jSrc&0x03];
*(PULONG) ajSrc &= ulMask;
*(PULONG) pjDst = (*(PULONG) pjDst & ~ulMask) | *(PULONG) ajSrc;
pjDst += lDeltaDst; pjSrc += lDeltaSrc; } } else //if (iSrc < iDst)
{ while (cy--) { jSrc = *(pjSrc-1) << jAlignL;
jSrc |= *pjSrc >> jAlignR;
ajSrc[0] = ajExpTable[(jSrc&0xC0)>>6]; ajSrc[1] = ajExpTable[(jSrc&0x30)>>4]; ajSrc[2] = ajExpTable[(jSrc&0x0C)>>2]; ajSrc[3] = ajExpTable[jSrc&0x03];
*(PULONG) ajSrc &= ulMask;
*(PULONG) pjDst = (*(PULONG) pjDst & ~ulMask) | *(PULONG) ajSrc;
pjDst += lDeltaDst; pjSrc += lDeltaSrc; } } }
}
/******************************Public*Routine******************************\
* vSrcCopyS4D4 * * History: * 09-Feb-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
VOID vSrcCopyS4D4(PBLTINFO psb) { // We assume we are doing left to right top to bottom blting
// Otherwise we would be in vSrcCopyS4D4Identity.
ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D4 - direction not up to down");
BYTE jSrc; BYTE jDst; LONG iSrc; LONG iDst; PBYTE pjDst; PBYTE pjSrc; PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1); PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart >> 1); ULONG cy = psb->cy; PULONG pulXlate = psb->pxlo->pulXlate;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1) { // Initialize all the variables
pjDst = pjDstHolder; pjSrc = pjSrcHolder;
iSrc = psb->xSrcStart; iDst = psb->xDstStart;
{ // If source and dest are not aligned we have to do
// this the hard way
//
if ((iSrc ^ iDst) & 1) { LONG iCnt; iSrc = psb->xSrcEnd - iSrc;
// if blt starts on odd nibble we need to update it
//
if ((iDst & 1) && iSrc) { *pjDst = (*pjDst & 0xf0) | (BYTE)pulXlate[((*pjSrc >> 4) & 0x0f)]; pjDst++; iSrc--; } // loop once per output byte (2 pixels)
//
iCnt = iSrc >> 1; while (--iCnt >= 0) { *pjDst++ = ((BYTE)pulXlate[*pjSrc & 0x0f] << 4) | (BYTE)pulXlate[(pjSrc[1] >> 4) & 0x0f]; pjSrc++; } // test if blt ends on odd nibble
//
if (iSrc & 1) *pjDst = (*pjDst & 0x0f) | ((BYTE)pulXlate[*pjSrc & 0x0f] << 4); } // Source and Dest are aligned
//
else { LONG iCnt; iSrc = psb->xSrcEnd - iSrc;
// if blt starts on odd nibble we need to update it
//
if ((iDst & 1) && iSrc) { *pjDst = (*pjDst & 0xf0) | (BYTE)pulXlate[*pjSrc++ & 0x0f]; pjDst++; iSrc--; } // loop once per output byte (2 pixels)
//
iCnt = iSrc >> 1; while (--iCnt >= 0) { *pjDst++ = (BYTE)pulXlate[*pjSrc & 0x0f] | ((BYTE)pulXlate[(*pjSrc & 0xf0) >> 4] << 4); pjSrc++; } // test if blt ends on odd nibble
//
if (iSrc & 1) *pjDst = (*pjDst & 0x0f) | ((BYTE)pulXlate[(*pjSrc >> 4) & 0x0f] << 4); } }
// Check if we have anymore scanlines to do
if (--cy) { pjSrcHolder += psb->lDeltaSrc; pjDstHolder += psb->lDeltaDst; } else break; } }
/******************************Public*Routine******************************\
* vSrcCopyS4D4Identity * * History: * 09-Feb-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
VOID vSrcCopyS4D4Identity(PBLTINFO psb) { BYTE jSrc; BYTE jDst; LONG iSrc; LONG iDst; PBYTE pjDst; PBYTE pjSrc; PBYTE pjDstHolder = psb->pjDst + ((psb->xDstStart) >> 1); PBYTE pjSrcHolder = psb->pjSrc + ((psb->xSrcStart) >> 1); ULONG cy = psb->cy;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
#if MESSAGE_BLT
DbgPrint("Now entering vSrcCopyS4D4Identity\n"); DbgPrint("xdir: %ld cy: %lu xSrcStart %lu xDstStart %lu xSrcEnd %lu \n", psb->xDir, cy, psb->xSrcStart, psb->xDstStart, psb->xSrcEnd); #endif
if (psb->xDir > 0) { // We're going left to right.
while(1) { // Initialize all the variables
pjDst = pjDstHolder; pjSrc = pjSrcHolder;
iSrc = psb->xSrcStart; iDst = psb->xDstStart; // If source and dest are not aligned we have to do
// this the hard way
//
if ((iSrc ^ iDst) & 1) { LONG iCnt; iSrc = psb->xSrcEnd - iSrc;
// if blt starts on odd nibble we need to update it
//
if ((iDst & 1) && iSrc) { *pjDst = (*pjDst & 0xf0) | ((*pjSrc >> 4) & 0x0f); pjDst++; iSrc--; } // loop once per output byte (2 pixels)
//
iCnt = iSrc >> 1; while (--iCnt >= 0) { BYTE jSrc = *pjSrc++ << 4; *pjDst++ = jSrc | ((*pjSrc >> 4) & 0x0f); } // test if blt ends on odd nibble
//
if (iSrc & 1) *pjDst = (*pjDst & 0x0f) | (*pjSrc << 4); } // Source and Dest are aligned
//
else { iSrc = psb->xSrcEnd - iSrc;
// if blt starts on odd nibble we need to update it
//
if ((iDst & 1) && iSrc) { *pjDst = (*pjDst & 0xf0) | (*pjSrc++ & 0x0f); pjDst++; iSrc--; } // loop once per output byte (2 pixels)
//
RtlMoveMemory(pjDst,pjSrc,iSrc >> 1);
// test if blt ends on odd nibble
//
if (iSrc & 1) { iSrc >>= 1; pjDst[iSrc] = (pjDst[iSrc] & 0x0f) | (pjSrc[iSrc] & 0xf0); } } // Check if we have anymore scanlines to do
if (--cy) { pjSrcHolder += psb->lDeltaSrc; pjDstHolder += psb->lDeltaDst; } else break; } } else { // We're going right to left. It must be on the same hsurf,
// therefore must be an identity translation.
ASSERTGDI(psb->pxlo->bIsIdentity(), "Error: S4D4 -xDir, non-ident xlate");
while(1) { // Initialize all the variables
pjDst = pjDstHolder; pjSrc = pjSrcHolder;
iSrc = psb->xSrcStart; iDst = psb->xDstStart;
if (!(iSrc & 0x00000001)) { jSrc = *pjSrc; pjSrc--; }
if (iDst & 0x00000001) { jDst = 0; } else { // We're gonna need the low nibble from the first byte
jDst = *pjDst; jDst = (BYTE) (jDst & 0x0F); }
// Do the inner loop on a scanline
while(iSrc != psb->xSrcEnd) { if (iSrc & 0x00000001) { // We need a new source byte
jSrc = *pjSrc; pjSrc--;
if (iDst & 0x00000001) { // jDst must be 0 right now.
ASSERTGDI(jDst == (BYTE) 0, "ERROR in vSrcCopyS4D4 srcblt logic");
jDst |= (BYTE) (jSrc & 0x0F); } else { jDst |= (BYTE) (((ULONG) (jSrc & 0x0F)) << 4); *pjDst = jDst; pjDst--; jDst = 0; } } else { if (iDst & 0x00000001) { // jDst must be 0 right now.
ASSERTGDI(jDst == (BYTE) 0, "ERROR in vSrcCopyS4D4 srcblt logic");
jDst |= (BYTE) ((jSrc & 0xF0) >> 4); } else { jDst |= (BYTE) (jSrc & 0xF0); *pjDst = jDst; pjDst--; jDst = 0; } }
iSrc--; iDst--; }
// Clean up after the inner loop. We are going right to left.
if (!(iDst & 0x00000001)) { // The last pel was the low nibble, we need to get the high
// nibble out of the bitmap and write then write the byte in.
*pjDst = (BYTE) (jDst | (*pjDst & 0xF0)); }
// Check if we have anymore scanlines to do
if (--cy) { pjSrcHolder += psb->lDeltaSrc; pjDstHolder += psb->lDeltaDst; } else break; } } }
/******************************Public*Routine******************************\
* vSrcCopyS8D4 * * * History: * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh] * optimize color translation * * 06-Feb-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
VOID vSrcCopyS8D4(PBLTINFO psb) { // We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D4 - direction not up to down");
LONG iDst; PBYTE pjSrc; PBYTE pjDst; LONG iDstEnd = psb->xDstStart + psb->cx; PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1); PBYTE pjSrcHolder = psb->pjSrc + psb->xSrcStart; ULONG cy = psb->cy; PULONG pulXlate = psb->pxlo->pulXlate;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1) { pjDst = pjDstHolder; pjSrc = pjSrcHolder;
iDst = psb->xDstStart;
if (iDst & 0x00000001) { // Do the first byte if it's misaligned.
*pjDst = (BYTE) ((*pjDst) & 0xF0) | ((BYTE) pulXlate[*(pjSrc++)]); pjDst++; iDst++; }
while(1) { if ((iDst + 1) < iDstEnd) { // Do a whole byte.
*(pjDst++) = (BYTE) (pulXlate[*(pjSrc + 1)] | (pulXlate[*pjSrc] << 4));
pjSrc += 2; iDst += 2; } else { // Check and see if we have a byte left to do.
if (iDst < iDstEnd) { // This is our last byte. Save low nibble from Dst.
*pjDst = (BYTE) (((*pjDst) & 0x0F) | ((BYTE) (pulXlate[*pjSrc] << 4))); }
break; } }
if (--cy) { pjSrcHolder += psb->lDeltaSrc; pjDstHolder += psb->lDeltaDst; } else break; } }
/******************************Public*Routine******************************\
* vSrcCopyS16D4 * * * History: * Sun 10-Feb-1991 -by- Patrick Haluptzok [patrickh] * Wrote it. \**************************************************************************/
VOID vSrcCopyS16D4(PBLTINFO psb) { // We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D4 - direction not up to down");
LONG iDst; PUSHORT pusSrc; PBYTE pjDst; LONG iDstEnd = psb->xDstStart + psb->cx; PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1); PUSHORT pusSrcHolder = (PUSHORT) (psb->pjSrc + (psb->xSrcStart << 1)); ULONG cy = psb->cy; XLATE *pxlo = psb->pxlo;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
while(1) { pjDst = pjDstHolder; pusSrc = pusSrcHolder;
iDst = psb->xDstStart;
if (iDst & 0x00000001) { // Do the first byte if it's misaligned.
*pjDst = (BYTE) ((*pjDst) & 0xF0) | ((BYTE) pxlo->ulTranslate(*(pusSrc++))); pjDst++; iDst++; }
while(1) { if ((iDst + 1) < iDstEnd) { // Do a whole byte.
*(pjDst++) = (BYTE) (pxlo->ulTranslate(*(pusSrc + 1)) | (pxlo->ulTranslate(*pusSrc) << 4));
pusSrc += 2; iDst += 2; } else { // Check and see if we have a byte left to do.
if (iDst < iDstEnd) { // This is our last byte. Save low nibble from Dst.
*pjDst = (BYTE) ((*pjDst) & 0x0F) | ((BYTE) (pxlo->ulTranslate(*pusSrc) << 4)); }
break; } }
if (--cy) { pusSrcHolder = (PUSHORT) (((PBYTE) pusSrcHolder) + psb->lDeltaSrc); pjDstHolder += psb->lDeltaDst; } else break; } }
/******************************Public*Routine******************************\
* vSrcCopyS24D4 * * * History: * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh] * optimize color translation * * 06-Feb-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
#define Translate32to4(ulPelTemp) ((ulPelLast == ulPelTemp) ? jPelLast : (jPelLast = (BYTE) pxlo->ulTranslate(ulPelLast = ulPelTemp)))
VOID vSrcCopyS24D4(PBLTINFO psb) { // We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D4 - direction not up to down");
LONG iDst; ULONG ulPelTemp; // variable to build src RGB's in.
PBYTE pjSrc; PBYTE pjDst; LONG iDstEnd = psb->xDstStart + psb->cx; PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1); PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart * 3); ULONG cy = psb->cy; XLATE *pxlo = psb->pxlo; ULONG ulPelLast; // This is the last pel in the src.
BYTE jPelLast; // This is the last pel in the dst.
BYTE jDstTmp;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
// Initialize the cache
ulPelLast = *(pjSrcHolder + 2); ulPelLast = ulPelLast << 8; ulPelLast |= (ULONG) *(pjSrcHolder + 1); ulPelLast = ulPelLast << 8; ulPelLast |= (ULONG) *pjSrcHolder; jPelLast = (BYTE) (pxlo->ulTranslate(ulPelLast));
// Just do it
while(1) { pjDst = pjDstHolder; pjSrc = pjSrcHolder;
iDst = psb->xDstStart;
if (iDst & 0x00000001) { // Do the first byte if it's misaligned.
ulPelTemp = *(pjSrc + 2); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *(pjSrc + 1); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *pjSrc;
Translate32to4(ulPelTemp); *pjDst = (BYTE) ((*pjDst) & 0xF0) | jPelLast; pjDst++; iDst++; pjSrc += 3; }
while(1) { if ((iDst + 1) < iDstEnd) { // Do a whole byte.
ulPelTemp = (ULONG) *(pjSrc + 2); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *(pjSrc + 1); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *pjSrc; jDstTmp = Translate32to4(ulPelTemp); pjSrc += 3;
ulPelTemp = (ULONG) *(pjSrc + 2); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *(pjSrc + 1); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *pjSrc; Translate32to4(ulPelTemp);
*(pjDst++) = (BYTE) (jPelLast | (jDstTmp << 4));
pjSrc += 3; iDst += 2; } else { // Check and see if we have a byte left to do.
if (iDst < iDstEnd) { // This is our last byte. Save low nibble from Dst.
ulPelTemp = (ULONG) *(pjSrc + 2); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *(pjSrc + 1); ulPelTemp = ulPelTemp << 8; ulPelTemp |= (ULONG) *pjSrc;
Translate32to4(ulPelTemp);
*pjDst = (BYTE) ((*pjDst) & 0x0F) | ((BYTE) (jPelLast << 4)); }
// We are done with this scan
break; } }
if (--cy) { pjSrcHolder += psb->lDeltaSrc; pjDstHolder += psb->lDeltaDst; } else break; } }
/******************************Public*Routine******************************\
* vSrcCopyS32D4 * * * History: * Wed 23-Oct-1991 -by- Patrick Haluptzok [patrickh] * optimize color translation * * Sun 10-Feb-1991 -by- Patrick Haluptzok [patrickh] * Wrote it. \**************************************************************************/
VOID vSrcCopyS32D4(PBLTINFO psb) { // We assume we are doing left to right top to bottom blting
ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D4 - direction not left to right"); ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D4 - direction not up to down");
LONG iDst; PULONG pulSrc; PBYTE pjDst; LONG iDstEnd = psb->xDstStart + psb->cx; PBYTE pjDstHolder = psb->pjDst + (psb->xDstStart >> 1); PULONG pulSrcHolder = (PULONG) (psb->pjSrc + (psb->xSrcStart << 2)); ULONG cy = psb->cy; XLATE *pxlo = psb->pxlo; ULONG ulPelTemp; ULONG ulPelLast; // This is the last pel in the src.
BYTE jPelLast; // This is the last pel in the dst.
BYTE jDstTmp;
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
// Initialize the cache
ulPelLast = *pulSrcHolder; jPelLast = (BYTE) (pxlo->ulTranslate(ulPelLast));
// Just do it
while(1) { pjDst = pjDstHolder; pulSrc = pulSrcHolder;
iDst = psb->xDstStart;
if (iDst & 0x00000001) { // Do the first byte if it's misaligned.
ulPelTemp = *(pulSrc++); Translate32to4(ulPelTemp); *pjDst = (BYTE) ((*pjDst) & 0xF0) | jPelLast; pjDst++; iDst++; }
while(1) { if ((iDst + 1) < iDstEnd) { // Do a whole byte.
ulPelTemp = *(pulSrc++); jDstTmp = Translate32to4(ulPelTemp); ulPelTemp = *(pulSrc++); Translate32to4(ulPelTemp);
*(pjDst++) = (BYTE) (jPelLast | (jDstTmp << 4));
iDst += 2; } else { // Check and see if we have a byte left to do.
if (iDst < iDstEnd) { // This is our last byte. Save low nibble from Dst.
ulPelTemp = *pulSrc; Translate32to4(ulPelTemp);
*pjDst = (BYTE) ((*pjDst) & 0x0F) | ((BYTE) (jPelLast << 4)); }
break; } }
if (--cy) { pulSrcHolder = (PULONG) (((PBYTE) pulSrcHolder) + psb->lDeltaSrc); pjDstHolder += psb->lDeltaDst; } else break; } }
|