Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1185 lines
36 KiB

#include "precomp.hxx"
#ifdef __cplusplus
extern "C" {
#endif
#include "dpf.h"
#ifdef __cplusplus
}
#endif
//#define BLT0808_FAST_TRANSPARENCY 1 // set to 1 if one wants a faster, less legal
// transparency comparison, set to 0 for a
// perfect safe but slower transparency
// comparison
void Blt08to08_NoTrans_Hcopy_SRCCOPY_Vcopy(BYTE* pSrcScanLine,
int iSrcScanStride,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows)
{
DWORD *pBigSrcPixel,
*pBigDstPixel,
*pBigEndDstPixel;
BYTE *pSrcPixel,
*pDstPixel,
*pAlignedSrcPixel,
*pAlignedDstPixel;
int iNumDwordsPerLine = iNumDstCols / 4,
iNumBytesLeftDst = iNumDstCols % 4,
iNumUnalignedSrcBytes,
iNumUnalignedDstBytes,
iNumUnalignByteDiff,
i,j;
DWORD dwSrc1, dwSrc2;
// If the total number of bytes per scan is less than 4, we are
// just going to do a regular byte-wise copy, so skip all this
// alignment junk.....
if(!iNumDwordsPerLine){
iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
}
else{
// Find out if the src and dest pointers are dword aligned
pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
// Now decrement the number of dwords per line and the
// number of bytes left over as appropriate
if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
iNumBytesLeftDst -= iNumUnalignedDstBytes;
else{
iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
if(iNumBytesLeftDst != sizeof(DWORD))
iNumDwordsPerLine--;
}
}
if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
// Do the fast dword copy since the alignments match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedSrcBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigSrcPixel = (DWORD*) pSrcPixel;
pBigDstPixel = (DWORD*) pDstPixel;
pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) {
*pBigDstPixel++ = *pBigSrcPixel++;
}
// take care of remaining pixels on scanline
if (iNumBytesLeftDst) {
pSrcPixel = (BYTE*) pBigSrcPixel;
pDstPixel = (BYTE*) pBigDstPixel;
for(j=0; j<iNumBytesLeftDst; j++){
*pDstPixel++ = *pSrcPixel++;
}
}
// advance to next scanline
pSrcScanLine += iSrcScanStride;
pDstScanLine += iDstScanStride;
}
}
else{
// Find out the difference between the source and dest unalign offsets
// If the unaligned dest offset is less than the unaligned src offset,
// we need to decrement pSrcScanLine so that we can dword-align the first
// source bytes (the extra bytes added to the beginning of the dword
// will end up getting masked off anyway).
if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
else
iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
iNumUnalignedDstBytes);
// Do the trickier copy since the alignments don't match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedDstBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up Dst pointer to the first 4-pixel chunk (dword)
pBigDstPixel = (DWORD *) pDstPixel;
pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
// Set up the temporary dword vars
dwSrc1 = *pBigSrcPixel++;
switch(iNumUnalignByteDiff){
case 1:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
dwSrc1 = dwSrc2;
}
break;
case 2:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
dwSrc1 = dwSrc2;
}
break;
case 3:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
dwSrc1 = dwSrc2;
}
break;
}
// Take care of the bytes left over
pDstPixel = (BYTE *)pBigDstPixel;
pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumBytesLeftDst; j++)
*pDstPixel++ = *pSrcPixel++;
// advance to next scanline
pSrcScanLine += iSrcScanStride;
pDstScanLine += iDstScanStride;
}
}
}
void Blt08to08_NoTrans_Hcopy_SRCCOPY_NoVcopy(BYTE* pSrcScanLine,
int iSrcScanStride,
int iNumSrcRows,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows)
{
DWORD *pBigSrcPixel,
*pBigDstPixel,
*pBigEndDstPixel;
BYTE *pSrcPixel,
*pDstPixel,
*pAlignedSrcPixel,
*pAlignedDstPixel;
int iNumDwordsPerLine = iNumDstCols / 4,
iNumBytesLeftDst = iNumDstCols % 4,
iNumUnalignedSrcBytes,
iNumUnalignedDstBytes,
iNumUnalignByteDiff,
iVertError = 0,
iVertAdvanceError,
iSrcScanAdvance,
i,j;
DWORD dwSrc1, dwSrc2;
// If the total number of bytes per scan is less than 4, we are
// just going to do a regular byte-wise copy, so skip all this
// alignment junk.....
if(!iNumDwordsPerLine){
iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
}
else{
// Find out if the src and dest pointers are dword aligned
pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
// Now decrement the number of dwords per line and the
// number of bytes left over as appropriate
if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
iNumBytesLeftDst -= iNumUnalignedDstBytes;
else{
iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
if(iNumBytesLeftDst != sizeof(DWORD))
iNumDwordsPerLine--;
}
}
if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
// compute advance and error terms for stepping
// vertically through the src bitmap
if (iNumSrcRows < iNumDstRows) {
iSrcScanAdvance = 0;
iVertAdvanceError = iNumSrcRows;
}
else{
iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
iVertAdvanceError = iNumSrcRows % iNumDstRows;
}
// Do the fast dword copy since the alignments match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedSrcBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigSrcPixel = (DWORD*) pSrcPixel;
pBigDstPixel = (DWORD*) pDstPixel;
pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) {
*pBigDstPixel++ = *pBigSrcPixel++;
}
// take care of remaining pixels on scanline
if (iNumBytesLeftDst) {
pSrcPixel = (BYTE*) pBigSrcPixel;
pDstPixel = (BYTE*) pBigDstPixel;
for(j=0; j<iNumBytesLeftDst; j++){
*pDstPixel++ = *pSrcPixel++;
}
}
// advance to next scanline
pSrcScanLine += iSrcScanAdvance;
pDstScanLine += iDstScanStride;
// update and check vertical stepping error,
// adjust src scanline pointer if necessary
iVertError += iVertAdvanceError;
if (iVertError >= iNumDstRows) {
pSrcScanLine += iSrcScanStride;
iVertError -= iNumDstRows;
}
}
}
else{
// Find out the difference between the source and dest unalign offsets
// If the unaligned dest offset is less than the unaligned src offset,
// we need to decrement pSrcScanLine so that we can dword-align the first
// source bytes (the extra bytes added to the beginning of the dword
// will end up getting masked off anyway).
if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
else
iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
iNumUnalignedDstBytes);
// compute advance and error terms for stepping
// vertically through the src bitmap
if (iNumSrcRows < iNumDstRows) {
iSrcScanAdvance = 0;
iVertAdvanceError = iNumSrcRows;
}
else{
iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
iVertAdvanceError = iNumSrcRows % iNumDstRows;
}
// Do the trickier copy since the alignments don't match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedDstBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up Dst pointer to the first 4-pixel chunk (dword)
pBigDstPixel = (DWORD *) pDstPixel;
pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
// Set up the temporary dword vars
dwSrc1 = *pBigSrcPixel++;
switch(iNumUnalignByteDiff){
case 1:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
dwSrc1 = dwSrc2;
}
break;
case 2:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
dwSrc1 = dwSrc2;
}
break;
case 3:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
dwSrc1 = dwSrc2;
}
break;
}
// Take care of the bytes left over
pDstPixel = (BYTE *)pBigDstPixel;
pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumBytesLeftDst; j++)
*pDstPixel++ = *pSrcPixel++;
// advance to next scanline
pSrcScanLine += iSrcScanAdvance;
pDstScanLine += iDstScanStride;
// update and check vertical stepping error,
// adjust src scanline pointer if necessary
iVertError += iVertAdvanceError;
if (iVertError >= iNumDstRows) {
pSrcScanLine += iSrcScanStride;
iVertError -= iNumDstRows;
}
}
}
}
void Blt08to08_NoTrans_NoHcopy_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
int iNumSrcCols,
int iNumSrcRows,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows,
int iHorizMirror)
{
BYTE *pSrcPixel,
*pDstPixel;
int iVertError = 0,
iVertAdvanceError,
iSrcScanAdvance,
iHorizError,
iHorizAdvanceError,
iSrcPixelAdvance;
// compute advance and error terms for stepping
// vertically through the src bitmap
if (iNumSrcRows < iNumDstRows) {
iSrcScanAdvance = 0;
iVertAdvanceError = iNumSrcRows;
} else {
iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
iVertAdvanceError = iNumSrcRows % iNumDstRows;
}
// compute advance and error terms for stepping
// horizontally through src bitmap
if (iNumSrcCols < iNumDstCols) {
iSrcPixelAdvance = 0;
iHorizAdvanceError = iNumSrcCols;
} else {
iSrcPixelAdvance = iNumSrcCols / iNumDstCols;
iHorizAdvanceError = iNumSrcCols % iNumDstCols;
}
for (int i = 0; i < iNumDstRows; i++) {
// set pointers to the beginning of src and dst scanlines,
// clear horizontal stepping error accumulator
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
iHorizError = 0;
for (int j = 0; j < iNumDstCols; j++) {
// copy a pixel
*pDstPixel = *pSrcPixel;
// advance to next pixel
pSrcPixel += iSrcPixelAdvance;
pDstPixel += iHorizMirror;
// update and check horizontal stepping error,
// adjust src pixel pointer if necessary
iHorizError += iHorizAdvanceError;
if (iHorizError >= iNumDstCols) {
pSrcPixel++;
iHorizError -= iNumDstCols;
}
}
// advance to next scanline
pSrcScanLine += iSrcScanAdvance;
pDstScanLine += iDstScanStride;
// update and check vertical stepping error,
// adjust src scanline pointer if necessary
iVertError += iVertAdvanceError;
if (iVertError >= iNumDstRows) {
pSrcScanLine += iSrcScanStride;
iVertError -= iNumDstRows;
}
}
}
void Blt08to08_Trans_Hcopy_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
int iNumSrcRows,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows,
BYTE bTransparentIndex)
{
BYTE *pSrcPixel,
*pDstPixel;
int iVertError = 0,
iVertAdvanceError,
iSrcScanAdvance;
// compute advance and error terms for stepping
// vertically through the src bitmap
if (iNumSrcRows < iNumDstRows) {
iSrcScanAdvance = 0;
iVertAdvanceError = iNumSrcRows;
} else {
iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
iVertAdvanceError = iNumSrcRows % iNumDstRows;
}
for (int i = 0; i < iNumDstRows; i++) {
// set pointers to beginning of src and dest scanlines
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
for (int j = 0; j < iNumDstCols; j++) {
// only copy pixel if it's not transparent
#if BLT0808_FAST_TRANSPARENCY
*pDstPixel ^= (*pDstPixel ^ *pSrcPixel) *
(BYTE) !(*pSrcPixel == bTransparentIndex);
#else
if (*pSrcPixel != bTransparentIndex)
{
*pDstPixel = *pSrcPixel;
}
#endif
pSrcPixel++;
pDstPixel++;
}
// advance to next scanline
pSrcScanLine += iSrcScanAdvance;
pDstScanLine += iDstScanStride;
// update and check vertical stepping error,
// adjust src scanline pointer if necessary
iVertError += iVertAdvanceError;
if (iVertError >= iNumDstRows) {
pSrcScanLine += iSrcScanStride;
iVertError -= iNumDstRows;
}
}
}
void Blt08to08_Trans_NoHcopy_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
int iNumSrcCols,
int iNumSrcRows,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows,
int iHorizMirror,
BYTE bTransparentIndex)
{
BYTE *pSrcPixel,
*pDstPixel;
int iVertError = 0,
iVertAdvanceError,
iSrcScanAdvance,
iHorizError,
iHorizAdvanceError,
iSrcPixelAdvance;
// compute advance and error terms for stepping
// vertically through the src bitmap
if (iNumSrcRows < iNumDstRows) {
iSrcScanAdvance = 0;
iVertAdvanceError = iNumSrcRows;
} else {
iSrcScanAdvance = iSrcScanStride * (iNumSrcRows / iNumDstRows);
iVertAdvanceError = iNumSrcRows % iNumDstRows;
}
// compute advance and error terms for stepping
// horizontally through src bitmap
if (iNumSrcCols < iNumDstCols) {
iSrcPixelAdvance = 0;
iHorizAdvanceError = iNumSrcCols;
} else {
iSrcPixelAdvance = iNumSrcCols / iNumDstCols;
iHorizAdvanceError = iNumSrcCols % iNumDstCols;
}
for (int i = 0; i < iNumDstRows; i++) {
// set pointers to the beginning of src and dst scanlines,
// clear horizontal stepping error accumulator
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
iHorizError = 0;
for (int j = 0; j < iNumDstCols; j++) {
// only copy pixel if it's not transparent
#if BLT0808_FAST_TRANSPARENCY
*pDstPixel ^= (*pDstPixel ^ *pSrcPixel) *
(BYTE) !(*pSrcPixel == bTransparentIndex);
#else
if (*pSrcPixel != bTransparentIndex) {
*pDstPixel = *pSrcPixel;
}
#endif
// advance to next pixel
pSrcPixel += iSrcPixelAdvance;
pDstPixel += iHorizMirror;
// update and check horizontal stepping error,
// adjust src pixel pointer if necessary
iHorizError += iHorizAdvanceError;
if (iHorizError >= iNumDstCols) {
pSrcPixel++;
iHorizError -= iNumDstCols;
}
}
// advance to next scanline
pSrcScanLine += iSrcScanAdvance;
pDstScanLine += iDstScanStride;
// update and check vertical stepping error,
// adjust src scanline pointer if necessary
iVertError += iVertAdvanceError;
if (iVertError >= iNumDstRows) {
pSrcScanLine += iSrcScanStride;
iVertError -= iNumDstRows;
}
}
}
#ifndef DDRAW
///////////////////////////////////////////////////////////////////////
//
// Private BlitLib_Chunk32_BitBlt08to08 -
// BitBlit from source bitmap to destination bitmap in 32 x 32
// bit chunks
//
// Parameters:
// pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
// pDibBitsDst Pointer to the bits for the Destination DIB
// prcDst Pointer to the Destination rectangle
// pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
// pDibBitsSrc Pointer to the bits for the Source DIB
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
// Status: Incomplete
//
///////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
SCODE BlitLib_Chunk32_BitBlt08to08(PDIBINFO pDibInfoDst,
PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc,
PDIBBITS pDibBitsSrc)
{
DWORD *pbDst,*pbSrc,*pend;
int j;
int iDstStride=DibWidthBytes(pDibInfoDst);
// calc pbsrc and pbdst
pbDst = (DWORD *) ((BYTE *) pDibBitsDst + (prcDst->top) * (iDstStride)
+ prcDst->left);
pbSrc=(DWORD *)pDibBitsSrc;
iDstStride-=32;
// convert stride to dwords
iDstStride/=4;
// copy a scanline
// counting down to 0 faster
for (j=32;j>0 ;j-- )
{
pend=(DWORD *)pbSrc+8;
for (; pbSrc < pend; pbSrc++ )
{
*pbDst++=*pbSrc;
}
pbDst+=iDstStride;
}
return(S_OK);
}
///////////////////////////////////////////////////////////////////////
//
// Private BlitLib_Chunk32_BitBlt08to08_Trans -
// BitBlit from source bitmap to destination bitmap in 32 x 32
// bit chunks with optional transparency
//
// Parameters:
// pDibInfoDst Pointer to the bitmapinfo for the Destination DIB
// pDibBitsDst Pointer to the bits for the Destination DIB
// prcDst Pointer to the Destination rectangle
// pDibInfoSrc Pointer to the bitmapinfo for the Source DIB
// pDibBitsSrc Pointer to the bits for the Source DIB
// crTransparent Tranparent color value
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
// Status: Incomplete
//
///////////////////////////////////////////////////////////////////////
SCODE BlitLib_Chunk32_BitBlt08to08_Trans(PDIBINFO pDibInfoDst,
PDIBBITS pDibBitsDst, PRECT prcDst, PDIBINFO pDibInfoSrc,
PDIBBITS pDibBitsSrc, COLORREF crTransparent)
{
BYTE * pbDst,*pend;
int j;
int iDstStride=DibWidthBytes(pDibInfoDst);
// calc pbsrc and pbdst
pbDst = (BYTE*) pDibBitsDst + (prcDst->top) * (iDstStride)
+ prcDst->left;
iDstStride-=32;
// copy a scanline
// counting down to 0 faster
for (j=32;j>0 ;j-- )
{
pend=pDibBitsSrc+32;
for (;pDibBitsSrc<pend;pDibBitsSrc++ )
{
if (*pDibBitsSrc != (BYTE)crTransparent)
*pbDst=*pDibBitsSrc;
pbDst++;
}
pbDst+=iDstStride;
}
return(S_OK);
}
#ifdef __cplusplus
}
#endif
#endif
///////////////////////////////////////////////////////////////////////
//
// Private Blt08to08_LeftToRight_BottomToTop_SRCOPY -
// BitBlit from source bitmap to destination bitmap (where these
// bitmaps overlap) by walking both the source and destination
// from left to right and bottom to top
//
// Parameters:
// pSrcScanLine Pointer to the first Source scan line
// iSrcScanStride The Source scan stride
// pDstScanLine Pointer to the first Destination scan line
// iDstScanStride The Destination scan stride
// iNumDstCols Number of destination columns
// iNumDstRows Number of destination rows
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
///////////////////////////////////////////////////////////////////////
void Blt08to08_LeftToRight_BottomToTop_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows)
{
DWORD *pBigSrcPixel,
*pBigDstPixel,
*pBigEndDstPixel;
BYTE *pSrcPixel,
*pDstPixel,
*pAlignedSrcPixel,
*pAlignedDstPixel;
int iNumDwordsPerLine = iNumDstCols / 4,
iNumBytesLeftDst = iNumDstCols % 4,
iNumUnalignedSrcBytes,
iNumUnalignedDstBytes,
iNumUnalignByteDiff,
i,j;
DWORD dwSrc1, dwSrc2;
// If the total number of bytes per scan is less than 4, we are
// just going to do a regular byte-wise copy, so skip all this
// alignment junk.....
if(!iNumDwordsPerLine){
iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
}
else{
// Find out if the source and dest pointers are dword aligned
pAlignedSrcPixel = (BYTE *)((((ULONG_PTR)pSrcScanLine) + 3) & (~3));
iNumUnalignedSrcBytes = (int)(pAlignedSrcPixel - pSrcScanLine);
pAlignedDstPixel = (BYTE *)((((ULONG_PTR)pDstScanLine) + 3) & (~3));
iNumUnalignedDstBytes = (int)(pAlignedDstPixel - pDstScanLine);
// Now decrement the number of dwords per line and the
// number of bytes left over as appropriate
if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
iNumBytesLeftDst -= iNumUnalignedDstBytes;
else{
iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
if(iNumBytesLeftDst != sizeof(DWORD))
iNumDwordsPerLine--;
}
}
if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
// Do the fast dword copy since the alignments match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedSrcBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigSrcPixel = (DWORD*) pSrcPixel;
pBigDstPixel = (DWORD*) pDstPixel;
pBigEndDstPixel = pBigDstPixel + iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) {
*pBigDstPixel++ = *pBigSrcPixel++;
}
// take care of remaining pixels on scanline
if (iNumBytesLeftDst) {
pSrcPixel = (BYTE*) pBigSrcPixel;
pDstPixel = (BYTE*) pBigDstPixel;
for(j=0; j<iNumBytesLeftDst; j++){
*pDstPixel++ = *pSrcPixel++;
}
}
// advance to next scanline
pSrcScanLine -= iSrcScanStride;
pDstScanLine -= iDstScanStride;
}
}
else{
// Find out the difference between the source and dest unalign offsets
// If the unaligned dest offset is less than the unaligned src offset,
// we need to decrement pSrcScanLine so that we can dword-align the first
// source bytes (the extra bytes added to the beginning of the dword
// will end up getting masked off anyway).
if(iNumUnalignedDstBytes > iNumUnalignedSrcBytes)
iNumUnalignByteDiff = iNumUnalignedDstBytes - iNumUnalignedSrcBytes;
else
iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedSrcBytes -
iNumUnalignedDstBytes);
// Do the trickier copy since the alignments don't match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedDstBytes; j++)
*pDstPixel++ = *pSrcPixel++;
// set up Dst pointer to the first 4-pixel chunk (dword)
pBigDstPixel = (DWORD *) pDstPixel;
pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
// Set up the temporary dword vars
dwSrc1 = *pBigSrcPixel++;
switch(iNumUnalignByteDiff){
case 1:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 8) | (dwSrc2 << 24);
dwSrc1 = dwSrc2;
}
break;
case 2:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 16) | (dwSrc2 << 16);
dwSrc1 = dwSrc2;
}
break;
case 3:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc2 = *pBigSrcPixel++;
*pBigDstPixel++ = (dwSrc1 >> 24) | (dwSrc2 << 8);
dwSrc1 = dwSrc2;
}
break;
}
// Take care of the bytes left over
pDstPixel = (BYTE *)pBigDstPixel;
pSrcPixel = ((BYTE *)(pBigSrcPixel)) - (sizeof(DWORD) - iNumUnalignByteDiff);
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumBytesLeftDst; j++)
*pDstPixel++ = *pSrcPixel++;
// advance to next scanline
pSrcScanLine -= iSrcScanStride;
pDstScanLine -= iDstScanStride;
}
}
}
///////////////////////////////////////////////////////////////////////
//
// Private Blt08to08_RightToLeft_TopToBottom_SRCOPY -
// BitBlit from source bitmap to destination bitmap (where these
// bitmaps overlap) by walking both the source and destination
// from right to left and top to bottom
//
// Parameters:
// pSrcScanLine Pointer to the first Source scan line
// iSrcScanStride The Source scan stride
// pDstScanLine Pointer to the first Destination scan line
// iDstScanStride The Destination scan stride
// iNumDstCols Number of destination columns
// iNumDstRows Number of destination rows
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
///////////////////////////////////////////////////////////////////////
void Blt08to08_RightToLeft_TopToBottom_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows)
{
DWORD *pBigSrcPixel,
*pBigDstPixel,
*pBigEndDstPixel;
BYTE *pSrcPixel,
*pDstPixel,
*pAlignedSrcPixel,
*pAlignedDstPixel;
int iNumDwordsPerLine = iNumDstCols / 4,
iNumBytesLeftDst = iNumDstCols % 4,
iNumUnalignedSrcBytes,
iNumUnalignedDstBytes,
iNumUnalignByteDiff,
i,j;
DWORD dwSrc1, dwSrc2;
// If the total number of bytes per scan is less than 4, we are
// just going to do a regular byte-wise copy, so skip all this
// alignment junk.....
if(!iNumDwordsPerLine){
iNumUnalignedSrcBytes = iNumUnalignedDstBytes = 0;
}
else{
// Find out if the source and dest pointers are dword aligned
pAlignedSrcPixel = (BYTE *)(((ULONG_PTR)pSrcScanLine) & (~3));
iNumUnalignedSrcBytes = (int)(pSrcScanLine - pAlignedSrcPixel) + 1;
pAlignedDstPixel = (BYTE *)(((ULONG_PTR)pDstScanLine) & (~3));
iNumUnalignedDstBytes = (int)(pDstScanLine - pAlignedDstPixel) + 1;
// Now decrement the number of dwords per line and the
// number of bytes left over as appropriate
if(iNumUnalignedDstBytes == sizeof(DWORD))
iNumUnalignedDstBytes = 0;
if(iNumUnalignedSrcBytes == sizeof(DWORD))
iNumUnalignedSrcBytes = 0;
else if(iNumUnalignedDstBytes <= iNumBytesLeftDst)
iNumBytesLeftDst -= iNumUnalignedDstBytes;
else{
iNumBytesLeftDst = sizeof(DWORD) - iNumUnalignedDstBytes + iNumBytesLeftDst;
iNumDwordsPerLine--;
}
}
if(iNumUnalignedDstBytes == iNumUnalignedSrcBytes){
// Do the fast dword copy since the alignments match
for (int i = 0; i < iNumDstRows; i++) {
// First set up the pointer to take care of unaligned DWORD bytes
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedSrcBytes; j++)
*pDstPixel-- = *pSrcPixel--;
// set up pointers to the first 4-pixel chunks
// on src and dst scanlines, and last chunk on
// dst scanline
pBigSrcPixel = (DWORD*) (pSrcPixel - 3);
pBigDstPixel = (DWORD*) (pDstPixel - 3);
pBigEndDstPixel = pBigDstPixel - iNumDwordsPerLine;
// copy scanline one 4-pixel chunk at a time
while (pBigDstPixel != pBigEndDstPixel) {
*pBigDstPixel-- = *pBigSrcPixel--;
}
if(iNumBytesLeftDst)
pSrcPixel = ((BYTE *)pBigSrcPixel) + 3;
pDstPixel = ((BYTE *)pBigDstPixel) + 3;
for (j = 0; j < iNumBytesLeftDst; j++)
*pDstPixel-- = *pSrcPixel--;
// advance to next scanline
pSrcScanLine += iSrcScanStride;
pDstScanLine += iDstScanStride;
}
}
else{
// Find out the difference between the source and dest unalign offsets
// If the unaligned dest offset is less than the unaligned src offset,
// we need to decrement pSrcScanLine so that we can dword-align the first
// source bytes (the extra bytes added to the beginning of the dword
// will end up getting masked off anyway).
if(iNumUnalignedDstBytes < iNumUnalignedSrcBytes)
iNumUnalignByteDiff = iNumUnalignedSrcBytes - iNumUnalignedDstBytes;
else
iNumUnalignByteDiff = sizeof(DWORD) - (iNumUnalignedDstBytes -
iNumUnalignedSrcBytes);
// Do the trickier copy since the alignments don't match
for (i = 0; i < iNumDstRows; i++) {
// Set up the first pointers
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumUnalignedDstBytes; j++)
*pDstPixel-- = *pSrcPixel--;
// set up Dst pointer to the first 4-pixel chunk (dword)
pBigDstPixel = (DWORD *) (pDstPixel - 3);
pBigSrcPixel = (DWORD *) (((ULONG_PTR)pSrcPixel) & (~3));
// Set up the temporary dword vars
dwSrc2 = *pBigSrcPixel--;
switch(iNumUnalignByteDiff){
case 1:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc1 = *pBigSrcPixel--;
*pBigDstPixel-- = (dwSrc1 >> 8) | (dwSrc2 << 24);
dwSrc2 = dwSrc1;
}
break;
case 2:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc1 = *pBigSrcPixel--;
*pBigDstPixel-- = (dwSrc1 >> 16) | (dwSrc2 << 16);
dwSrc2 = dwSrc1;
}
break;
case 3:
for(j=0; j<iNumDwordsPerLine; j++){
dwSrc1 = *pBigSrcPixel--;
*pBigDstPixel-- = (dwSrc1 >> 24) | (dwSrc2 << 8);
dwSrc2 = dwSrc1;
}
break;
}
// Take care of the bytes left over
pDstPixel = ((BYTE *)pBigDstPixel + 3);
pSrcPixel = (((BYTE *)(pBigSrcPixel)) + 4 +
(iNumUnalignByteDiff - 1));
// First we need to copy the bytes to get to an aligned dword
for(j=0; j<iNumBytesLeftDst; j++)
*pDstPixel-- = *pSrcPixel--;
// advance to next scanline
pSrcScanLine += iSrcScanStride;
pDstScanLine += iDstScanStride;
}
}
}
///////////////////////////////////////////////////////////////////////
//
// Private Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY -
// BitBlit using a transparent color index from source bitmap to
// destination bitmap (where these bitmaps overlap) by walking
// both the source and destination from left to right and bottom
// to top
//
// Parameters:
// pSrcScanLine Pointer to the first Source scan line
// iSrcScanStride The Source scan stride
// pDstScanLine Pointer to the first Destination scan line
// iDstScanStride The Destination scan stride
// iNumDstCols Number of destination columns
// iNumDstRows Number of destination rows
// bTransparentIndex Palette Index of the transparent color
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
///////////////////////////////////////////////////////////////////////
void Blt08to08_LeftToRight_BottomToTop_Trans_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows,
BYTE bTransparentIndex)
{
BYTE *pSrcPixel,
*pDstPixel;
for (int i = 0; i < iNumDstRows; i++) {
// set pointers to beginning of src and dest scanlines
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
for (int j = 0; j < iNumDstCols; j++) {
// only copy pixel if it's not transparent
if (*pSrcPixel != bTransparentIndex) {
*pDstPixel = *pSrcPixel;
}
pSrcPixel++;
pDstPixel++;
}
// advance to next scanline
pSrcScanLine -= iSrcScanStride;
pDstScanLine -= iDstScanStride;
}
}
///////////////////////////////////////////////////////////////////////
//
// Private Blt08to08_RightToLeft_TopToBottom_Trans_SRCOPY -
// BitBlit using a transparent color index from source bitmap to
// destination bitmap (where these bitmaps overlap) by walking
// both the source and destination from right to left and top
// to bottom
//
// Parameters:
// pSrcScanLine Pointer to the first Source scan line
// iSrcScanStride The Source scan stride
// pDstScanLine Pointer to the first Destination scan line
// iDstScanStride The Destination scan stride
// iNumDstCols Number of destination columns
// iNumDstRows Number of destination rows
// bTransparentIndex Palette Index of the transparent color
//
// Return Value:
// NO_ERROR or E_* value as specified in the .H file.
//
///////////////////////////////////////////////////////////////////////
void Blt08to08_RightToLeft_TopToBottom_Trans_SRCCOPY(BYTE* pSrcScanLine,
int iSrcScanStride,
BYTE* pDstScanLine,
int iDstScanStride,
int iNumDstCols,
int iNumDstRows,
BYTE bTransparentIndex)
{
BYTE *pSrcPixel,
*pDstPixel;
for (int i = 0; i < iNumDstRows; i++) {
// set pointers to beginning of src and dest scanlines
pSrcPixel = pSrcScanLine;
pDstPixel = pDstScanLine;
for (int j = 0; j < iNumDstCols; j++) {
// only copy pixel if it's not transparent
if (*pSrcPixel != bTransparentIndex) {
*pDstPixel = *pSrcPixel;
}
pSrcPixel--;
pDstPixel--;
}
// advance to next scanline
pSrcScanLine += iSrcScanStride;
pDstScanLine += iDstScanStride;
}
}