199 lines
6.8 KiB
C
199 lines
6.8 KiB
C
/****************************************************************************
|
|
MERGE.C
|
|
|
|
$Log: S:\oiwh\display\merge.c_v $
|
|
*
|
|
* Rev 1.3 02 Jan 1996 09:58:08 BLJ
|
|
* Changed alot of UINTs to ints.
|
|
* Changed IMG structure to include the image data.
|
|
* Changed lp prefix to p.
|
|
*
|
|
* Rev 1.2 12 Apr 1995 13:45:32 BLJ
|
|
* Jason's changes for 32 bit.
|
|
*
|
|
* Rev 1.1 06 Apr 1995 15:06:50 BLJ
|
|
* Intermediate checkin.
|
|
*
|
|
* Rev 1.0 17 Mar 1995 13:58:10 BLJ
|
|
* Initial entry
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "privdisp.h"
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
FUNCTION: MergeImgs
|
|
|
|
PURPOSE: This routine merges the source img into the dest image.
|
|
rSrceImageRect = Relative to 0,0 of the dest img.
|
|
rDestMergeRect = Rect of dest img to be merged.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI MergeImgs(PIMG pSourceImg, PIMG pDestImg,
|
|
RECT rDestMergeRect, RECT rSrceImageRect){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nPixels;
|
|
int nEndingDestPixels;
|
|
int nDestBytes;
|
|
int nStartingSrceByte;
|
|
int nStartingSrcePixel;
|
|
int nStartingDestByte;
|
|
BOOL bDoFirst1; // TRUE = nse first srce mask to get first dest byte.
|
|
BOOL bDoFirst2; // TRUE = nse second srce mask to get first dest byte.
|
|
BOOL bDoLast2; // TRUE = nse second srce masks to get last dest byte.
|
|
int nLine;
|
|
PBYTE pDestLine;
|
|
PBYTE pDestByte;
|
|
PBYTE pSourceLine;
|
|
PBYTE pSourceByte;
|
|
|
|
BYTE cSrceShift1; // Amount to shift the source byte left to align with dest.
|
|
BYTE cSrceShift2; // Amount to shift the source byte right to align with dest.
|
|
BYTE cSrceMask1; // 0 = valid bits.
|
|
BYTE cSrceMask2; // 0 = valid bits.
|
|
BYTE cFirstDestMask; // Dest mask for first byte.
|
|
BYTE cLastDestMask; // Dest mask for last byte.
|
|
BYTE cDestByte;
|
|
|
|
int nLoop;
|
|
|
|
|
|
// Clip rDestMergeRect to how much data we have to work with.
|
|
rDestMergeRect.left = max(rDestMergeRect.left, rSrceImageRect.left);
|
|
rDestMergeRect.top = max(rDestMergeRect.top, rSrceImageRect.top);
|
|
rDestMergeRect.right = min(rDestMergeRect.right, rSrceImageRect.right);
|
|
rDestMergeRect.bottom = min(rDestMergeRect.bottom, rSrceImageRect.bottom);
|
|
|
|
// Check for errors.
|
|
if (rDestMergeRect.left >= rDestMergeRect.right
|
|
|| rDestMergeRect.top >= rDestMergeRect.bottom){
|
|
nStatus = Error(DISPLAY_INVALIDRECT);
|
|
goto Exit;
|
|
}
|
|
|
|
nPixels = rDestMergeRect.right - rDestMergeRect.left;
|
|
// Pixel 0 = 0x80, pixel 7 = 0x01. 0 = black, 1 = white.
|
|
// 0 = valid bits.
|
|
|
|
// *pDestByte &= (((*pSrceByte << cSrceShift1) | cSrceMask1)
|
|
// & ((*(pSrceByte + 1) >> cSrceShift2) | cSrceMask2))
|
|
// | cDestMask
|
|
|
|
switch (nPixels){
|
|
case 1: cFirstDestMask = 0x80; break;
|
|
case 2: cFirstDestMask = 0xc0; break;
|
|
case 3: cFirstDestMask = 0xe0; break;
|
|
case 4: cFirstDestMask = 0xf0; break;
|
|
case 5: cFirstDestMask = 0xf8; break;
|
|
case 6: cFirstDestMask = 0xfc; break;
|
|
case 7: cFirstDestMask = 0xfe; break;
|
|
default: cFirstDestMask = 0xff; break;
|
|
}
|
|
nStartingDestByte = rDestMergeRect.left / 8;
|
|
cFirstDestMask >>= (rDestMergeRect.left & 7);
|
|
cFirstDestMask = ~cFirstDestMask; // 0 = valid bits.
|
|
nPixels = max(0, nPixels - (8 - (rDestMergeRect.left & 7)));
|
|
nDestBytes = nPixels / 8;
|
|
nEndingDestPixels = nPixels & 7;
|
|
switch (nEndingDestPixels){
|
|
case 0: cLastDestMask = 0xff; break;
|
|
case 1: cLastDestMask = 0x7f; break;
|
|
case 2: cLastDestMask = 0x3f; break;
|
|
case 3: cLastDestMask = 0x1f; break;
|
|
case 4: cLastDestMask = 0x0f; break;
|
|
case 5: cLastDestMask = 0x07; break;
|
|
case 6: cLastDestMask = 0x03; break;
|
|
case 7: cLastDestMask = 0x01; break;
|
|
}
|
|
|
|
nPixels = rDestMergeRect.right - rDestMergeRect.left;
|
|
nStartingSrcePixel = rDestMergeRect.left - rSrceImageRect.left;
|
|
nStartingSrceByte = nStartingSrcePixel / 8;
|
|
// 0 = valid bits.
|
|
cSrceShift1 = (8 - (char)rSrceImageRect.left) & 7;
|
|
switch (cSrceShift1){
|
|
case 0: cSrceMask1 = 0x00; break;
|
|
case 1: cSrceMask1 = 0x01; break;
|
|
case 2: cSrceMask1 = 0x03; break;
|
|
case 3: cSrceMask1 = 0x07; break;
|
|
case 4: cSrceMask1 = 0x0f; break;
|
|
case 5: cSrceMask1 = 0x1f; break;
|
|
case 6: cSrceMask1 = 0x3f; break;
|
|
case 7: cSrceMask1 = 0x7f; break;
|
|
}
|
|
cSrceMask2 = ~cSrceMask1;
|
|
cSrceShift2 = 8 - cSrceShift1;
|
|
|
|
if ((rDestMergeRect.left & 7) >= cSrceShift2){
|
|
bDoFirst2 = TRUE;
|
|
bDoFirst1 = FALSE;
|
|
}else{
|
|
bDoFirst1 = TRUE;
|
|
if (cSrceShift2 < 8 && (rDestMergeRect.right - (rDestMergeRect.left & -8)) >= cSrceShift2){
|
|
bDoFirst2 = TRUE;
|
|
}else{
|
|
bDoFirst2 = FALSE;
|
|
}
|
|
}
|
|
|
|
if ((rDestMergeRect.right & 7) > cSrceShift2){
|
|
bDoLast2 = TRUE;
|
|
}else{
|
|
bDoLast2 = FALSE;
|
|
}
|
|
|
|
for (nLine = rDestMergeRect.top; nLine < rDestMergeRect.bottom; nLine++){
|
|
pSourceLine = &pSourceImg->bImageData[0] + ((nLine - rSrceImageRect.top) * pSourceImg->nBytesPerLine);
|
|
pDestLine = &pDestImg->bImageData[0] + (nLine * pDestImg->nBytesPerLine);
|
|
|
|
pSourceByte = pSourceLine + nStartingSrceByte;
|
|
pDestByte = pDestLine + nStartingDestByte;
|
|
|
|
|
|
// *pDestByte &= (((*pSrceByte << cSrceShift1) | cSrceMask1)
|
|
// & ((*(pSrceByte + 1) >> cSrceShift2) | cSrceMask2))
|
|
// | cDestMask
|
|
|
|
// Do first source byte.
|
|
cDestByte = (BYTE) -1;
|
|
if (bDoFirst1){
|
|
cDestByte &= (*(pSourceByte++) << cSrceShift1) | cSrceMask1;
|
|
}
|
|
if (bDoFirst2){
|
|
cDestByte &= (*pSourceByte >> cSrceShift2) | cSrceMask2;
|
|
}
|
|
*(pDestByte++) &= cFirstDestMask | cDestByte;
|
|
|
|
// Do middle bytes.
|
|
if (!cSrceShift1){ // If source and dest are aligned.
|
|
for (nLoop = nDestBytes; nLoop; nLoop--){
|
|
*(pDestByte++) &= *(pSourceByte++);
|
|
}
|
|
}else{ // If source and dest are not aligned.
|
|
for (nLoop = nDestBytes; nLoop; nLoop--){
|
|
cDestByte = (*(pSourceByte++) << cSrceShift1) | cSrceMask1;
|
|
cDestByte &= (*pSourceByte >> cSrceShift2) | cSrceMask2;
|
|
*(pDestByte++) &= cDestByte;
|
|
}
|
|
}
|
|
|
|
// Do last byte.
|
|
if (cLastDestMask != 0xff){
|
|
cDestByte = (*pSourceByte << cSrceShift1) | cSrceMask1;
|
|
if (bDoLast2){
|
|
cDestByte &= (*(++pSourceByte) >> cSrceShift2) | cSrceMask2;
|
|
}
|
|
*pDestByte &= cLastDestMask | cDestByte;
|
|
}
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|